目录
前言
细节图解分析定时器中断细节,T0和T1的使用,及机器时序的计算.........
一.定时器介绍
1.1CPU时序
CPU时序是指在微处理器中控制指令执行的时钟信号序列
①振荡周期:为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡 周期)。
②状态周期:2 个振荡周期为 1 个状态周期,用 S 表示。振荡周期又称 S 周期或时钟周期。
③机器周期:1 个机器周期含 6 个状态周期,12 个振荡周期
④指令周期:完成 1 条指令所占用的全部时间,它以机器周期为单位。
例如:外接晶振为 12MHz 时,51 单片机相关周期的具体值为:
振荡周期=1/12us;
状态周期=1/6us;
机器周期=1us;
指令周期=1~4us;
1.2定时器特点
①51 单片机有两组定时器/计数器,因为既可以定时,又可以计数,故称之为定时器/计数器。
②定时器/计数器和单片机的 CPU 是相互独立的。定时器/计数器工作的过程 是自动完成的,不需要 CPU 的参与。
③51 单片机中的定时器/计数器是根据机器内部的时钟或者是外部的脉冲信 号对寄存器中的数据加 1。 有了定时器/计数器之后,可以增加单片机的效率,一些简单的重复加 1 的 工作可以交给定时器/计数器处理。CPU 转而处理一些复杂的事情。同时可以实 现精确定时作用。
1.3定时器原理
由高 8 位和低 8 位两 个寄存器 THx 和 TLx 组成。它随着计数器的输入脉冲进行自加 1,也就是每来一个脉冲,计数器就自动加 1,当加到计数器为全 1 时,再输入一个脉冲就使计数 器回零,且计数器的溢出使相应的中断标志位置 1,向 CPU 发出中断请求(定时 /计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到; 如果工作于计数模式,则表示计数值已满。可见,由溢出时计数器的值减去计数初值才是加 1 计数器的计数值。
上图中的 T0 和 T1 引脚对应的是单片机 P3.4 和 P3.5 管脚。51 单片机定时/ 计数器的工作由两个特殊功能寄存器控制。TMOD 是定时/计数器的工作方式寄存 器,确定工作方式和功能;TCON 是控制寄存器,控制 T0、T1 的启动和停止及 设置溢出标志。
1.4定时器/计数器结构
结构如下:
两种工作模式:定时器/计数器
这里假设TMOD=0x01,则为工作方式1;(注 :有四个不同的工作方式,这里是TMOD=0x01所以为工作方式1);当THO溢出时,置位 TCON 中的 TF0 标志,向 CPU 发出中断请求
二.定时器细节
2.1定时器结构
定时器结构
2.2定时器0/1
以定时器1结构为例,定时器0和定时器1类似的
这里使用定时器1中断使流水灯点亮,后面会介绍时序
#include "reg52.h" typedef unsigned int u16; //对系统默认数据类型进行重定义 typedef unsigned char u8; //定义LED1管脚 sbit LED1=P2^0; /******************************************************************************* * 函 数 名 : delay_10us * 函数功能 : 延时函数,ten_us=1时,大约延时10us * 输 入 : ten_us * 输 出 : 无 *******************************************************************************/ void delay_10us(u16 ten_us) { while(ten_us--); } /******************************************************************************* * 函 数 名 : time1_init * 函数功能 : 定时器1中断配置函数,通过设置TH和TL即可确定定时时间 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void time1_init(void) { TMOD|=0X10;//选择为定时器0模式,工作方式1 TH1=0XFC; //给定时器赋初值,定时1ms TL1=0X18; ET1=1;//打开定时器1中断允许 EA=1;//打开总中断 TR1=1;//打开定时器 } /******************************************************************************* * 函 数 名 : main * 函数功能 : 主函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void main() { time1_init();//定时器1中断配置 while(1) { } } void time1() interrupt 3 //定时器1中断函数 { static u16 i;//定义静态变量i TH1=0XFC; //给定时器赋初值,定时1ms TL1=0X18; i++; if(i==1000) { i=0; LED1=!LED1; } }
三.定时器配置
3.1计算时序
前面我们介绍过机器周期的概念,它是 CPU 完成一个基本操作所需要的时间。 其计算公式是:机器周期=1/单片机的时钟频率。51 单片机内部时钟频率是外部时钟的 12 分频,也就是说当外部晶振的频率输入到单片机里面的时候要进行 12 分频。比如说你用的是 12MHZ 晶振,那么单片机内部的时钟频率就是 12/12MHZ, 当你使用 12MHZ 的外部晶振的时候,机器周期=1/1M=1us。如果我们想定时 1ms 的初值是多少呢?1ms/1us=1000。也就是要计数 1000 个,初值=65535-1000+1 (因为实际上计数器计数到 65536(2 的 16 次方)才溢出,所以后面要加 1) =64536=FC18H,所以初值即为 THx=0XFC,TLx=0X18。
注意:(MHz,即兆赫,是一个波动频率的单位,代表每秒一百万次周期性变动的次数)
假设:
外部晶振:11.0592(MHZ)
时钟周期:1/11059200 = 0.09(us);
机器周期:12*0.09us=1.08(us) (定时器+1就相当于1.08us)
如果需要定时1ms (1ms=1000us)
那么:1000us/1.08 = 925 (925.925925........这里取925)
65536 - 925 =64611 (因为定时器工作方式1,为16位,而64611为初值:意思就是每次从64611加到65536,加了925次,8位溢出所需时间为1us)
64411=0xFC63
TH0=0xFC
TH1=0x63
四.硬件设计
使用定时器,模拟流水灯
4.1定时器结构
注意:使用定时器中断的时候,这里不是使用P3.4接口,而是把结果给P3.4,因为它为中断接口,所以可以控制T0和T1接口进行定时器中断
四.软件设计
#include "reg52.h" typedef unsigned int u16; //对系统默认数据类型进行重定义 typedef unsigned char u8; //定义LED1管脚 //sbit LED1=P2^0; #define LED_PORT P2 //使用宏定义 P2 端口 void delay_10us(u16 ten_us) { while(ten_us--); } void time0_init(void) { TMOD|=0X01;//选择为定时器0模式,工作方式1 TH0=0XFC; //给定时器赋初值,定时1ms TL0=0X63; ET0=1;//打开定时器0中断允许 EA=1;//打开总中断 TR0=1;//打开定时器 } void main() { time0_init();//定时器0中断配置 while(1) { } } void time0() interrupt 1 //定时器0中断函数 { static u16 i;//定义静态变量i static u8 k=0; TH0=0XFC; //给定时器赋初值,定时1ms TL0=0X63; i++; if(i>=5000) { i=0; LED_PORT=~(0x01<<k); k++; if(k>=8) k=0; } }
以上就是本期补齐的内容,欢迎参考指正,如有不懂,欢迎评论或私信出下期!!!