这个原因还是蛮多的,分同的情况,单片机的处理速度是很快的,有的时候为了让我们便于观察需要加入延时,例如一个指示灯的亮灭,如果不加入延时是看不出来的,再有就是键盘去抖动,一般按键都有20ms左右的抖动,为了更好的检测防止干扰,也需要延时一段时间在进行判断,总之延时的作用在不同的情况下也不同。
具体的使用例程将在之后学习中不断补充。
摘自 http://zhidao.baidu.com/question/171796304.html百度回答,谢谢答主
-
为什么单片机程序中会有延时程序加入
2016-05-28 19:10:00这个原因还是蛮多的,分同的情况,单片机的处理速度是很快的,有的时候为了让我们便于观察需要加入延时,例如一个指示灯的亮灭,如果不加入延时是看不出来的,再有就是键盘去抖动,一般按键都有20ms左右的抖动,为了...转载于:https://www.cnblogs.com/caolinsummer/p/5538130.html
-
单片机音乐程序的设计原理解析
2020-07-14 00:17:05例如,要产生200Hz的音频信号,按图1接入喇叭(若属临时实验,也可将喇叭直接接在P1口线上),实验程序为:其中子程序DEL为延时子程序,当R3为1时,延时时间约为20us,R3中存放延时常数,对200HZ音频,其周期为1/200... -
【单片机】前后台程序框架中单定时器实现多延时任务
2020-10-09 21:58:28前言说明 ...如要求每 500ms 上报一次 ADC 检测的值,通过判断这个全局变量是否大于 5000 (500*10),如果大于的话就将 ADC 值通过串口发出去,实现间隔 500ms 上报一次。 其实这个思想是很不错的,但前言说明
在我所接触到的很多MCU源代码(不跑RTOS),无论是我们的同事还是其它方案的源代码,为了实现某些不需要太精确固定周期的工作,常见的做法都会是启动一个定时器,按照比较小的间隔来产生中断,如 0.1 毫秒一次,在定时器中断函数里面进行计数,根据计数值来给多个全局变量置1,在需要的源文件里面导出这些全局变量。如要求每 500ms 上报一次 ADC 检测的值,通过判断 500ms 的全局变量是否被置1,如果置位的话就将 ADC 值通过串口发出去,并且将这个全局变量设置为0,实现间隔 500ms 上报一次。
其实这个思想是很不错的,但是经常看到这些全局变量满天飞,真心有些受不了,即使有些源码将所有需要判断这些全局变量的地方集中在一个源文件,N多的 IF 语句,也会让人看的眼花缭乱,特别是与上下文的变量名相似时,特别容易出错,实在是不好维护。碰到这种源码,在项目时间容许的情况下,我大概率会选择重写,不然真的是太痛苦了。(通常这种全局变量满天飞的源代码,其它的功能实现的代码都好不到哪去)
因为这种方法很常用,也很好用,所以我将其作为基础接口进行封装,实测效果不错,核心思想并未改变。
封装源码
time_base.h
/** ****************************************************************************** * @文件 time_base.h * @版本 V1.0.0 * @日期 * @概要 计时功能接口 * @作者 lmx * @邮箱 lovemengx@qq.com ****************************************************************************** * @注意 * ****************************************************************************** */ #ifndef TIME_BASE_H #define TIME_BASE_H // 可选的时间点 typedef enum { TIME_BASE_FLAGS_01MS = 1 << 0, TIME_BASE_FLAGS_1MS = 1 << 1, TIME_BASE_FLAGS_10MS = 1 << 2, TIME_BASE_FLAGS_100MS = 1 << 3, TIME_BASE_FLAGS_500MS = 1 << 4, TIME_BASE_FLAGS_1000MS = 1 << 5, TIME_BASE_FLAGS_2000MS = 1 << 6, TIME_BASE_FLAGS_3000MS = 1 << 7, TIME_BASE_FLAGS_ALL = 0xFF, }timer_base_flags_e; // 初始化和释放 void time_base_init(); void time_base_release(); // 主循环里面每完成一个循环都需要调用一次 void time_base_update_flags(); // 各个功能模块需要在某个时间点执行的时候调用, 传入对应的标志即可判断时间点是否达到 unsigned char time_base_is_flags(timer_base_flags_e flags); #endif
time_base.c
/** ****************************************************************************** * @文件 time_base.h * @版本 V1.0.0 * @日期 * @概要 计时功能接口 * @作者 lmx * @邮箱 lovemengx@qq.com ****************************************************************************** * @注意 * ****************************************************************************** */ #include "gd32e23x.h" #include "configuration.h" #include "time_base.h" // 定义定时器基准结构 typedef struct { unsigned int bitmap; // 使用位来记录各个时间点是否到位 unsigned int time[8]; // 每一个数据位置位所需要的计数值 }timer_base_flags_t; // 这里的值与 timer_base_flags_e 一一对应, 并且与定时器中断时间相关 // 定时器每 0.1ms 会产生一次中断, 这里的值必须是从小到大 static volatile timer_base_flags_t timer_base_flags = { .bitmap = 0x00, .time[0] = 1, // 0.1ms .time[1] = 10, // 1ms .time[2] = 100, // 10ms .time[3] = 1000, // 100ms .time[4] = 5000, // 500ms .time[5] = 10000, // 1000ms .time[6] = 20000, // 2000ms .time[7] = 30000, // 3000ms }; #define TIMER_BASE_TIME_ARRAR_MAX (sizeof(timer_base_flags.time) / sizeof(timer_base_flags.time[0])) // 用于被外部接口判断指定时间点是否到达 static volatile unsigned int timer_bitmap = 0x00; // 定时器中断服务程序 void CFG_TIME_BASE_IRQ_FUNCTION(void) { static unsigned int time_01ms_count = 0; static unsigned int i = 0; if(RESET != timer_interrupt_flag_get (CFG_TIME_BASE_TIMER, TIMER_INT_FLAG_UP)) { timer_interrupt_flag_clear(CFG_TIME_BASE_TIMER, TIMER_INT_UP); // 计数器计数, 当达到最大值时会自动复位为 1 time_01ms_count = time_01ms_count % timer_base_flags.time[TIMER_BASE_TIME_ARRAR_MAX - 1] + 1; timer_base_flags.bitmap |= 1 << 0; // 依次各个时间点是否到达 for(i = 1; i < TIMER_BASE_TIME_ARRAR_MAX; i++){ if(0 == time_01ms_count % timer_base_flags.time[i]){ timer_base_flags.bitmap |= 1 << i; } } } } // 更新标志位 void time_base_update_flags() { static unsigned int i = 0; // 拷贝当前时间标志位, 便于其他模块判断指定的时间点是否抵达 timer_interrupt_disable(CFG_TIME_BASE_TIMER, TIMER_INT_UP); timer_bitmap = timer_base_flags.bitmap; timer_base_flags.bitmap &= ~timer_base_flags.bitmap; timer_interrupt_enable(CFG_TIME_BASE_TIMER, TIMER_INT_UP); return ; } // 判断标志位 unsigned char time_base_is_flags(timer_base_flags_e flags) { return timer_bitmap & flags ? 1 : 0; } // 初始化 void time_base_init() { timer_parameter_struct para; rcu_periph_clock_enable(CFG_TIME_BASE_RCU_CLOCK); timer_deinit(CFG_TIME_BASE_TIMER); para.prescaler = 720 - 1; // 72M720分频100khz para.alignedmode = TIMER_COUNTER_EDGE; para.counterdirection = TIMER_COUNTER_UP; //向上计数 para.period = 10 - 1; // 0.1 ms para.clockdivision = 0; //不分频 para.repetitioncounter = 0; //计数重复值0 timer_init(CFG_TIME_BASE_TIMER, ¶); nvic_irq_enable(CFG_TIME_BASE_IRQ_NUMBER, 0U); timer_interrupt_enable(CFG_TIME_BASE_TIMER, TIMER_INT_UP); timer_auto_reload_shadow_enable(CFG_TIME_BASE_TIMER); timer_enable(CFG_TIME_BASE_TIMER); return ; } // 释放 void time_base_release() { timer_interrupt_disable(CFG_TIME_BASE_TIMER, TIMER_INT_UP); nvic_irq_disable(CFG_TIME_BASE_IRQ_NUMBER); timer_disable(CFG_TIME_BASE_TIMER); rcu_periph_clock_disable(CFG_TIME_BASE_RCU_CLOCK); return ; }
configuration.h
/** ****************************************************************************** * @文件 configuration.h * @版本 V1.0.0 * @日期 * @概要 配置信息文件 * @作者 lmx * @邮箱 lovemengx@qq.com ****************************************************************************** * @注意 * ****************************************************************************** */ #ifndef CONFIGURATION_H #define CONFIGURATION_H #include "gd32e23x.h" #include "gd32e230c_eval.h" #include "systick.h" // 时基定时器 #define CFG_TIME_BASE_TIMER TIMER2 #define CFG_TIME_BASE_RCU_CLOCK RCU_TIMER2 #define CFG_TIME_BASE_IRQ_NUMBER TIMER2_IRQn #define CFG_TIME_BASE_IRQ_FUNCTION TIMER2_IRQHandler #endif
使用方法
/** ****************************************************************************** * @文件 main.c * @版本 V1.0.0 * @日期 * @概要 主程序文件 * @作者 lmx ****************************************************************************** * @注意 * * 版权归深圳市智汇创科技有限公司所有,未经允许不得使用或修改 * ****************************************************************************** */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "time_base.h" #include "xxx.h" #include "ccc.h" #include "aaa.h" int main(void) { time_base_init(); // 主循环 while(1) { time_base_update_flags(); // 更新时间标志 xxx_process(); ccc_process(); aaa_process(); } time_base_release(); return 0; } // xxx.c 里面的实现 void xxx_process() { if(time_base_is_flags(TIME_BASE_FLAGS_100MS) == 0){ return ; } // 100 ms 做的事情 } // ccc.c 里面的实现 void ccc_process() { if(time_base_is_flags(TIME_BASE_FLAGS_3000MS) == 0){ return ; } // 3000 ms 做的事情 } // aaa.c 里面的实现 void aaa_process() { if(time_base_is_flags(TIME_BASE_FLAGS_500MS) == 0){ return ; } // 500 ms 做的事情 }
-
用C51编写单片机延时函数
2007-03-12 23:18:00参考了51单片机 Keil C 延时程序...参考了51单片机 Keil C 延时程序的简单研究后,我们可知道, 在Keil C中获得最为准确的延时函数将是 voiddelay(unsignedchart){while(--t);} 反汇编代码如下:执行DJNZ指令需要...参考了51单片机 Keil C 延时程序的简单研究,自己也亲身测试和计算了一些已有的延时函数。
这里假定单片机是时钟频率为12MHz,则一个机器周期为:1us.
参考了51单片机 Keil C 延时程序的简单研究后,我们可知道, 在Keil C中获得最为准确的延时函数将是反汇编代码如下:void delay(unsigned char t)
{
while(--t);
}
执行DJNZ指令需要2个机器周期,RET指令同样需要2个机器周期,根据输入t,在不计算调用delay()所需时间的情况下,具体时间延时如下:t Delay Time (us) 1 2×1+2 =4 2 2×2+2=6 N 2×N+2=2(N+1)
当在main函数中调用delay(1)时, 进行反汇编如下:
调用delay()时,多执行了两条指令,其中MOV R, #data需要1个机器周期,LJMP需要2个机器周期,即调用delay()需要3us.
Keil C仿真截图与计算过程:
加上调用时间,准确的计算时间延时与Keil C仿真对比如下:(可见,仿真结果和计算结果是很接近的)t Delay Time (us) 仿真11.0592Mhz时钟(us) 1 3+2×1+2 =7 | 7.7(实际) 7.60 2 3+2×2+2=9 | 9.9 9.76 N 3+2×N+2=2N+5 | (2N+5)*1.1 / 3 11 | 12.1 11.94 15 35 | 38.5 37.98 100 205 | 225.5 222.44 255 515 | 566.5 558.81
也就是说,这个延时函数的精度为2us,最小的时间延时为7us,最大的时间延时为3+255×2+2=515us.
实际中使用11.0592MHz的时钟,这个延时函数的精度将为2.2us,最小时间延时为7.7us, 最大时间延时为566.5us.
这个时间延时函数,对于与DS18B20进行单总线通信,已经足够准确了。
现在,我们将时钟换成11.0592MHz这个实际用到的频率,每个机器周期约为1.1us.
现在让我们来分析一下这个之前用过的延时函数://延时函数, 对于11.0592MHz时钟, 例i=10,则大概延时10ms.
void delayMs(unsigned int i)
{
unsigned int j;
while(i--)
{
for(j = 0; j < 125; j++);
}
}
它的反汇编代码如下:
分析: T表示一个机器周期(调用时间相对于这个ms级的延时来说,可忽略不计)1 C:0000 MOV A, R7 ;1T
2 DEC R7 ;1T 低8位字节减1
3 MOV R2, 0x06 ;2T
4 JNZ C:0007 ;2T 若低8位字节不为0, 则跳到C:0007
5 DEC R6 ;1T 低8位字节为0, 则高8位字节减1
6 C:0007 ORL A, R2 ;1T
7 JZ C:001D ;2T 若高8位也减为0, 则RET
8 CLR A ;1T A清零
9 MOV R4, A ;1T R4放高位
10 MOV R5, A ;1T R5放低位
11 C:000D CLR C ;1T C清零
12 MOV A, R5 ;1T
13 SUBB A, #0x7d ;1T A = A-125
14 MOV A, R4 ;1T
15 SUBB A, #0x00 ;1T A
16 JNC C:0000 ;2T A为零则跳到C:0000
17 INC R5 ;1T R5增1
18 CJNE R5,#0x00, C:001B ;2T R5>0, 跳转到C:000D
19 INC R4 ;1T
20 C:001B SJMP C:000D ;2T
21 C:001D RET
对于delayMs(1), 执行到第7行就跳到21行, 共需时12T, 即13.2us
对于delayMs(2), 需时9T+13T+124×10T+7T+12T = 9T+13T+1240T+7T+12T =1281T =1409.1us.
对于delayMs(3), 需时9T×(3-1)+(13T+124×10T+7T)×(3-1)+12T
=1269T×(3-1)+12T=2550T=2805us.
对于delayMs(N),N>1, 需时1269T×(N-1)+12T = 1269NT-1257T=(1395.9N-1382.7)us.
利用Keil C仿真delayMs(1) = 0.00166558s = 1.67ms 截图如下:
由分析可知具体的计算延时时间与Keil C仿真延时对比如下:i Time Delay 仿真延时 1 13.2us 1.67ms 2 1409.1us 3.31ms 3 2805us 4.96ms N (1395.9N-1382.7)us 10 12.6ms 16.50ms 20 26.5ms 32.98ms 30 40.5ms 49.46ms 50 68.4ms 82.43ms 100 138.2ms 164.84ms 200 277.8ms 329.56ms 500 696.6ms 824.13ms 1000 1394.5ms 1648.54ms 1500 2092.5ms 2472.34ms 2000 2790.4ms 3296.47ms 5 5.6ms 8.26ms 73 100.5ms 120.34ms 720 1003.7ms = 1s 1186.74ms
计算delayMs(10)得到延时时间为:12576.3us约等于12.6ms,接近我们认为的10ms。计算结果和仿真结果只要delayMs(1)有很大出入, 其它都接近, 在接受范围内.
经过以上分析,可见用C语言来做延时并不是不太准确,只是不容易做到非常准确而已,若有一句语句变了,延时时间很可能会不同,因为编译程序生成的汇编指令很可能不同。
PS:
对于每条51单片机汇编指令的字长和所需机器周期汇总如下:转自:http://bbs.mcustudy.com/printpage.asp?BoardID=2&ID=1454
Appendix E - 8051 Instruction Set
Arithmetic Operations
Mnemonic Description Size Cycles
ADD A,Rn Add register to Accumulator (ACC). 1 1
ADD A,direct Add direct byte to ACC. 2 1
ADD A,@Ri Add indirect RAM to ACC. 1 1
ADD A,#data Add immediate data to ACC. 2 1
ADDC A,Rn Add register to ACC with carry. 1 1
ADDC A,direct Add direct byte to ACC with carry. 2 1
ADDC A,@Ri Add indirect RAM to ACC with carry. 1 1
ADDC A,#data Add immediate data to ACC with carry. 2 1
SUBB A,Rn Subtract register from ACC with borrow. 1 1
SUBB A,direct Subtract direct byte from ACC with borrow 2 1
SUBB A,@Ri Subtract indirect RAM from ACC with borrow. 1 1
SUBB A,#data Subtract immediate data from ACC with borrow. 2 1
INC A Increment ACC. 1 1
INC Rn Increment register. 1 1
INC direct Increment direct byte. 2 1
INC @Ri Increment indirect RAM. 1 1
DEC A Decrement ACC. 1 1
DEC Rn Decrement register. 1 1
DEC direct Decrement direct byte. 2 1
DEC @Ri Decrement indirect RAM. 1 1
INC DPTR Increment data pointer. 1 2
MUL AB Multiply A and B Result: A <- low byte, B <- high byte. 1 4
DIV AB Divide A by B Result: A <- whole part, B <- remainder. 1 4
DA A Decimal adjust ACC. 1 1
Logical Operations
Mnemonic Description Size Cycles
ANL A,Rn AND Register to ACC. 1 1
ANL A,direct AND direct byte to ACC. 2 1
ANL A,@Ri AND indirect RAM to ACC. 1 1
ANL A,#data AND immediate data to ACC. 2 1
ANL direct,A AND ACC to direct byte. 2 1
ANL direct,#data AND immediate data to direct byte. 3 2
ORL A,Rn OR Register to ACC. 1 1
ORL A,direct OR direct byte to ACC. 2 1
ORL A,@Ri OR indirect RAM to ACC. 1 1
ORL A,#data OR immediate data to ACC. 2 1
ORL direct,A OR ACC to direct byte. 2 1
ORL direct,#data OR immediate data to direct byte. 3 2
XRL A,Rn Exclusive OR Register to ACC. 1 1
XRL A,direct Exclusive OR direct byte to ACC. 2 1
XRL A,@Ri Exclusive OR indirect RAM to ACC. 1 1
XRL A,#data Exclusive OR immediate data to ACC. 2 1
XRL direct,A Exclusive OR ACC to direct byte. 2 1
XRL direct,#data XOR immediate data to direct byte. 3 2
CLR A Clear ACC (set all bits to zero). 1 1
CPL A Compliment ACC. 1 1
RL A Rotate ACC left. 1 1
RLC A Rotate ACC left through carry. 1 1
RR A Rotate ACC right. 1 1
RRC A Rotate ACC right through carry. 1 1
SWAP A Swap nibbles within ACC. 1 1
Data Transfer
Mnemonic Description Size Cycles
MOV A,Rn Move register to ACC. 1 1
MOV A,direct Move direct byte to ACC. 2 1
MOV A,@Ri Move indirect RAM to ACC. 1 1
MOV A,#data Move immediate data to ACC. 2 1
MOV Rn,A Move ACC to register. 1 1
MOV Rn,direct Move direct byte to register. 2 2
MOV Rn,#data Move immediate data to register. 2 1
MOV direct,A Move ACC to direct byte. 2 1
MOV direct,Rn Move register to direct byte. 2 2
MOV direct,direct Move direct byte to direct byte. 3 2
MOV direct,@Ri Move indirect RAM to direct byte. 2 2
MOV direct,#data Move immediate data to direct byte. 3 2
MOV @Ri,A Move ACC to indirect RAM. 1 1
MOV @Ri,direct Move direct byte to indirect RAM. 2 2
MOV @Ri,#data Move immediate data to indirect RAM. 2 1
MOV DPTR,#data16 Move immediate 16 bit data to data pointer register. 3 2
MOVC A,@A+DPTR Move code byte relative to DPTR to ACC (16 bit address). 1 2
MOVC A,@A+PC Move code byte relative to PC to ACC (16 bit address). 1 2
MOVX A,@Ri Move external RAM to ACC (8 bit address). 1 2
MOVX A,@DPTR Move external RAM to ACC (16 bit address). 1 2
MOVX @Ri,A Move ACC to external RAM (8 bit address). 1 2
MOVX @DPTR,A Move ACC to external RAM (16 bit address). 1 2
PUSH direct Push direct byte onto stack. 2 2
POP direct Pop direct byte from stack. 2 2
XCH A,Rn Exchange register with ACC. 1 1
XCH A,direct Exchange direct byte with ACC. 2 1
XCH A,@Ri Exchange indirect RAM with ACC. 1 1
XCHD A,@Ri Exchange low order nibble of indirect RAM with low order nibble of ACC. 1 1
Boolean Variable Manipulation
Mnemonic Description Size Cycles
CLR C Clear carry flag. 1 1
CLR bit Clear direct bit. 2 1
SETB C Set carry flag. 1 1
SETB bit Set direct bit. 2 1
CPL C Compliment carry flag. 1 1
CPL bit Compliment direct bit. 2 1
ANL C,bit AND direct bit to carry flag. 2 2
ANL C,/bit AND compliment of direct bit to carry. 2 2
ORL C,bit OR direct bit to carry flag. 2 2
ORL C,/bit OR compliment of direct bit to carry. 2 2
MOV C,bit Move direct bit to carry flag. 2 1
MOV bit,C Move carry to direct bit. 2 2
JC rel Jump if carry is set. 2 2
JNC rel Jump if carry is not set. 2 2
JB bit,rel Jump if direct bit is set. 3 2
JNB bit,rel Jump if direct bit is not set. 3 2
JBC bit,rel Jump if direct bit is set & clear bit. 3 2
Program Branching
Mnemonic Description Size Cycles
ACALL addr11 Absolute subroutine call. 2 2
LCALL addr16 Long subroutine call. 3 2
RET Return from subroutine. 1 2
RETI Return from interrupt. 1 2
AJMP addr11 Absolute jump. 2 2
LJMP addr16 Long jump. 3 2
SJMP rel Short jump (relative address). 2 2
JMP @A+DPTR Jump indirect relative to the DPTR. 1 2
JZ rel Jump relative if ACC is zero. 2 2
JNZ rel Jump relative if ACC is not zero. 2 2
CJNE A,direct,rel Compare direct byte to ACC and jump if not equal. 3 2
CJNE A,#data,rel Compare immediate byte to ACC and jump if not equal. 3 2
CJNE Rn,#data,rel Compare immediate byte to register and jump if not equal. 3 2
CJNE @Ri,#data,rel Compare immediate byte to indirect and jump if not equal. 3 2
DJNZ Rn,rel Decrement register and jump if not zero. 2 2
DJNZ direct,rel Decrement direct byte and jump if not zero. 3 2
Other Instructions
Mnemonic Description Size Cycles
NOP No operation. 1 1
其它可查看《单片机基础》-李广弟等编著,P70 “MCS-51单片机指令汇总”转载于:https://www.cnblogs.com/fengmk2/archive/2007/03/12/672477.html
-
STC单片机精确延时参数测定方法
2011-10-27 23:53:28在使用STC单片机的时候,大家是不是会遇见一个问题:延时往往很难把握。当然可以使用延时函数产生波形输出到示波器观察来修改延时参数,但是没有示波器时有没有方法来...具体代码如下://程序说明:测试stc单片机延时在使用STC单片机的时候,大家是不是会遇见一个问题:延时往往很难把握。当然可以使用延时函数产生波形输出到示波器观察来修改延时参数,但是没有示波器时有没有方法来确定延时参数呢。我这里自创了个办法,发到这与大家分享一下。
其方法是这样,首先设置好定时器的定时时间,在调用延时函数前打开定时器,定时器中断函数中读取出延时参数,然后通过串口将延时参数输出。具体代码如下:
//程序说明:测试stc单片机延时常数,串口输出 //作者:mjx //注:程序测量精度高,适用stc这种指令不固定的单片机 #include "STC12C5A60S2.h" #include <intrins.h> int i,j,ii,jj;//ii,jj作为定时器定时结束时暂存数,用于延时结束后串口输出 void Uart1_Send(unsigned char Data) //向控制器发送数据 { ES=0; TI=0; SBUF=Data; while(TI==0); TI=0; ES=1; } //延时函数 void delay(int k) { for(i = 0; i < k; i++) { for(j = 0; j < 30000; j++) { _nop_();_nop_();_nop_();_nop_();_nop_(); } } } void Uart1_init(void) // 使用定时器1作为波特率发生器 { PCON=0x00; //SMOD=0 SCON=0x50; //0101,0000 8位可变波特率,无奇偶校验位 TMOD|=0x20; //0011,0001 设置顶时器1为8位自动重装计数器 AUXR=0x00; //设置定时器1工作在1T模式下 TH1=0xfd; //设置定时器1自动重装数 TL1=0xfd; TR1=1; //开定时器1 // ES=1; //允许串口1中断 EA=1; //开总中断 } void main() { TMOD=0x01;//T0定时器 TH0 = 0xdC; //11.0592MHz--10ms 设置不同的时间,可以测试stc单片机内部延时参数 TL0 = 0x00; ET0 = 1; EA=1; Uart1_init();//初始化uart1,波特率9600,其他默认 TR0 = 1;//开启定时 delay(100);//延时 Uart1_Send(0x30+jj/10000); Uart1_Send(0x30+(jj%10000)/1000); Uart1_Send(0x30+(jj%1000)/100); Uart1_Send(0x30+(jj%100)/10); Uart1_Send(0x30+jj%10); Uart1_Send(0x2e); Uart1_Send(0x30+ii/10000); Uart1_Send(0x30+(ii%10000)/1000); Uart1_Send(0x30+(ii%1000)/100); Uart1_Send(0x30+(ii%100)/10); Uart1_Send(0x30+ii%10); while(1); } void Timer0(void) interrupt 1 using 3 { ii=i; // 暂存延时函数的i和j jj=j; // TR0=0; }
-
Python实现的简单的单片机串口助手程序
2019-09-03 21:46:41项目中遇到需要用电脑通过串口来控制单片机IO口,查询了一些资料,可以...将配合单片机程序对单片机进行控制。 python实现的串口助手代码如下: import time; #需要调用延时函数 import serial #需要调用串口库 ... -
Proteus仿真—40个单片机初学程序.
2009-04-13 13:00:56作为单片机的指令的执行的时间是很短,数量大微秒级,因此,我们要求的闪烁时间间隔为0.2秒,相对于微秒来说,相差太大,所以我们在执行某一指令时,插入延时程序,来达到我们的要求,但这样的延时程序是如何设计呢... -
换单片机时程序上也要注意
2009-11-20 12:06:00以前也有过用89c58换89c52,晶振也由12m改为24m时就出现同样问题,同样的程序下载进去运行出错,当时想到的就是24m比12m晶振高一倍,于是将程序中的需要延时的地方适当更改,延长点时间来解决问题。 由... -
汇编延时程序算法详解(范文).doc
2020-11-20 21:11:08汇编延时程序算法详解(范文) 第 PAGE \* Arabic 1 页第 PAGE \* Arabic 1 页 汇编延时程序算法详解 摘要 计算机反复执行一段程序以达到延时的目的称为软件延时单片机应用程序中经常需要短时间延时有时要求很高的精度... -
c51单片机led奇数偶数亮_单片机程序实际案例
2020-12-11 06:55:14实例21:用for语句控制蜂鸣器鸣笛次数#include //... //将sound位定义为P3.7/****************************************函数功能:延时形成1600Hz音频****************************************/void delay1600(voi... -
嵌入式系统/ARM技术中的汇编延时程序算法详解
2020-11-24 10:18:26相当一部分人对此仍很模糊,授人鱼,不如授之以渔,本文将以12MHZ晶振为例,详细讲解MCS-51单片机中汇编程序延时的精确算法。 关键词 51单片机 汇编 延时算法 指令周期、机器周期与时钟周期 指令周期:CPU... -
汇编延时程序算法详解
2011-03-18 10:01:00但在部分算法讲解中发现有错误之处,而且延时的具体算法讲得并不清楚,相当一部分人对此仍很模糊,授人鱼,不如授之以渔,本文将以12MHZ晶振为例,详细讲解MCS-51单片机中汇编程序延时的精确算法。 指令周期、... -
单片机汇编语言中能用MOV代替PUSH吗?中断控制中,设置SP初值有何意义?怎样避免中断程序不破坏延时参数?
2020-04-08 18:03:27你想知道的PC\SP在这里 ... 另外怎样避免中断程序不破坏延时参数? 可以在中断中启用不同的工作寄存器组;也可以将原工作器组的数据进行保护,中断服务完了再返回去。 ... -
《51单片机应用开发从入门到精通》——2.4 延时时间计算实例
2017-05-02 11:11:0051单片机应用开发从入门到精通在单片机的实时控制系统中,常常需要用到延时操作,所以,延时子程序往往是编写单片机程序中不可缺少的一部分。延时方法有硬件延时和软件延时,硬件延时将在后面有... -
单片机奇偶交替闪烁_来,跟我编一个最简单的单片机程序吧!
2020-12-24 13:41:40例:让该端口输出高电平的语句是:SETB P1.0让该端口输出低电平的语句是:CLR P1.0好了,现在我们将小灯接在单片机的P1.0端口上,如下图所示: 由上图可知,当端口P1.0输出高电平时,小灯D不亮,因为小灯中不会有... -
C语言实现单片机的键盘程序
2011-06-09 20:30:01c语言实现单片机的键盘程序 #include "SST89x5x4.H" #include #define uchar unsigned char #define uint unsigned int #define _Nop() _nop_() unsigned char code Key_Value_Table[16]={0xff,0x00,0x01,0xff,0x... -
51单片机数模转换程序
2012-10-19 13:25:49单片机数模转换程序 将da#include <reg52.h> //52系列单片机头文件 #include #define uchar unsigned char #define uint unsigned int sbit dula=P2^6; //申明U1锁存器的锁存端 sbit wela=P2^7; //申明U2锁存器的... -
这个单片机串口程序为何输入字符串而熟出的是ascll码?
2016-05-22 14:28:39//毫秒级延时函数 void delay(unsigned int x) { unsigned char i; while(x--) { for(i = 0;i ;i++); } } //字符发送函数 void putchar(unsigned char data1) { SBUF = data1; //将待发送的字符送入发送缓冲... -
汇编延时程序算法详解------转载
2010-01-04 09:44:00汇编延时程序算法详解2010-01-04 摘要 计算机反复执行...而且延时的具体算法讲得并不清楚,相当一部分人对此仍很模糊,授人鱼,不如授之以渔,本文将以12MHZ晶振为例,详细讲解MCS-51单片机中汇编程序延时的精确算法。 -
C51单片机程控滤波器的程序
2014-03-27 08:32:51功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对 此状态位进行操作.(不应答或非应答都使ack=0 假) 发送数据正常,ack=1; ack=0表示被控器无应答或损坏。 -------------------------------... -
基于msp430的单片机的DES加密程序
2016-07-31 10:36:54上课的时候做的一个课程设计,因为对单片机编程知识学习的比较少,所以,在自学了一些知识后,编写的程序, 其中,对于时钟也是根据for循环的延时来编写的,大家如果有更好的代码可以告诉我。 它的主要功能是,... -
基于51单片机的高精度舵机控制程序PWM 定时器
2018-09-12 00:57:13但是PWM控制舵机的程序实现方式多种多样,有的使用延时(delay(ms)),有的使用定时器(time),而网上搜到的大部分控制代码却质量一般,控制精度都需要提高,就要对单片机定时器有详细的了解,否则延时将出现偏差。... -
汇编 延时
2012-05-28 19:45:42摘要 计算机反复执行一段程序以达到延时的目的称为...相当一部分人对此仍很模糊,授人鱼,不如授之以渔,本文将以12MHZ晶振为例,详细讲解MCS-51单片机中汇编程序延时的精确算法。 关键词 51单片机 汇编 延时算法 -
在进行C51程序设计时如何精确延时的常见方法介绍
2013-10-15 23:32:54单片机因具有体积小、功能强、成本低以及便于实现分布式控制而有非常广泛的应用领域。单片机开发者在编制各种应用程序时经常会遇到实现精确延时的问题,比如按键去抖...为此我特意的将如何在C51程序中精确延时进行了... -
16路PWM舵机模块驱动程序51单片机
2018-07-10 11:33:28淘宝上卖的16路PWM舵机驱动模块的51单片机程序 部分程序如下 #include <reg52.h> #include <intrins.h> #include #include typedef unsigned char uchar; typedef unsigned int uint; sbit scl=P1^3; //时钟... -
闪烁LED程序——小白的单片机笔记
2017-05-05 10:30:00#include"reg52.h" ... //利用重定义将unsigned简化为u16 sbit led1=P2^0; void delay(u16 i )//延时函数,其实质是一个循环递减语句。 { while (i--); } void main() { while(1) { ... -
STC单片机 闪烁灯,LED流水灯 程序讲解
2020-12-02 22:40:10在循环中不断的进行开关,这就是逻辑其实挺简单的,但是中间需要有一个延时,如果不延时就不会看到效果。 在这里需要用到C语言里面的一个重定义关键字: unsigned andsigned int 分为无符号 unsigned 和有...
-
屏幕颜色拾取器.zip
-
python办公自动化技巧
-
Soul网关插件之Sofa
-
(新)备战2021软考网络工程师分类强化培训套餐
-
otp_win64_23.2.exe
-
国家注册信息安全工程师体系课程(CISP-PTE)
-
Java学习路线,好的学习路线和好的方法,能让我们少走些弯路
-
Go-sdk1.13.12-csdn高速下载
-
python基础
-
小学数学知识点大全 (几何的初步知识)<NLP 颜色标记>
-
FFmpeg4.3黄金系列课程:c++版
-
EPLAN 3D宏文件
-
2021年美容师(中级)多少分及格及美容师(中级)新版试题
-
visual studio professional 2017 2019
-
08 Python编程语言基础技术框架(4)之函数介绍.mp4
-
生信数据库标准规范.pdf
-
23种JAVA设计模式
-
一个人的行动力,取决于他的底层信念。
-
2021年起重机械指挥考试题库及起重机械指挥免费试题
-
(新)备战2021软考系统集成学习套餐