;用汇编代码设计程序,完成8个LED灯的循环闪烁:
;LED1亮,其余灭->LED2亮,其余灭……,如此循环5次后,
;进行全灭->全亮闪烁,时间间隔为500ms用p0口控制
下列程序已经测试通过
;----------------------
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP T0_INT
MAIN:
SETB TR0 ;T0定时方式0
MOV SP, #60H
MOV IE, #82H
MOV B, #61 ;定时500ms,500 000 / 8192 = 61
;-----------------------
MOV A, #127
MOV R1, #40
LP0:MOV P0, A
JBC F0, $ + 5
SJMP $ - 3
RR A
DJNZ R1, LP0
;-----------------------
CLR A
LP1:MOV P0, A
JBC F0, $ + 5
SJMP $ - 3
CPL A
LJMP LP1
;-----------------------
T0_INT: ;自动重新装入0
DJNZ B, T0_END
MOV B, #61
SETB F0
T0_END:
RETI
;-----------------------
END
如果单纯延时,可以用实验的办法,在keilc51里面仿真
void Delay1S(char n)
{
char i,j;
n=n4;
for(;n;n--)
{
for(i=6;i;i++)
{
for(j=7;j;j++) // 一个循环约为1mS
;
}
}
}
看编译后的汇编:
C:0x0805 7D01 MOV R5,#0x06;j=1,1时钟
C:0x0807 0D INC R5;j++,1时钟
C:0x0808 ED MOV A,R5;A=R5,1时钟
C:0x0809 70FC JNZ C:0807;A=0,2时钟
循环共249次,一个循环共需4个时钟周期,加上第一个赋值语句1周期。
共997uS,加上外层循环,一次约1mS,
如果要精确的延时建议采用中断:
#include "reg51h"
//timer init
void initTimer(void)
{
TMOD=0x2;
TH0=0x6;
TL0=0x6;
}
int T250uS;
char T_mark;
//timer0/counter0 interrupt
void timer0(void) interrupt 1
{
//add your code here
T250uS++;
T_mark=0;
}
void Delay1S(char n)
{
for(;n;n--)
for(T250uS=0;T250uS<4000;)
{
T_mark=1;
while(T_mark);
}
}
//the main fun
void main(void)
{
initTimer();
TR0=1;
ET0=1;
EA=1;
while(1)
{
Delay1S(1);
}
}
用定时器做,同时在定时器中计数,比如10ms中断一次,那么计数达到100次就行了。
思路:1S的延时比较长了,单片机还要干其他的工作,那么就不能用循环等待方式,定时器是个比较好的选择,定时器的一个中断没有那么长的时间,就需要定时累加的办法。
把定时器设置成定时模式方式1,使用T0,则TMOD=0x01
6Mhz对应的机器周期是2us
则定时时间=(最大值-X)2us
20ms =( 65536-X )2us x=55536 对应的十六进制 D8F0
所以TH0=0xD8,TL0=0xF0
开中断 ET0=1;EA=1
启动定时器TR0=1
用delay来产生延时在要求较高的场合不大合适。
可调用系统时间来产生准确的延时,并且可控制延迟时间
TEMP: MOV AH,2CH
INT 21H
ADD DH,5 ;获得时间DH为 当前的秒数,5秒可以自己选择
PUSH DX
WAIT:
POP DX
MOV AL,DH
PUSH DX
MOV AH,2CH ;新的时间
INT 21H
CMP DH,AL
JB WAIT ;小于5秒的话继续查询
欢迎讨论
以上就是关于关于AT89c51单片机定时器实现延时子程序的问题全部的内容,包括:关于AT89c51单片机定时器实现延时子程序的问题、51单片机用汇编语言设计1S延时子程序,晶振为12MHz。 (麻烦附上详细计算过程以及详细说明,、1S延时子程序设计思路等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)