C51定时器计数器
C51定时器计数器
电路图
定时/计数器的结构和工作原理
1,定时/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器TH1,TH2组成
TH1+TL0的模是65536,可表达范围0~65535,65535+1时就会溢出产生相关中断
2,TMOD是定时/计数器的工作方式寄存器,确定工作方式和功能;
3,TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志
定时计数器相关寄存器
TCON寄存器(中断的请求与外部中断的选择)
位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
addr:88H | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
中断源 | T1 | T1 | T0 | T0 | INT1 | INT1 | INT0 | INT0 |
-
IT0和IT1是设置外部中断的触发方式
当其为0时,为低电平触发方式
当其为1时,为负跳变触发方式 -
IE0和IE1是外部中断标志位
-
下面是定时/计数器的控制
TF0和TF1是定时器的中断标志
TR1和TR0是打开相应的定时器TF1:T1溢出中断请求标志位,T1计数溢出时由硬件自动置 TF1为1。CPU响应中断后TF1由硬件自动清0。T1工作时,CPU可随时 查询TF1的状态。所以,TF1可用作查询测试的标志。TF1也可以用软 件置1或清0,同硬件置1或清0的效果一样。 TR1:T1运行控制位。TR1置1时,T1开始工作;TR1置0时,T1停止工作。TR1由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。 TF0:T0溢出中断请求标志位,其功能与TF1同。TR0 TR0:T0运行控制位,其功能与TR1类同。
IE寄存器(开关)
位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
addr:A8H | EA | ES | ET1 | EX1 | ET0 | EX0 | ||
中断源 | 串 | T1 | INT1 | T0 | INT0 |
- EX0外部中断0允许位;
- ET0定时/计数器T0中断允许位;
- EX1 外部中断0允许位;
- ET1 定时/计数器T1中断允许位;
- ES 串行口中断允许位;
- EA CPU中断允许(总允许)位;
计数存放寄存器
| Mnemonic |ADD| NAME |7~0位|
|--|--|--|--|--|
|TL0| 8Ah| Timer / Counter 0 Low Byte ||
| TH0 |8Ch |Timer / Counter 0 High Byte||
|TL1 | 8Bh |Timer / Counter 0 High Byte||
|TH1 | 8Dh |Timer / Counter 1 High Byte||
TMOD寄存器(寄存器工作方式)
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
addr:89H | GATE | C/T1 | M1 | M0 | GATE | C/T0 | M1 | M0 |
中断源 | T1 | T1 | T1 | T1 | T0 | T0 | T0 | T0 |
GATE:门控位。GATE=0时,只要用软件使TCON中的TR0或TR1为1,就可以启动定时/计数器工作;GATA=1时,要用软件使TR0或TR1为1,同时外部中断引脚或也为高电平时,才能启动定时/计数器工作
C/T :定时/计数模式选择位。 C/T =0为定时模式; C/T =1为计数模式。
M1M0:工作方式设置位。定时/计数器有四种工作方式,由M1M0进行设置。
M1M0设置的工作方式
M1 | M0 | 工作方式 | 功能简述 |
---|---|---|---|
0 | 0 | 方式0 | 13位计数器,TLi只用低5位 |
0 | 1 | 方式1 | 16位计数器 |
1 | 0 | 方式2 | 8位自动重装计数器。仅TLi作为计数器,THi的值不变。TLi溢出, THi中的值自动装入TLi中. |
1 | 1 | 方式3 | T0分为两个独立的8位计数器 |
方式0
方式0为13位计数,由TL0的低5位(高3位未用)和TH0的8位组成。TL0的低5位溢出时向TH0进位,TH0溢出时,置位TCON中的TF0标志,向CPU发出中断请求
方式1
方式1的计数位数是16位,由TL0作为低8位、TH0作为高8位,组成了16位加1计数器
计数个数与计数初值的关系为: X=216-N
方式2
方式2为自动重装初值的8位计数方式
计数个数与计数初值的关系为: X=28-N
方式3
方式3只适用于定时/计数器T0,定时器T1处于方式3时相当于TR1=0,停止计数
工作方式3将T0分成为两个独立的8位计数器TL0和TH0 。
定时器操作步骤:
1,选择工作方式(设置M1,M0)
2,选择控制方式(设置GATE)
3,选择定时器还是计数器模式(设置C/T)
4,给定时/计数器赋初值(设置THx和TLx)
5,开启定时器中断(设置ET0或ET1)
6,开启总中断(设置EA)
7,打开计数器(设置TR1或TR0)
8,编写中断程序
周期晶振
1,晶振频率(frequency oscillate): 晶体振荡器的固有频率
2,时钟周期(Clock Cycle): 时钟周期是计算机中最基本的、最小的时间单位,为晶振频率12Mhz倒数
3,状态周期: CPU从一个状态转换到另一状态所需要的时间,一个状态周期S包含2个节拍,前一时钟周期称为P1节拍,后一时钟周期称为P2节拍
4,机器周期: 一个机器周期包含六个状态例如,取指令、存储器读、存储器写等。即机器周期等于6个状态周期,而一个状态周期是2个时钟周期,因此一个机器周期又等于12个时钟周期
5,指令周期: 取出并执行一条指令的时间
6,总线周期: 访问1次存储器和I/O端口操作所需要的时间
时间比较:时钟周期 < 状态周期 < 机器周期 < 指令周期 < 总线周期
初值计算
这里使用16位的定时器,那单片机定时器0的最大计数就是65536.晶振约为12MHZ(11.0592MHZ),那一个机器周期就是1us,定时器 0工作在方式1时最大定时65.536ms
1,计数值 = 定时时间 / (振荡周期 * 12)
2,初值 = 65536 - 计数值
3,定时时间 =(振荡周期 * 12) * (65536 - 初值)
例子
//第一个led灯以500ms一次的频率闪烁
void timer1_init()//初始化
{
TMOD = 0x10; //定时器0选择工作方式1
TH1 = 0x4C; //设置初始值,定时50ms
TL1 = 0x00;
EA = 1; //打开总中断
ET1 = 1; //打开定时器0中断
TR1 = 1; //启动定时器0
}
void main()
{
int i = 0;
led = 1;
timer1_init();//定时器1的初始化
while(1)
{
if(i==10)
{
led = ~led;
i = 0; //注意i需要零
}
}
}
void timer1() interrupt 3 //中断服务函数
{
TH1 = 0x4C; //设置初始值,定时50ms,这里晶振用12
TL1 = 0x00;
i++;
}
...Thank you for reading...______________________Heisenberg_Poppings