十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
计数器是按机器周期算的
成都创新互联专注骨干网络服务器租用10年,服务更有保障!服务器租用,达州电信机房 成都服务器租用,成都服务器托管,骨干网络带宽,享受低延迟,高速访问。灵活、实现低成本的共享或公网数据中心高速带宽的专属高性能服务器。
一个机器周期=12时钟周期
不管时钟多少,都按一个机器周期=12时钟周期计算 //**** 关键 ****//
12MHZ时钟换过来就是1M机器周期(1M/S)
1ms就是1000机器周期;
6MHZ时钟换过来就是0.5M机器周期(0.5M/S)
1ms就是500机器周期
8位计数器最高范围是65536,
如果我们要记时1s,可以以10ms为单位,循环记时100次
现在就是初始化,10ms为例
TL0=-10000; //对T0计数初始化赋值,用12M的JT,10ms也就是机器周期计数10000
TH0=-100008;
这就是初始化,一次溢出10ms
(若用6M的JT,10ms也就是机器周期计数5000)
当然这只是其中一部分,具体还有比如TR0(1)的设置
溢出中断允许等!
上面两句等价于
TL0=55536;//(65536-10000)
TH0=555368;
相当于从55536开始数,
数10000次(10ms)后溢出,为一个记数周期
100次后就是1s
上述过程是在中断服务程序中的
上面的内容不知道对你有没有用~~(网上找的)
用中断,定时器工作方式1,计数最大数为65536,那么从15536开始计数,达到65536要计50000次,6M的晶振机器周期为2微秒,那么溢出一次耗时为100000微秒,计数溢出10次即为1秒钟
ORG 000BH
AJMP TIME0
ORG 30H
MAIN:
MOV 30H,#00H;先把30H地址的数据清零,用做给溢出计数用
MOV TMOD,#00000001B
MOV TH0,#3CH
MOV TL0,#0B0H
SETB EA
SETB ET0
SETB TR0
LOOP:AJMP LOOP
TIME0:PUSH ACC
PUSH PSW
INC 30H;进入中断后就自增
MOV A,30H
CJNE A,#10,T_RET;看计数器的溢出到了10次没,没有就跳到T_RET再继续从15536计数
T_L1:延时1秒到了,写自己的程序吧。
MOV 30H,#00H;记得把溢出计数器再次清零
T_RET:MOV TH0,#3CH
MOV TL0,#0B0H
POP PSW
POP ACC
RETI
END
延时有很多种方法,有一种是让单片机去做无聊的循环,
还有一种是用定时器。
我本身也是菜鸟所以只能粗略的讲一下。
第一种的算法是
晶振的周期T1=1/f; 这里f=6MHz 所以T1=1/6 us;(微秒)
单片机花12个T1去执行一个指令,
所以一个机器周期等于12个晶振周期,
T2=12*T1=2us
10ms=1000 0us
所以你要得到10ms的延时就要想办法让机器去做5000条“无聊的指令”
所以
DEL: MOV R5,#05H
F1: MOV R6,#05H
F2: MOV R7,#32H
F3: DJNZ R7,F3
DJNZ R6,F2
DJNZ R5,F1
RET
这种方法是用于对时间要求不高的地方,我说的是其思想,程序中可能有错的地方
用定时器的方法我不太会就不误人了 (补充一下就是这个是用汇编写的,你在主程序中用ACALL DEL调用就延时了。
通过调用这个子程序就可以实现
DEL1S: MOV R1,#10
DEL1: MOV R2,#100
DEL2: MOV R3,#250
DEL3: DJNZ R3,DEL3 ;2*2*250*100*10=1000000us
DJNZ R2,DEL2
DJNZ R1,DEL1
RET
没有做具体计算,要准确的定时1s的话可以稍微改动一下R1R2R3的值。6M晶振则机器周期为2us,一条指令执行为2个机器周期,由此得出其延时时间
最好的方式是使用定时器中断来做延时,更精确
C语言软件延时一般用for循环或while循环:
void delay(unsigned int data)
{
unsigned int i, j;
for(i=data; i!=0; i--)
for(j=1000; j!=0; j--);
}
void delay(unsigned int data)
{
unsigned int i, j;
i=data;
while(i--)
for(j=1000; j!=0; j--);
}
不同的单片机指令周期不太一样,
想精确延时200ms,最好用protue软件仿真一下,或者自己也可以在开发环境中利用断点调试。
PS:用定时器是最好的方法。
6M晶振,方式2定时1mS的时间太长,不能直接实现,(最大定时应该是512uS)下面是500uS定时示例程序,可在中断函数中计数每2次得1S。
void Timer1Init(void) //500微秒@6.000MHz
{
AUXR = 0xBF; //定时器时钟12T模式
TMOD = 0x0F; //设置定时器模式
TMOD |= 0x20; //设置定时器模式
TL1 = 0x06; //设置定时初值
TH1 = 0x06; //设置定时重载值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
}