#include <reg52h>
unsigned int c
void main{
TMOD=0x01;//设置定时器0为工作方式1
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;//开总中断
ET0=1;//开定时器0中断
TR0=1;//启动定时器0
c=0;
while(1)
{
if(c==12000)
{c=0;}
//10分钟 很精确
}
}
void time0() interrupt 1
{ c++;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
}
要求编写延时子程序,就不要使用定时器;
也不要用C语言,因为C语言的执行时间,并不确定。
用汇编语言,是最简单、准确的。
51单片机的程序如下:
DL1000:
MOV R7,#248
DJNZ R7,$
MOV R7,#250
DJNZ R7,$
RET
正好1000个机器周期。
R7,是8位寄存器,其最大数值是255,不能直接存入500。
这个代码其实还是很清楚明了的。
DELY1: PUSH AX ;延时子程序,这里PUSH AX 其实可以不要的,因为AX没有做任何改动
PUSH CX ; 因为使用了CX来计数,所以先保存CX进堆栈
MOV CX,30H ; 循环30H也就是48次
DLY1: CALL DELY2 ; 在次调用一个延时子程序
LOOP DLY1 ; 循环,48次,不到次数则继续循环
POP CX ; 恢复被保护的原来CX的值
POP AX ; 恢复被保护的原来AX的值
RET ; 过程返回
DELY2: PUSH CX ; 内部调用的过程,也需要把CX当前的值保护进堆栈
MOV CX,8000H ; 循环8000H也就是32768次
LOOP $ ; $ 表示当前地址,也就是自己的地址,32768次循环不到则原地踏步
POP CX ; 恢复被保护的CX的值
RET ; 过程返回
1、比较死板的方法是自己写一个delay函数,里面用for,while等做一些循环,下面是1ms的延时函数
void delay1ms(void)
{
unsigned char i,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++);
}
具体算法是//(3j+2)i=(3×33+2)×10=1010(us),但精确度不高,如果想准确点可以调节相应的参数用示波器来实
现,上面的函数适用于程序简单,对时间性要求不高,如:点led灯,单个按键 *** 作等等。
2,就是用定时器中断里面设定标志位来产生延时的方法,比如你可以把定时器设定为每1ms进一次中断,在中断里面
把一个标志位(如flag)置一
当你需要1ms延时的时候你可以先初始化定时器,然后查询标志位是否置一,置一则执行if后面的语句,即if(fla{};
当你需要10ms延时时,你可以把flag设置为uchar,中断里面flag++;外面查询用if(10==flag){};
以此类推,上面的方法精确度高适用地方。
你把程序格式弄的规范一些,很好看出来的。。。我只画了一个流程图给你,另外一个也很简单的嘛,自己动手弄弄吧。。;延时子程序_1
DELAY1:
PUSH
05H
MOV
R5,#10H
DELAY2:
LCALL
DISP1
;调用子程序DISP1
DJNZ
R5,DELAY2
POP
05H
;延时子程序_2
DELAY12:
PUSH
06H
PUSH
05H
MOV
R6,#4
DELAY21:
MOV
R5,#225
DELAY31:
DJNZ
R5,DELAY31
DJNZ
R6,DELAY21
POP
05H
POP
06H
RET
END
;用汇编代码设计程序,完成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
(1)、C51语言中调用汇编语言程序;
C51语言调用汇编语言程序要注意以下几点:
1:在文件栏选中File Group和C51程序原文件,在配置文件选项中激活“产生汇编(SRC)文件,“编译(SRC)文件”和“创建工程(目标)时包含”三个选项。
2:根据选择的编译模式,把相应的库文件(如SMALL模式,库文件为KEIL\C51\LIB\C51SLIB)加入工程中。
3:在C51语言中必须声明需要调用的函数为外部函数。extern void DELAY(void);
4:在汇编语言程序中必须声明被调用子程序为公共子程序,在被调用的文件中还需要声明此文件是可从新定位的。
PUBLIC DELAY,DEL
DELAYY SEGMENT CODE
RSEG DELAYY
实例如下:
C51语言文件:
#include "reg51h"
extern void DELAY(void);
extern void DEL(void);
void main(void)
{
P1=0x00;
DELAY();
DEL();
P1=0xff;
}
汇编语言文件:
PUBLIC DELAY,DEL
DELAYY SEGMENT CODE
RSEG DELAYY
DELAY: MOV R2,#3H
DJNZ R2,$
RET
DEL: MOV R3,#03H
DJNZ R3,$
RET
END
(2)、C51语言中嵌入汇编程序;
在C51语言中嵌套使用汇编语言编写程序要注意以下的几个问题:
1:在文件栏选中File Group和C51程序原文件,在配置文件选项中激活“产生汇编(SRC)文件,“编译(SRC)文件”和“创建工程(目标)时包含”三个选项。
2:根据选择的编译模式,把相应的库文件(如SMALL模式,库文件为KEIL\C51\LIB\C51SLIB)加入工程中。
3:用#pragma asm,和#pragma endasm语句包含嵌入的汇编语言程序。
实例如下:
#include "reg51h"
void delay(void);
void main(void)
{
void delay(void);
P1=0x00;
#pragma asm
MOV R3,#08H
DJNZ R3,$
#pragma endasm
P1=0xff;
}
void delay(void)
{
#pragma asm
MOV R4,#08H
DJNZ R4,$
#pragma endasm
}
首先明确机器执行一条指令耗时大概是1us那么延时10ms的程序如下:MOV AX,50L1:MOV BX,100L2:DEC BX JNZ L2DEC AXJNZ L1执行完之后时间大约为10ms多一点
根据具体问题类型,进行步骤拆解/原因原理分析/内容拓展等。
具体步骤如下:/导致这种情况的原因主要是……
以上就是关于求C语言单片机延时10分钟子程序全部的内容,包括:求C语言单片机延时10分钟子程序、汇编语言编写一段延时1000个指令周期的子程序、我想请教一下有关汇编语言延时子程序的问题下面的子程序有点看不懂,请大家帮忙解释一下,谢谢!等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)