中断及定时器问题

时间:2022-12-23 23:25:57
void main(void)
{P2=0X0F;EA=1;IT1=1;ET0=1;
  TMOD=0X01;
TH0=-5000/256;   //计时0.01秒
TL0=-5000/256;
TR0=1;
FOR(;;);
}
//定时计数器0的中断服务程序
void timer0(void) interupt 1  using 1
{TH0=-5000/256;
TL0=-5000/256;

buffer[0]==100   //计数100
{L3=!L3;L2=!L2;L1=!L1;L0=!L0;}
}  //总的定时是10ms
   

1、计时0.01秒用TH0=-5000/256;   TL0=-5000/256;是怎么算得到的,详细步骤是怎么的。2、为什么中断服务程序里还要重写一遍TH0=-5000/256;   TL0=-5000/256;    


  求求各位大哥大姐指教

10 个解决方案

#1


1)假定使用12MHz的晶振,那么,定时器的定时脉冲为晶振频率的1/12,即1MHz。例程中,定时器工作于方式1(TMOD=0X01),所以,定时器0以16位方式定时计数。TH0=-5000/256;  TL0=-5000%256(这里一定是写错了,呵呵);主要是为了凑定时器的定时时间。16位定时器在计数到0xFFFF后会产生溢出中断。-5000的16进制值为0xEC78,再加上0x1388就可以使定时器溢出;而0x1388的10进制值就是5000,也就是,为T0置5000(D)的初值,那么1um×5000,即0.5ms后,定时器会产生一次溢出。
之所以用TH0=-5000/256;  TL0=-5000%256;是因为方便单片机赋值的缘故。-5000/256=0xE7;-5000%256=0x78,这样,与TH0 =0XE7,TL0=0X78就一样了。
2)重写是因为:方式1工作下的定时器在溢出后自已不会重载,要软件手动重载,故重写了一遍。
PS:
     这个程序是有问题的,除了那个"%"以外。在最后的{L3=!L3;L2=!L2;L1=!L1;L0=!L0;} 的花括号里要加一句"buffer[0]=0;",否则,无论你如何改动buffer[0]的判断条件,P0口这几个位的翻转时间都不会有明显的变化。

#2


写错了,是置了-5000(D),也就是0XEC78,少了个负号。。

#3



你选择的计数方式是方式1 ,由TMOD=0x01决定

方式1的定时公式是( T=12*(2^16-a)/f)us////////////////
////////////T是定时的周期;f是晶振;a就是计算出来的初值将其化成十六进制就是TH0和TL0; 2^16是2的16次方
为了定时的准确性,因为每次当计数满了以后会产生中断;我们要重新定初值!!!所以在中断函数里要重新定初值!!



#4


如果你选的是方式2 那他是8位的带自动重新装入的计数器;
在中断里面就不用重新赋值了;

方式1没有自动重新装入的功能;每次计数都要重新装入初值;所以在中断里面要重新赋值;

由上面说的 T=12*(2^16-a)/f

 可得 a=2^16-(f*T)/12;T是定时的时间;f是晶振;a就是计算出来的初值将其化成十六进制就是TH0和TL0;2^16是2的16次方 

#5


谢谢  

#6


奇怪了,从你之前的帖子到现在的帖子,怎么TH0/TL0中都有-(负号)呢?从哪里参考的程序?虽然结果不一定有问题,可这样写却是很大的问题。

#7


为什么了?


 cauhorse大哥    buffer[0]=0;应该写为buffer[1]={0}把  

#8


程序里还有一个问题
for不能用大写

#9


这要多看看51单片机资料就可以了

#10


这是跟据这个程序写的;
buffer[0]=0;
为buffer数组的第一个元素重新赋值为0。

#1


1)假定使用12MHz的晶振,那么,定时器的定时脉冲为晶振频率的1/12,即1MHz。例程中,定时器工作于方式1(TMOD=0X01),所以,定时器0以16位方式定时计数。TH0=-5000/256;  TL0=-5000%256(这里一定是写错了,呵呵);主要是为了凑定时器的定时时间。16位定时器在计数到0xFFFF后会产生溢出中断。-5000的16进制值为0xEC78,再加上0x1388就可以使定时器溢出;而0x1388的10进制值就是5000,也就是,为T0置5000(D)的初值,那么1um×5000,即0.5ms后,定时器会产生一次溢出。
之所以用TH0=-5000/256;  TL0=-5000%256;是因为方便单片机赋值的缘故。-5000/256=0xE7;-5000%256=0x78,这样,与TH0 =0XE7,TL0=0X78就一样了。
2)重写是因为:方式1工作下的定时器在溢出后自已不会重载,要软件手动重载,故重写了一遍。
PS:
     这个程序是有问题的,除了那个"%"以外。在最后的{L3=!L3;L2=!L2;L1=!L1;L0=!L0;} 的花括号里要加一句"buffer[0]=0;",否则,无论你如何改动buffer[0]的判断条件,P0口这几个位的翻转时间都不会有明显的变化。

#2


写错了,是置了-5000(D),也就是0XEC78,少了个负号。。

#3



你选择的计数方式是方式1 ,由TMOD=0x01决定

方式1的定时公式是( T=12*(2^16-a)/f)us////////////////
////////////T是定时的周期;f是晶振;a就是计算出来的初值将其化成十六进制就是TH0和TL0; 2^16是2的16次方
为了定时的准确性,因为每次当计数满了以后会产生中断;我们要重新定初值!!!所以在中断函数里要重新定初值!!



#4


如果你选的是方式2 那他是8位的带自动重新装入的计数器;
在中断里面就不用重新赋值了;

方式1没有自动重新装入的功能;每次计数都要重新装入初值;所以在中断里面要重新赋值;

由上面说的 T=12*(2^16-a)/f

 可得 a=2^16-(f*T)/12;T是定时的时间;f是晶振;a就是计算出来的初值将其化成十六进制就是TH0和TL0;2^16是2的16次方 

#5


谢谢  

#6


奇怪了,从你之前的帖子到现在的帖子,怎么TH0/TL0中都有-(负号)呢?从哪里参考的程序?虽然结果不一定有问题,可这样写却是很大的问题。

#7


为什么了?


 cauhorse大哥    buffer[0]=0;应该写为buffer[1]={0}把  

#8


程序里还有一个问题
for不能用大写

#9


这要多看看51单片机资料就可以了

#10


这是跟据这个程序写的;
buffer[0]=0;
为buffer数组的第一个元素重新赋值为0。