M1和M0:操作模式控制位 当M1=0,M0=1时,也就是工作方式1的16位定时器/计数器
GATE: 门控制位 当GATE=1,时,INT0(INT1)=1,且TR0(TR1)=1则启动定时器/计数器
当GATE=0,时,只要TR0(TR1)=1定时器/计数就开始工作
C/T: 选择定时或者选择计数方式
当C/T=0时,则选择定时方式(每个周期使计数器加1)
当C/T=1时,则选择计数方式(当接收到的外部脉冲产生负跳变时使计数器加1)
特殊寄存器之状态控制寄存器TCON
TF1: 定时器T1溢出中断标志 当定时器T1溢出时,由硬件置1
当响应中断时,由硬件置0,
TR1:定时器T1运行控制位,由软件控制置位和复位,控制定时器是否运行,当是0时,关闭定时器1。TF1和TR1都是控制定时器T1的,同理TF0和TR0都是控制定时器T0的
IE1,IT1,IE0,IT0是控制外部中断的
IE1:外部中断1请求标志
IE0:外部中断0请求标志
IT1:外部中断1触发方式选择位
IT0:外部中断0触发方式选择位
定时器0的工作方式逻辑图:
分析上面的逻辑图知(INT0非 OR GATE非)AND TR0为真时定时器0启动工作
C/T=1为计数工作方式,计数脉冲由T0引脚输入。
C/T=0为定时工作方式。
工作的过程中,发生溢出是硬件自动设置TF0=1,然后单片机去处理中断
定时器0工作方式1下分析
因为定时器在默认情况下装入的是00000000 00000000,当定时器开始计数时,寄存器的值一直加1,当加到11111111 11111111时,外部再过来一个脉冲后就发生溢出了,单片机就去处理中断程序了。假设单片机的晶振的频率是12MHZ,那么一个机器周期的时间就是1us,这种情况下一共需要的时间是65536us,也就是65.5ms,因此如果我们要定时65.5ms的话,就可以这样做,但是定的时间如果不是65.5ms的话,则需要装入定时器中一个初值。假设我们要计数的个数是N个,设装入的初值是X,则X+N=2^16, 解得X=2^16-N,比如要装50000个数的话,初值X=65536-50000=15536,然后把15536对256取模15536/256=60装入TH0中,15536%256=176装入TL0中。因为实验板上的晶振是11.0592MHZ,可知机器周期=1.09us,比如说我们要定时50ms(50000us)那么计数的个数是N=50000/1.09=45872,再计算初始值X=65536-45872=19664,,再分别计算TH0和TL0中具体装多少就可以了。
利用定时器工作方式1,在实验板上实现第一个发光二极管以1s亮灭闪烁
程序如下:
- #include
- #define uchar unsigned char
- #define uint unsigned int
- ***it led1=P1^0;
- uchar num;
- void main()
- {
- TMOD=0x01; // 工作方式是1
- TH0=(65536-45872)/256; //计算初值
- TL0=(65536-45872)%256; //计算初值
- EA=1; //开总中断
- ET0=1; //定时器T0 中断允许
- TR0=1; //启动定时器定时的功能
- while(1);[/p][p=30, 2, left]
- }
- void T0_time()interrupt 1 //定时器0的中断服务程序
- {
- TH0=(65536-45872)/256; //重装初值
- TL0=(65536-45872)%256;
- num++;
- if(num==20) //应为定时1s,因此循环20次
- {
- num=0; //重新赋值num进入下一次循环
- led1=~led1; //定时1s后,改变发光二极管的状态[/p][p=30, 2, left]
- }
- }
复制代码
上面程序等价于
- #include
- #define uchar unsigned char
- #define uint unsigned int
- ***it led1=P1^0;
- uchar num;
- void main()
- {
- TMOD=0x01;
- TH0=(65536-45872)/256;
- TL0=(65536-45872)%256;
- EA=1;
- ET0=1;
- TR0=1;
- while(1)
- {
- if(num==20)
- {
- num=0;
- led1=~led1;
- }
- }
- void T0_time() interrupt 1
- {
- TH0=(65536-45872)/256;
- TL0=(65536-45872)%256;
- num++;
- }
复制代码
程序分析:首先进入主程序设置一些寄存器的初始参数,开中断。当执行到while(1);时,停在这里,另一方面定时器还在计数,当发生溢出时,于是就转去执行中断程序,执行完后又回到while(1);处,如此一直循环下去。。。注意:循环的前提是中断没有关闭,除非你关中断!
1
评分
-
查看全部评分