求教!AT89C52定时器初值问题!
sbit d1=P1^0;
int m,num;
main()
{ m=40;
TMOD=0x01;
TH0=(65536-m)/256;
TL0=(65536-m)%256;
EA=1;
ET0=1;
TR0=1;
while(1);
}
void T0_timer() interrupt 1
{
TH0=(65536-m)/256;
TL0=(65536-m)%256;
d1=~d1;
}
****************************************************************
#include<reg52.h>
sbit d1=P1^0;
int m,num;
main()
{
TMOD=0x01;
TH0=(65536-40)/256;
TL0=(65536-40)%256;
EA=1;
ET0=1;
TR0=1;
while(1);
}
void T0_timer() interrupt 1
{
TH0=(65536-40)/256;
TL0=(65536-40)%256;
d1=~d1;
}
************************************************************
晶振的频率为11.0592,为什么直接赋值40的时候,频率为几K,而赋值为m的时候,频率只有314HZ?如果,定时器初值不能装变量m的话,如何用定时器分时产生两个频率?比如先产生一个5K的频率,5ms后再产生一个10K的频率,跪求高人指点!
你将m的类型设置成unsigned int格式试试,并且直接在全局变量中赋值;对于两个频率当你使用一个定时器时,进行计数,当满足条件时就改变装入的初值就好了;用两个的话,就用TR0和TR1来控制,分别装好初值后来回切换就好了,思路已经提供给你了,程序什么的自己写最好,别人给你的还是别人的,自己锻炼锻炼,有什么问题再问
#define uint unsigned int
uint m=40;
***************
加上这两句,还是不行。还会产生另一个问题:如果把m定义成全局变量的话,定时器的初值不可能在改变了,也就不能产生出另一个频率了。
今天我调试了一下,发现TH0=(65536-m)/256;TL0=(65536-m)%256;和TH0=(65536-40)/256;TL0=(65536-40)%256;执行这两种计算定时器初值的时间有很大的不同,对于后一种只用大概10几至20uS,而前一种竟然有800~1000uS(汗,第一次知道),两条赋值就能达到1600~2000uS,所以当用变量的形式来赋予这么小的初值时,他的大部分时间都在赋值,所以不会起作用
那个全局变量能对定时器产生影响的,全局变量变得话会使得定时器初值改变的,要将m值设置到3000以上
有什么问题再问吧
机器人真的很多哎
我已经用其他的方法解决了这个问题,我加了个标志量,满足条件的时候切换就可以了。
那个全局变量能对定时器产生影响
为什么啊 ? 能解释吗?是数据类型的问题吗?
定时器哪儿有这样赋值的,都是先算出初值直接写进去。学死了。
按照我的理解,编译器编译成汇编时把(65536-40)当做常数来处理,直接把(65536-40)这个双字节数的高字节赋给TH0,低字节赋给TL0。而把(65536-m)/265,和(65556-m)%256,编译成两个16位常数减去一个双字节整形变量并除以256,和求余256的子程序,再把返回值赋给TH0,和TL0。这两个程序用汇编来编还是很长的
今天特意看了一下这两种方式编译后生成的汇编程序,第一种方法生成的汇编代码只有两句:
MOV TH0,#0FFH
MOV TL0,#0D8H
用6M晶振的话,每句执行时间是4uS,总共8uS。
而第二种方法生成的汇编程序先是执行一个双字节的减法程序,然后在调用一个双字节的除法子程序,一个赋值语句共1280uS,两个赋值语句总共用时2540uS。
今天特意看了一下这两种方式编译后生成的汇编程序,第一种方法生成的汇编代码只有两句:
MOV TH0,#0FFH
MOV TL0,#0D8H
用6M晶振的话,每句执行时间是4uS,总共8uS。
而第二种方法生成的汇编程序先是执行一个双字节的减法程序,然后在调用一个双字节的除法子程序,一个赋值语句共1280uS,两个赋值语句总共用时2540uS。
了解了 ,谢谢!
受教了