一.定时器
1.定时器的介绍
delay的过程,cpu是干不了其他事情的,占用了cpu
用了定时器,cpu就可以干其他事情了
原理框图
(1)时钟
单片机的各个模块是按照统一的节拍进行工作的
统一的节拍来源于单片机的时钟(时钟信号是一个高低电平交错的信号)
单片机在一个时钟周期内,只能执行一条指令,单片机的时间单位都是时钟周期的整数倍
晶振的频率也就是单片机的主频
主频越高,性能越好
12兆赫兹进行12分频后就是1兆赫兹,周期为1微秒,则计数单元每隔一微秒us就进行一次计数
补充:晶振的工作原理(压电效应)
施加压力造成形变,就会产生电压放电(内部产生极化现象)
反过来,施加电压,也会发生形变(逆压电效应)
如果在两级施加的是交变电压,就会产生震动,也就是谐振
越薄的晶体谐振频率就越高(高频的晶振体积都比较小)
以上原理即为压电效应
(2)计数单元(计数器)
TL0:timer low
TH0:timer high
存的数字溢出会置标准为TF0,有标志位后会向中断系统申请中断 (定时器溢出就是一种中断源)
控制位
TR0控制定时器是否启动或暂停
2.stc89c52定时器资源
3.定时器的工作模式
二.中断系统
1.介绍![](https://i-blog.csdnimg.cn/blog_migrate/fd530988db94dd6e7fb0b5eea64d0a58.png)
2.流程
3.中断资源
定时器0,1的中断入口
void Timer0_Rountine(void) interrrupt 1;
void Timer1_Rountine(void) interrrupt 3;
中断号是中断程序的入口
4.定时器相关的寄存器
TCON是timer control的缩写
GATE是门控位,用于控制定时器的启动是否受外部中断源的影响,GATE为0时,只要TCON中的TR0或者TR1为1,就可以启动定时器或者计数器驱动。GATE为1时,需要TCON中的TR0或者TR1为1,同时外部中断INT0/1也为高电平,才可以启动定时器或者计数器驱动。
寄存器名称后面跟1则为定时器1的寄存器
寄存器名称后面跟0则为定时器0的寄存器
补充:寄存器
8位的51单片机内部的每个寄存器就相当于有 8个开关
32位的32单片机的每个寄存器相当于有32个开关
寄存器是cpu内部存放数据的小型存储区域 ,用来暂时存放参与运算的数据和运算结果
寄存器拥有非常高的读写速度,所以在寄存器之间的数据传送非常快
三.代码实现 中断,时钟
1.配置
1.模式模式
16位定时器是将两个八位组合在一起,只能记录0-65535的数,并需要每次在中断中进行赋初值
占用了中断的运行时间,所以计时的精度并不是很高
可位寻址:可以对寄存器的每一位单独进行赋值
2.TCON配置
TR0=0
TF=0(不进行配置也不会有太大的影响)
3.利用赋初值将每隔一微秒计数一次改为每隔一秒计数一次
以10进制举例
以上3步就将定时器部分配置完成
4.配置中断
2.设置程序
1.设置中断入口
2.计数1000次将一微秒累加至一秒
需要定义全局变量
3.中断重新赋值
问题:配置TMOD时,可以发现,在配置定时器0时也会改变定时器1的状态
解决:与或式赋值法
简化写法
问题:简单配置计数器,之前手写的代码实际会有多出一微妙的误差
原因:
由于计数器的值在到达65535时,并不会马上进行重置,而是会执行下一次计数,当数准备跳到65536时,系统才会进行重置为0;所以实际上手写的代码一次count if 计时为1001微秒,所以赋初值时要在低位多加一个1
4.代码优化
中断函数完成后静态局部变量不清理,最好将变量的定义放在中断函数内部
四.按键控制流水灯和时钟计时案例
1.按键控制
1.模块化独立按键
2.主函数实现
注意:为什么要检测按键的值为0
单片机IO接上拉电阻。上拉是为了让引脚默认是高电平(即单片机上电后,引脚电压默认是高电平),但是上拉的力量抗不住接地(GND),所以按键没有按下时单片机IO口为高电平,而按下后为0(GND)。所以通过检测0来检测是否按下