STC12系列单片机C语言的延时程序
STC12系列单片机C语言的延时程序

STC12系列单片机C语言的延时程序本举例所用CPU为STC12C5412系列12倍速的单片机,只要修改一下参数值其它系例单片机也通用,适用范围宽。
共有三条延时函数说明如下:函数调用分两级:一级是小于10US的延时,二级是大于10US的延时//====================小于10US的【用1US级延时】====================//----------微秒级延时---------for(i=X;i>;X;i--) 延时时间=(3+5*X)/12提示(单位us, X不能大于255)//================大于10US;0;Ms--)for(i=26;i>;0;i--);}i=[(延时值-1.75)*12/Ms-15]/4如想延时60US则i=[(60-1.75)*12/6-15]/4=25.375≈26; 修改i的值=26,再调用上面的【10US级延时函数】Delay10us(6); 则就精确延时60US;如果想延时64US可以用这二种函数组合来用:Delay10us(6); for(i=9;i>;X;i--) 共延时64US//==============对于大于20Ms的可用中断来实现程序运行比较好===============中断用定时器0, 1Ms中断:void timer0(void) interrupt 1{TL0=(0xffff-1000+2)%0x100;TH0=(0xffff-1000+2)/0x1 00; //每毫秒执行一次if(DelayMs_1>;0)DelayMs_1--;//大于20Ms延时程序}函数调用void DelayMs(uint a)//延时 a×1(ms)的时间。
{DelayMs_1=a;while(DelayMs_1);}如果延时50Ms则函数值为 DelayMs(50)。
单片机STC12C5A60S2控制AT24C04的程序(C语言)

