1、下面几个是单片机的延时程序(包括asm和C程序,都是我在学单片机的过程中用到的),在单片机延时程序中应考虑所使用的晶振的频率,在51系列的单片机中我们常用的是110592MHz和120000MHz的晶振,而在AVR单片机上常用的有8000MHz和4000MH的晶振所以在网上查找程序时如果涉及到精确延时则应该注意晶振的频率是多大。
2、软件延时:(asm)
晶振12MHZ,延时1秒
程序如下:
DELAY:MOV 72H,#100
LOOP3:MOV 71H,#100
LOOP1:MOV 70H,#47
LOOP0:DJNZ 70H,LOOP0
NOP
DJNZ 71H,LOOP1
MOV 70H,#46
LOOP2:DJNZ 70H,LOOP2
NOP
DJNZ 72H,LOOP3
MOV 70H,#48
LOOP4:DJNZ 70H,LOOP4
定时器延时:
晶振12MHZ,延时1s,定时器0工作方式为方式1
DELAY1:MOV R7,#0AH ;;晶振12MHZ,延时05秒
AJMP DELAY
DELAY2:MOV R7,#14H ;;晶振12MHZ,延时1秒
DELAY:CLR EX0
MOV TMOD,#01H ;设置定时器的工作方式为方式1
MOV TL0,#0B0H ;给定时器设置计数初始值
MOV TH0,#3CH
SETB TR0 ;开启定时器
HERE:JBC TF0,NEXT1
SJMP HERE
NEXT1:MOV TL0,#0B0H
MOV TH0,#3CH
DJNZ R7,HERE
CLR TR0 ;定时器要软件清零
SETB EX0
RET
3、C语言延时程序:
10ms延时子程序(12MHZ)
void delay10ms(void)
{
unsigned char i,j,k;
for(i=5;i>0;i--)
for(j=4;j>0;j--)
for(k=248;k>0;k--);
}
1s延时子程序(12MHZ)
void delay1s(void)
{
unsigned char h,i,j,k;
for(h=5;h>0;h--)
for(i=4;i>0;i--)
for(j=116;j>0;j--)
for(k=214;k>0;k--);
}
200ms延时子程序(12MHZ)
void delay200ms(void)
{
unsigned char i,j,k;
for(i=5;i>0;i--)
for(j=132;j>0;j--)
for(k=150;k>0;k--);
}
500ms延时子程序程序: (12MHZ)
void delay500ms(void)
{
unsigned char i,j,k;
for(i=15;i>0;i--)
for(j=202;j>0;j--)
for(k=81;k>0;k--);
}
定义一个延时xms毫秒的延时函数
void delay(unsigned int xms) // xms代表需要延时的毫秒数
{
unsigned int x,y;
for(x=xms;x》0;x--)
for(y=110;y》0;y--);
}
使用:
void Delay10us(uchar Ms)
{
uchar data i;
for(;Ms》0;Ms--)
for(i=26;i》0;i--);
}
i=[(延时值-175)12/Ms-15]/4
扩展资料1、在C51中进行精确的延时子程序设计时,尽量不要或少在延时子程序中定义局部变量,所有的延时子程序中变量通过有参函数传递。
2、在延时子程序设计时,采用dowhile,结构做循环体要比for结构做循环体好。
3、在延时子程序设计时,要进行循环体嵌套时,采用先内循环,再减减比先减减,再内循环要好。
正好做过,就给你吧!
;
; 主程序和中断程序入口
;
;
ORG 0000H
LJMP START
ORG 0003H
RETI
ORG 000BH
RETI
ORG 0013H
RETI
ORG 001BH
RETI
ORG 0023H
RETI
ORG 002BH
RETI
;
;
;
; 初始化程序中的各变量
;
;
CLEARMEMIO: CLR A
MOV P2,A
MOV R0,#70H
MOV R2,#0DH
LOOPMEM: MOV @R0,A
INC R0
DJNZ R2,LOOPMEM
MOV 20H,#00H
MOV A,#0FFH
MOV P0,A
MOV P1,A
MOV P3,A
RET
;
;
;
; 主 程 序
;
;
START: LCALL CLEARMEMIO ;初始化
MAIN: LCALL TEST ;测量一次
LCALL DISPLAY ;显示数据一次
AJMP MAIN
NOP ;PC值出错处理
NOP
NOP
LJMP START
;
;
; 显 示 控 制 程 序
;
;
DISPLAY: JB 00H,DISP11 ;
MOV R3,#04H ;4路信号循环显示控制
MOV R0,#70H ;显示数据初址70H~73H
MOV 77H,#00H ;显示通道路数初值
DISLOOP1: LCALL TUNBCD ;显示数据转为三位BCD码存入76H、75H、74H(最大500v)
MOV R2,#0FFH ;每路显示时间控制 4MS255
DISLOOP2: LCALL DISP ;调四位显示程序
LCALL KEYWORK1 ;
DJNZ R2,DISLOOP2 ;
INC R0 ;显示下一路
INC 77H ;通道显示数加一
DJNZ R3,DISLOOP1
RET
;
DISP11: MOV A,77H ;
SUBB A,#01H ;
MOV 77H,A ;
ADD A,#70H ;
MOV R0,A ;
DISLOOP11: LCALL TUNBCD ;显示数据转为三位BCD码存入7AH、79H、78H(最大500v)
MOV R2,#0FFH ;每路显示时间控制 4MS25
DISLOOP22: LCALL DISP ;调四位显示程序
LCALL KEYWORK2 ;
DJNZ R2,DISLOOP22
INC 77H ;通道显示数加一
RET
;
;
; 显示数据转为三位BCD码程序
;
;显示数据转为三位BCD码存入76H、75H、74H(最大值500v)
;
TUNBCD: MOV A,@R0 ;255/51=500V运算
MOV B,#51 ;
DIV AB ;
MOV 76H,A ;个位数放入76H
MOV A,B ;余数大于19H,F0为1,乘法溢出,结果加5
CLR F0
SUBB A,#1AH
MOV F0,C
MOV A,#10 ;
MUL AB ;
MOV B,#51 ;
DIV AB
JB F0,LOOP2 ;
ADD A,#5
LOOP2: MOV 75H,A ;小数后第一位放入75H
MOV A,B
CLR F0
SUBB A,#1AH
MOV F0,C
MOV A,#10 ;
MUL AB ;
MOV B,#51 ;
DIV AB
JB F0,LOOP3 ;
ADD A,#5
LOOP3: MOV 74H,A ;小数后第二位放入74H
RET
;
;
; 显示 程 序
;
;共阳显示子程序,显示内容在74H—77H
;
DISP: MOV R1,#74H ;共阳显示子程序,显示内容在74H—77H
MOV R5,#0FEH ;数据在P1输出,列扫描在P30-P33
PLAY: MOV P1,#0FFH
MOV A,R5
ANL P3,A
MOV A,@R1
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV P1,A
JB P32,PLAY1 ;小数点处理
CLR P17 ;小数点显示(显示格式为XXXX)
PLAY1: LCALL DL1MS
INC R1
MOV A,P3
JNB ACC3,ENDOUT
RL A
MOV R5,A
MOV P3,#0FFH
AJMP PLAY
ENDOUT: MOV P3,#0FFH
MOV P1,#0FFH
RET
TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH
;
;
; 延时程序
;
;
DL10MS: MOV R6,#0D0H ;10MS延时子程序
DL1: MOV R7,#19H
DL2: DJNZ R7,DL2
DJNZ R6,DL1
RET
;
DL1MS: MOV R4,#0FFH ;513+513=1MS
LOOP11: DJNZ R4,LOOP11
MOV R4,#0FFH
LOOP22: DJNZ R4,LOOP22
RET
;
;
; 电压测量(A/D)子程序
;
; 一次测量数据4个,依次放入70H-73H单元中
;
TEST: CLR A ;模数转换子程序
MOV P2,A
MOV R0,#70H ;转换值存放首址
MOV R7,#04H ;转换4次控制
LCALL TESTART ;启动测试
WAIT: JB P37,MOVD ;等A/D转换结束信号
AJMP WAIT
;
TESTART: SETB P23 ;测试启动
NOP
NOP
CLR P23
SETB P24
NOP
NOP
CLR P24
NOP
NOP
NOP
NOP
RET
;
MOVD: SETB P25 ;取A/D转换数据
MOV A,P0
MOV @R0,A
CLR P25
INC R0
MOV A,P2 ;通道地址加1
INC A
MOV P2,A
CJNE A,#04H,TESTEND ;等8路A/D转换结束
TESTEND: JC TESTCON
CLR A ;结束恢复端口
MOV P2,A
MOV A,#0FFH
MOV P0,A
MOV P1,A
MOV P3,A
RET
;
TESTCON: LCALL TESTART
LJMP WAIT
;
;
; 按键检测子程序
;
;
KEYWORK1: JNB P35,KEY1
KEYOUT: RET
;
KEY1: LCALL DISP ;延时消抖
JB P35,KEYOUT
WAIT11: JNB P35,WAIT12
CPL 00H
MOV R2,#01H
MOV R3,#01H
RET
;
WAIT12: LCALL DISP ;键释放等待时显示用
AJMP WAIT11
;
KEYWORK2: JNB P35,KEY1
JNB P36,KEY2
RET
;
KEY2: LCALL DISP ;延时消抖用
JB P36,KEYOUT
WAIT22: JNB P36,WAIT21
INC 77H
MOV A,77H
CJNE A,#04H,KEYOUT11
KEYOUT11: JC KEYOUT1
MOV 77H,#00H
KEYOUT1: RET
;
WAIT21: LCALL DISP ;键释放等待时显示用
AJMP WAIT22
;
END
附录3:
单片机C源程序清单
//
// 四路电压表C程序
// 使用keil C51 ver709
//
/使用AT89C52单片机,12MHZ晶振,P0口读入AD值,P2口作AD控制,用共阳LED数码管
P1口输出段码,P3口扫描,最高位指示通道(0-7)。/
#include "reg52h" //52系列单片机定义文件
#include "intrinsh" //调用_nop_();延时函数用
#define ad_con P2 //AD控制口
#define addata P0 //AD数据计入读入口
#define Disdata P1 //显示数据段码输出口
#define uchar unsigned char//无符号字符(8位)
#define uint unsigned int //无符号整数(16位)
sbit ALE=P2^3; //锁存地址控制位
sbit START=P2^4; //启动一次转换位
sbit OE=P2^5; //0809输出数据控制位
sbit EOC=P3^7; //转换结束标志位
sbit DISX=Disdata^7; //LED小数点
//
//
uchar code dis_7[11]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff};
/ 共阳七段LED段码表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" /
uchar code scan_con[4]={0xfe,0xfd,0xfb,0xf7}; //四位列扫描控制字
uchar data ad_data[8]={0x00,0x00,0x00,0x00};//定义4个数据内存单元
uint data dis[5]={0x00,0x00,0x00,0x00,0x00}; //定义4个显示数据单元、1个数据暂存单元
//
//
/1毫秒延时子函数/
delay1ms(uint t)
{
uint i,j;
for(i=0;i<t;i++)
for(j=0;j<120;j++)
;
}
//
//
/显示扫描子函数/
scan()
{
uchar k,n;
int h;
dis[3]=0x00; //通道初值为0
for(n=0;n<4;n++) //每次显示4个数据
{
dis[2]=ad_data[n]/51; //测得值转换为三位BCD码,最大为500V
dis[4]=ad_data[n]%51; // 余数暂存
dis[4]=dis[4]10; //计算小数第一位
dis[1]=dis[4]/51; //
dis[4]=dis[4]%51; //
dis[4]=dis[4]10; //计算小数第二位
dis[0]=dis[4]/51; //
for(h=0;h<500;h++) //每个通道值显示时间控制(约1秒)
{
for(k=0;k<4;k++) //四位LED扫描控制
{
Disdata=dis_7[dis[k]];
if(k==2){DISX=0;}
P3=scan_con[k];delay1ms(1);P3=0xff;
}
}
dis[3]++; //通道值加1
}
}
//
//
/0809AD转换子函数/
test()
{
uchar m;
uchar s=0x00;
ad_con=s;
for(m=0;m<4;m++)
{
ALE=1;_nop_();_nop_();ALE=0; //转换通道地址锁存
START=1;_nop_();_nop_();START=0; //开始转换命令
_nop_();_nop_();_nop_();_nop_(); //延时4微秒
while(EOC==0); //等待转换结束
OE=1;ad_data[m]=addata;OE=0;s++;ad_con=s;//取AD值,地址加1
}
ad_con=0x00; //控制复位
}
//
//
/主函数/
main()
{
P0=0xff; //初始化端口
P2=0x00;
P1=0xff;
P3=0xff;
while(1)
{
scan(); //依次显示4个通道值一次
test(); //测量转换一次
}
}
//
//
//结束//
一、用定时器中断,50ms中断的1 次,20次就是1秒
#include <REG51H>
#define uchar unsigned char
sbit LED =P1^1; //接一LED,1 秒钟亮或灭一次
uchar time;
void init_t0int()
{
TMOD=0x01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void main()
{
init_t0int();
while(1);
}
void t0int() interrupt 1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
time++;
if(time==20)
{
time=0;
LED=~LED;
}
}
二、用循环延时可能程序更简单一点,但没实际意义 。单片机在这1 秒内只能循环而不能做其它事。
#include<reg51h>
sbit LED=P1^0;
void delay_ms(unsigned char ms)
{
unsigned char i;
while(ms--)
for(i=0;i<123;i++);
}
void main()
{
while(1)
{
delay_ms(1000);
LED=~P1^0; //P10接一LED,可看到LED每1S亮或灭一次
}
}
参考资料:
以上就是关于51单片机求10微秒的延时函数 C语言(晶振11.0592MHz)全部的内容,包括:51单片机求10微秒的延时函数 C语言(晶振11.0592MHz)、51单片机C语言中delay函数是怎么定义和使用的、用汇编语言写一个51单片机adc0809的程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)