单片机常见延时与中断问题及解决方法
周期等于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调用就延时了。 8、今天我用单片机做“眨眼的LED”实验时,程序运行,每次只令灯亮或灭都没问题,但是一开延时不能出现期盼的灯亮灯灭的现象,这是怎么回事? 实验的硬件条件是:STC89C52,编译环境:keil 3。 下面是我写的程序,请教高手!!! #include #define uchar unsigned char //宏定义,方便以后程序的书写 #define uint unsigned int sbit P1_0 = P1 ^ 0; //位变量定义 void Delay(uint t) { uchar i; while(--t) { for(i = 0; i 125; i++) //延时1MS,在这里我们用的晶振是是12M,根据机器周期的计算,我们 {;} //可算得本次循环延时约1MS } } void main(void) { while(1) { P1_0 = 0; //点亮LED灯 Delay(1000); //应单片执行程序的时间很快,所以必须延时,要不看不到实验现象 P1_0 = 1; //熄灭LED灯 } 补充提问:我是让P1.0先低然后延时之后再高,即灯先亮再灭,然后开始循环的 答:应该这样写 while(1) { P1_0 = 0; //点亮LED灯 Delay(1000); //应单片执行程序的时间很快,所以必须延时,要不看不到实验现象 P1_0 = 1; //熄灭LED灯 Delay(1000); 补充问题回复:问题恰恰就错在这了,循环完一遍之后灯由灭到亮根本没有时间延时,即第一次循环中灯还没来的机灭呢,就进入到第二轮循环中的亮了,所以原因就在这,这错误太低级了,以后引以为鉴吧 9、单片机延时函数的问题 void delay(uchar i) { uchar j; while(i--) { for(j=125;j>0;j--) ; } } 这个函数中的i,j的大小有**吗? 答:这个函数中j的大小和你定义的数据类型有关,因为你定义的为无符号字符型,为单字节数据,所以最大为255。. 如果你需要增大,可以改变j的数据类型定义,如unsigned int (2字节)可以到65535;无符号长整形unsigned long(4字节) 可以到4294967295。 而上面所所256是-1,而你定义的是无符号字符型。 10、请教一个AVR单片机延时的问题 外部晶振用的是8MHz,延时1微秒的程序如下: void delay_us(unsigned int delay_counter)//延时1us { do { delay_counter--; } while(delay_counter>1); } 请问,为什么能延时1微秒啊? 答:8MHZ表示单片机的运行周期为1/8us,也就是0.125us执行一步 你使用的是软件延时 那么包括程序的提取,执行等都要花费时间 比如,你提取这个函数可能花去一步,那现在就使用了0.125us啦 接着你执行这个函数,在单片机内部,运算是通过寄存器的移来移去实现的 这都需要时间,可能你看到的就一句counter--这个指令,可能会花费好几个时钟周期来实现 举个例子: c=a+b,只有一句,但实际上花费的时间并不短 mov a,#data1;//数据data1放入a寄存器 mov b,#data2;//数据data2放入b寄存器 add a,b;//寄存器a的值与b相加,结果放入a mov c,a;//将a的值放入c 这样才是单片机内部真正执行的指令,这需要花费至少4个时钟周期,而不是1个 至于晶体管级的我就不解释了,你得好好学习汇编才能理解单片机的运作。 至于这个函数为什么能延时1ms,这个是靠经验来判断的,最直接的方法就是用示波器看,以上均为推论。 11、PIC单片机的延时问题 晶振4Mhz: void delay() { unsigned int d=1000; while(--d){;} } 此函数在4M晶体下产生10003us的延时,也就是10MS。 问题:我刚算了一下他应该执行了999条指令,1条单周期的指令也才1US,那就是999us,为什么会有10ms的延时? 1:for(x=100;--x;){;} : 2: for(x=0;x100;x++){;} 2句话相同 第一句:X的值范围是不是 1~99?为什么? 第二句:X的范围是不是0~99?为什么?这么算的。我知道符号在前在后的区别。2句话应该是不一样的才对啊! 答: 问题1:“我刚算了一下他应该执行了999条指令”因为你算错了。延时时间是由产生的汇编代码所决定的,C语言语句只是个假象,千万不要以为C语言一行就是一条指令!此处由于涉及到双字节减法,因此会有额外的判断,编译结果每次循环耗费几十个周期毫不奇怪。 问题2:前一句x从100开始递减,递减至1时退出循环。后一句x从0开始递增,递增到100时退出循环。所谓“2句话”相同仅仅是指这两个循环体的循环次数相同。实际上两个循环的执行过程是完全不同的,所消耗时间也有可能不同。 12、stc单片机的延
- FPGA的DSP性能揭秘(06-16)
- 基于单片机通用引脚的软件UART设计(10-16)
- 分时操作系统思想在单片机中的具体应用 (10-30)
- 基于AT89C51+DSP的双CPU伺服运动控制器的研究(05-26)
- 关于RTX51 TINY的分析与探讨(05-30)
- 基于MC9S12DGl28单片机的智能寻迹车设计(04-03)