void Delay5ms()
{
WORD n = 2500;
while(n--)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
}
/**************************************
起始信号
**************************************/
void AT24C04_Start()
{
SDA = 1; //拉高数据线
SCL = 1; //拉高时钟线
Delay5us(); //延时
SDA = 0; //产生下降沿
Delay5us(); //延时
SCL = 0; //拉低时钟线
SDA = 1; //产生上升沿
*******************************
发送应答信号
入口参数:ack(0:ACK 1:NAK)
**************************************/
void AT24C04_SendACK(bit ack)
{
SDA = ack; //写应答信号
SCL = 1; //拉高时钟线
Delay5us(); //延时
SCL = 0; //拉低时钟线
Delay5us(); //延时
}
/**************************************
接收应答信号
**************************************/
单片机·延时程序小结

单片机·延时程序小结
在单片机实验中,有一个很重要也是很基本的子程序必须要求我们掌握,
那就是延时程序。
下面我凭记忆来讲解延时程序。
课本上讲,1 个机器周期=6 个状态周期=12 个时钟周期,而这个时钟周期与
晶振频率有关。
我们接下来要上的实验基本都是以12MHz 的晶振。
12M 的频率,得其周期为1/12 乘10 的-6 方s,那么1 个机器周期就是它的12 倍,即1us, 而一般语句需要2 个机器周期,例如
MOV R6,#20
DNJZ R6,$
每一次执行时,每一个过程就需要2 个机器周期,为1us 乘2。
.同样C 语言中for 循环语句没执行一次也是2 个机器周期,即2us。
下面我会以每个语句执
行一次用时的2us 为基本单位,不会再细化了。
汇编语言最基本延时:
MOV R6,#20
D1:MOV R7,#248
DNJZ R7,$//循环248 次,共用248X2us,
DNJZ R6,D1
我开始也是搞不懂怎么算它到底延时多少,现在给大家写它表达式:
我觉得应该从最后往前算,在MOR R7,#248 执行一次前提下,用时1X2us, 然后循环减248,用时248X2us,故共用时[2+2X248]us。
然而又由于DNJZ R6,D1,上面的过程又循环20 次,故上面的循环最终用时20X[2+2X248]us。
接着注意到单纯DNJZ R6,D1 会用时20X2=40us。
STC12延时函数的探究

STC12延时函数的探究
这种写法是C中嵌套了汇编。
精确延时时间
=2*t*T+5*T,T为一个机器周期。
对于8051,
如果t=1,那么这个函数执行应该是7us。
如果是STC12,那么这个延时函数的延时应该是:若t=1,精确延时
=2*1*1/12+5*1/12=(7/12)us啊。
昨天也查了STC12手册手册上对时钟写的很笼统,其中一句话是:与8051指令执行时间对比,一共有12个指令,一个时钟就可以执行完成,工作在相同频率下运行速度
提高8~12倍
难道这里应该是(7/8)us?而不是(7/12)us?
这个是uint型函数时间是近似的
那么可以用延时时间=8*t*T
应该是8*1*(1/12)=8/12
根据程序分析猜想t=1时这个延时函数应该为1us最为合理。
用示波器测试过执行一个delay(5000)大约5.8ms。
51执行一个delay(5000)大约40064us
嗯,用示波器测得那个IO口的频率变化为85.47HZ,那
么一个delay(5000)就是(1/85.47)/2*1000=5850us
这里的t设的uint型,有误差,加上 LED=1;LED=0;执行也会消耗时间结果存在误差。
最后总结得出这条延时语句在51上执行一次大约花7us,在12上花1us。
示波器测试通过!和我计算符合。
STC12C5A60S2单片机c语言程序代码调试例程

//12T指的是每12个时钟加1与普通C51一样
//允许将P3.5/T1脚配置为定时器1的时钟输出CLKOUT1,只
能工作在定时器模式2下
//T1工作在1T模式时的输出频率 = SYSclk/(256-TH0)/2
//T1工作在12T模式时的输出频率 = SYSclk/12/(256-TH0)/2
//工作模式为1T
BRT = 0xff;
#if( Bus_clk == 12 )
CLK_DIV = 0x00;
#elif( Bus_clk == 6 )
CLK_DIV = 0x01;
#elif( Bus_clk == 3 )
CLK_DIV = 0x02;
#elif( Bus_clk == 1500 )
void Delay_ms( uint time )
{
uint t; //延时时间 = (time*1003+16)us while(time--)
{
for( t = 0; t < 82; t++ );
}
}
//***********************************//
//1T指的是每1个时钟加1,是普通C51的12倍
//12T指的是每12个时钟加1与普通C51一样
AUXR = 0xc0; //T0定时器速度是普通8051的12倍,即工作在1T模式下
//T1定时器速度是普通8051的12倍,即工作在1T模式下
TMOD = 0x22; //定时器0工作模式为方式2,自动装载时间常数
#define uchar unsigned char
单片机的延时与中断问题及解决方法

单片机的延时与中断问题及解决方法概述在单片机的应用开发中,延时和中断是两个非常重要的概念。
延时是指在程序中暂停一段时间,而中断是指在程序执行过程中突然打断当前的执行流程去处理其他事务。
延时和中断的使用对于单片机的应用开发非常重要,合理的使用可以提高程序的效率和可靠性。
在实际开发中,延时和中断也经常会遇到一些问题。
本文将针对单片机的延时和中断问题进行分析,并提出相应的解决方法。
延时问题及解决方法延时是指在程序执行过程中暂停一段时间。
单片机中常用的延时方法有软件延时和硬件延时两种。
软件延时是通过在程序中执行循环来实现延时的。
例如:void delay(unsigned int time){while(time--);}硬件延时是通过单片机内部的定时器来实现延时的。
在51单片机中可以通过配置定时器的初值和工作模式来实现延时。
在实际开发中,延时经常会遇到一些问题。
延时时间不准确,延时过长或过短等。
造成这些问题的原因有很多,常见的原因包括系统时钟频率不准确、程序执行过程中被中断打断、延时中使用了未初始化的变量等。
为了解决这些问题,可以采取一些措施。
要确保系统时钟频率的准确性。
一般来说,单片机的延时是通过系统时钟来实现的,如果系统时钟频率不准确,那么延时时间也会不准确。
要确保系统时钟频率的准确性。
一种简单的方法是通过外部晶振来提供时钟信号,另一种方法是通过软件校准系统时钟频率。
要避免在延时中使用未初始化的变量。
在C语言中,未初始化的变量的值是不确定的,因此在延时中使用未初始化的变量可能会导致延时时间不准确。
在延时前要确保所使用的变量已经正确初始化。
要避免在延时中被中断打断。
在单片机的程序执行过程中,可能会发生各种中断事件,如果在延时中被中断打断,那么延时时间也会不准确。
为了避免这种情况,可以在延时前禁止所有中断,延时结束后再使能中断。
中断问题的解决方法主要包括中断优先级的设置、中断屏蔽和中断标志的清除。
中断优先级的设置是非常重要的。
单片机软件延时程序的设计

单片机软件延时程序的设计一、单片机软件延时的基本原理单片机执行指令需要一定的时间,通过编写一系列无实际功能的指令循环,让单片机在这段时间内持续执行这些指令,从而实现延时的效果。
延时的时间长度取决于所使用的单片机型号、晶振频率以及所编写的指令数量和类型。
以常见的 51 单片机为例,假设其晶振频率为 12MHz,一个机器周期等于 12 个时钟周期,那么执行一条单周期指令的时间约为1μs。
通过编写一定数量的这种单周期指令的循环,就可以实现不同时长的延时。
二、软件延时程序的设计方法1、简单的空操作延时这是最基本的延时方法,通过使用空操作指令“NOP”来实现。
以下是一个简单的示例:```cvoid delay_nop(unsigned int n){unsigned int i;for (i = 0; i < n; i++){_nop_();}}```这种方法的延时时间较短,而且不太精确,因为实际的延时时间还会受到编译器优化等因素的影响。
2、基于循环的延时通过使用循环来执行一定数量的指令,从而实现较长时间的延时。
以下是一个基于循环的延时函数示例:```cvoid delay_ms(unsigned int ms){unsigned int i, j;for (i = 0; i < ms; i++){for (j = 0; j < 120; j++)_nop_();}}}```在这个示例中,通过内外两层循环来增加延时的时间。
需要注意的是,这里的循环次数是根据实验和估算得出的,实际的延时时间可能会有一定的偏差。
3、更精确的延时为了实现更精确的延时,可以根据单片机的机器周期和指令执行时间来精确计算延时的循环次数。
例如,对于12MHz 晶振的51 单片机,要实现 1ms 的延时,可以这样计算:1ms =1000μs,一个机器周期为1μs,执行一条指令需要 1 到 4 个机器周期。
假设平均每条指令需要 2 个机器周期,那么要实现1000μs的延时,大约需要执行 2000 条指令。
单片机C语言延时程序计算

2 软件延时与时间计算
在很多情况下,定时器/计数器经常被用作其他用途,这时候就只能用软件方法延时。下面介绍几种软件延时的方法。
2.1 短暂延时
可以在C文件中通过使用带_NOP_( )语句的函数实现,定义一系列不同的延
单片机系统一般常选用11.059 2 MHz、12 MHz或6 MHz晶振。第一种更容易产生各种标准的波特率,后两种的一个机器周期分别为1 μs和2 μs,便于精确延时。本程序中假设使用频率为12 MHz的晶振。最长的延时时间可达216=65 536 μs。若定时器工作在方式2,则可实现极短时间的精确延时;如使用其他定时方式,则要考虑重装定时初值的时间(重装定时器初值占用2个机器周期)。
80us 1 1 48 0
90us 1 1 55 +0.5
}
延时时间 a的值 b的值 c的值 延时误差(us)
10us 1 1 1 -0.5
1ms 1 3 219 -1.5
2ms 2 3 220 +3
900us
9 1 63 -1.5
60us 1 1 35 +0.5
70us 1 1 42 +1
在实际应用中,定时常采用中断方式,如进行适当的循环可实现几秒甚至更长时间的延时。使用定时器/计数器延时从程序的执行效率和稳定性两方面考虑都是最佳的方案。但应该注意,C51编写的中断服务程序编译后会自动加上PUSH ACC、PUSH PSW、POP PSW和POP ACC语句,执行时占用了4个机器周期;如程序中还有计数值加1语句,则又会占用1个机器周期。这些语句所消耗的时间在计算定时初值时要考虑进去,从初值中减去以达到最小误差的目的。
300us 3 1 63 +1.5
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
STC12系列单片机C语言的延时程序
本举例所用CPU 为STC12C5412 系列12 倍速的单片机,只要修改一下参数值其它系例单片机也通用,适用范围宽。
共有三条延时函数说明如下:函数调用
分两级:一级是小于10US 的延时,二级是大于10US 的延时
//====================小于10US 的【用1US 级延时】
====================//----------微秒级延时---------for(i=X;i>X;i--) 延时时间
=(3+5*X)/12 提示(单位us, X 不能大于255)//================大于10US0;Ms--)for(i=26;i>0;i--);}i=[(延时值-1.75)*12/Ms-15]/4 如想延时60US 则
i=[(60-1.75)*12/6-15]/4=25.375≈26; 修改i 的值=26,再调用上面的【10US 级延时函数】Delay10us(6); 则就精确延时60US;如果想延时64US 可以用这二种函数组合来用: Delay10us(6); for(i=9;i>X;i--) 共延时64US//============== 对于大于20Ms 的可用中断来实现程序运行比较好===============中断用定
时器0, 1Ms 中断:void timer0(void) interrupt 1{ TL0=(0xffff-1000+2)% 0x100;TH0=(0xffff-1000+2)/0x100; //每毫秒执行一次if(DelayMs_1>0) DelayMs_1--;//大于20Ms 延时程序}函数调用void DelayMs(uint a)//延时 a 乘以1(ms)的时间。
{ DelayMs_1=a; while(DelayMs_1);}如果延时50Ms 则函数值为DelayMs(50)tips:感谢大家的阅读,本文由我司收集整编。
仅供参阅!。