
如果单纯延时,可以用实验的办法,在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);
}
}
delay1000ms:(HT46R65的单片机)(注意不要开启计时中断允许位)
mov a,10000111b (设置频率和记数方式)(上升记数还是下降记数)
mov tmr0c,a (tmr0c 计数器的控制寄存器)
mov a,low(65536-31250) (设置的频率就是1S上升31250)因此是DELAY1S
mov TMR0L,a (计数器的赋予初始值的低位寄存器)
mov a,high(65536-31250)
mov TMR0h,a(计数器的赋予初始值的高位寄存器)
set tmr0c4 (打开记数)
snz intc06 (是否有中断请求标志)(有就跳过)
jmp $-1 (退回一步)
clr tmr0c4 (关闭记数)
clr intc06 (清除中断标志)
ret
用定时器1的工作方式2实现延时1s 不好,方式2最大只能定时256us,中断太频繁了
主程序中:
uint a=0;
TMOD=0X20;
TH1=256-200;//定时200us
TL1=256-200;
ET1=1;
EA=1;
TR1=1;
中断程序里:
a++;
if(a ==5000)
{
a=0;
其它 *** 作
}
//----假设,系统工作于
12mhz/12t的传统51单片机下#include
<reg51h>
sbit
test
=
p1^0;
void
delay_50ms(unsigned
char
times)
{
while(times
--
)
{
th0
=
0x3c;
//----装入初值,定时器0定时50ms
tl0
=
0xb0;
tr0
=
1;
//-----启动定时器
while(!tf0);
//-----等等定时时间到达
tf0
=
0;
//-----清零定时到达标志
}
}
void
delay_1s(unsigned
char
times)
{
while(times
--
)
{
delay_50ms(20);
}
}
void
main(void)
{
tmod
=
0x01;
//----定时器0工作于方式1
while(1)
{
delay_1s(2);
test
=
~test;
}
}
#include "reg52h" //此文件中定义了单片机的一些特殊功能寄存器#include//因为要用到左右移函数,所以加入这个头文件
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
u16 t=0;
void Timer0Init()
{
TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
}
void Timer0() interrupt 1
{
TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
t++;
}
void main (){
Timer0Init();
while(1){
if(t==1000)
{
t=0;
break;
} //延时1s
}
}
通用办法,可以类推:
DELAY1s:MOV R5,#08H ; ∵ 1s=1000000us
MOV R6,#0A2H ; ∴ 1000000/2=500000
MOV R7,#20H ; 500000用16进制表示为: 07A120
; 所以 R5=07H+1=08H
; R6=0A1H+1=0A2H
; R7=20H
loop: DJNZ R7,$ ; 延时时间≈2×[(R5-1)×256+R6-1]×256+R7
DJNZ R6,loop ; 当R5、R6等于0,相当于256参与运算
DJNZ R5,loop ; 当R5、R6等于0,相当于256参与运算
RET
以上就是关于51单片机用汇编语言设计1S延时子程序,晶振为12MHz。 (麻烦附上详细计算过程以及详细说明,全部的内容,包括:51单片机用汇编语言设计1S延时子程序,晶振为12MHz。 (麻烦附上详细计算过程以及详细说明,、单片机。用汇编语言编程。 设计一软件延时1s的子程序。设晶振频率为12MHz。、用定时器1的工作方式2实现延时1s的程序是什么(单片机)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)