STC51(点灯+五向开关)
mini DSO STC15 开源示波器
中景园STC89C52资料
其实本来不是写定时器的文章,而是想写一篇长长的文章把单片机说完。但是我写的写的后悔了,实在是有点多,写完定时器就饿了,SO,最后起了这个名字。
nop是一个空指令的时间
对我们使用引脚的定义
没什么好说的,就是记住0是低电平,1是高电平。再者就是nop是一个空的时钟时间。注意上面函数的声明。
模块化编程,是怎么回事?考虑变与不变的艺术,注意分层的艺术。
dev是外设传感器的封装,写函数接口。sys是单片机本身的资源。
C是具体的实现,H是暴露的接口。
写函数声明,各种可变的参数
sys里面写关于操作寄存器的头文件,还有数据类型的重新定义。
需要注意的是,引脚也是一种资源,所以也放在配置的文件夹。
然后一个main文件作为逻辑的实现,完事。
函数与逻辑和模块之间的联系就是头文件。
关于按键检测,是永远不会缺席的功能。这里就先说查询法,这个查询我感觉有点扫描的味道,不就是一个循环里面判断一次和IO口相关联的状态标志。
看我代码,在死循环里面调用按下的语句。
消抖什么的,老生常谈了,不说了。功能就是如果按下按键就返回一个1.
也就是if为真,那就继续运行。不就是把灯开了。
这就是灯的IO
另外注意五向开关,也是需要占用好多IO的。
说下设计的逻辑,一定要在这个按键的状态前先查询,这个按键的当前情况,就好像你去买东西,先知道哪个地方还卖你要的东西吗?
因为我们想的是没有,
key1 = 1; //设置成输入状态
所以要:
!key1 = !1
是真!
开始延时,穷人做法,跳过抖动。
接着再判断一下这个状态,因为一直是准备读取,你还没有读取,对吧!不停的为真,一直就按着。一直IO为0.不继续运行,直到你放开,这个循环条件变假了。因为是你摁的时候有抖动,你松开的时候也有,所以处理方法一样。
是一样的
处理过后,相当于你读取了这个信息,相当于你取走了东西,这个东西你要还愿。flag=0,后面用return把它这个函数得到的信息传出去,给上层的函数使用。
就是这样。
STC51(LCD1602全解析.上),我以前写过,但是觉得不深刻,这里重新写。
使用外设,俩步走,先初始化,接着就是通信过程。
数字器械就是活的个时序,就是IO的电平变化+时间。
这是LCD1602的初始化代码,别问为什么我也不知道,先用。不是我不求甚解,其实我是真的不知道。
这里你也看见了,读写操作。怎么实现?用IO的电平变化:
写指令
写数据
时序
还有一个事情,就是在写操作前要看看LCD忙不忙:
忙信号检测
初始化而已。接下来看下连线问题:
8个线
接着就是
那么操作这个LCD,你就让IO口搭配的输出不同电平就行。
对于显示器件,知道在哪里显示什么就ok了~
高(0100)+低(0001)
这才是一个字符,如果一个串呢?
也是有函数的.
其实本来是要写应用的,但是我觉得太早了,不如再写几下相关的硬件。
这里先说定时器这个东西,前面的延时实现都是空语句浪费时间,这样很不好,至少不精确。
定时器的一些通俗解释我就不说了,我觉得这个地方可以是哟个数学建模里面的一些方法说明:
假设:
我们先认为一个可以记录的事情的两个相邻间隔的时间是相同的。
要记录的事情可以被记录
有个容器可以装我们记录的事情
定时器的工作就是这样:就好像你拿一个羽毛球往羽毛球桶里面塞,你一秒钟可以塞一个。10s后一个桶满了,然后你把这个桶里面的球倒入一个大桶里面,你顺手在本子上面划一道。
其实我们就可以计算了,你一个人塞了多少球?以及塞球用了多少时间。仔细想想还有进位的知识。就像表一样!
下面我找了一个土的要死的视频截图:
上面的水滴就是你塞球,时间是1秒一颗
满了以后就倒出去,是个容器就会满
初值重装,就是你一开始的羽毛球桶里面有几个。其实就是为了可控这个过程
可恶啊,让这么丑的示意图说明白了
我们开始抽象一下,一个定时器有什么构成:
要求事件之间的间隔时间相同
这个装事件的箱子多大
这个事件该怎么表示?
差不多啦!
因为我们说的是51单片机(我是觉得你51玩不明白就去玩ARM,STM32这些,笑话一样,不可否认你会用,但是你深刻吗?)。
一般51单片机的定时器名字叫TIMER,然后寄存器就是箱子,起个名字叫TL0,TH0. 也就是说定时器有两个箱子,名字分别是tl,th。
有箱子放啥?放事件,不论是什么事件无非就是发生了!然后在单片机里面就是1,0,相当于一个事件的发生标志。发生一个在TL的最低位写一个1,在发生就再放1.
其实有一个事情是,这个事件怎么触发,你看它本身很无聊,就是一个一个的。所以在单片机里面有晶振搬砖。
其实你要深刻的理解这个东西,所有的单片机定时器都是这样的。
那定时器怎么样用?其实就是闹钟的用法
我们先看怎么打开,闹钟是按钮打开。在单片机里面都是0,1,所以很容易就是0,1.
剩下是多长时间?闹钟的话我们是看走了多少格子,那单片机也是这样的原理,就是TH,TL这两个箱子如何组合的事情。
这个如何组合是一种模式,所以有个寄存器叫TMOD(time mode)干这个事情。
你看
一个格子有两个状态,0或1.那这么多格子,就是00、01,11,10.
4个工作模式哇。里面的时间够了,怎么传出去这个时间到了的意思呢?
使用TCON寄存器里面的TF,full满的意思,上面满了TF(0->1),告诉CPU满了。
你看是不是
你看
TF就是满了以后是中断。
接下来看怎么用!首先定时器我们要解决定时时长的问题。通过TH,TL控制。这里选16bit
先开启定时器1,都设置1.
然后就是M1,M0,设置01.这就OK了。
TMOD = 0000 0001 = 0x01.
一开始要计数了,TH,TL都为0,16bit,就是2的16次方,65535这么多。
有溢出,所以2^16+1,每次装一个值需要12/11.0592 微秒,装65536需要
UnitT=65536x(12/11.0592)= 71000微秒 = 71ms,那我要定时1s。
明显TH,TL都不够,兄弟别慌,循环几次就OK。
比如UnitT = 10ms,循环100次就1s啦!
那UnitT=10000us,也就是UnitT=(65536-X)x(12/11.0592)=10000us.
X就是我们的TH,TL的初始化的值。
算不来的自己用软件
继续,初始值为19456,然后不停的++,那么到65535,这是TL满了,然后不停的增长到TH到65535,两个都放不下了,TF变1,告诉CPU时间到了。
要注意TF变1 是溢出了一次,时间还没有到。要TF溢出20次,这才到1s。
这就是我们的框图,当TF为1时,我们要记录这个溢出事件,而且要把寄存器TLTH,清零,接着装值,拍拍屁股开始干活。
我觉得我讲的最清晰了,再听不懂可以考虑不用学了。
这里学点数字电路小知识。
学会了吗?
我们来分析一个,这个定时器的本质就是一个加减法的计数器,本质就是对脉冲计数。
只不过这个来源不一样,系统时钟的脉冲,就是定时,12或者6时钟得到一个计数脉冲.
如果是外部引脚那就是计数。一个脉冲+1
很清晰吧
6T肯定是快啊,你以前2个点吃一个,现在一个点吃一个。
看这个,3开关是由4,5,6控制的。
6为非门,GATE=0,输出1,5为或门,5,6搭配必出一,由高电平就全高了。4为与门这个时候,从56上来的信号是确定的1.要想4输出1,那就要TR0为1就行,其实侧面说明,TR0是开关了。巧妙
这不就开始了