单片机的几种延时函数

合集下载

1T单片机和12T单片机延时函数

1T单片机和12T单片机延时函数

12T和1T单片机us和ms级延时模块Delay.c* 文件名:Delay.c* 芯片:STC12C5A60S2* 晶振:12MHz* 创建者:李泉华* 创建日期:2014.7.10* 功能描述:单片机us和ms级延时,适用于12MHz的12T和1T单片机#include "Delay.h"#define uchar unsigned char#define uint unsigned int/** 函数名:DelayUs12T* 功能描述:12T单片机us级延时,7us~515us,精度2us* 输入参数:delayUsVal = (t-5)/2* 返回值:无*/void DelayUs12T(uchar delayUsVal){while (--delayUsVal);}/** 函数名:DelayUs1T* 功能描述:1T单片机us级延时,2us~85us,精度1us * 输入参数:delayUsVal = 3t - 3* 返回值:无*/void DelayUs1T(uchar delayUsVal){while (--delayUsVal);}/** 函数名:DelayMs12T* 功能描述:12T单片机ms级延时* 输入参数:delayMsVal:延时多少ms,1ms~65535ms * 返回值:无*/void DelayMs12T(uint delayMsVal){uchar i, j;while (delayMsVal--)for (i = 0; i<3; i++)for (j = 0; j<106; j++); }/** 函数名:DelayMs1T* 功能描述:1T单片机ms级延时* 输入参数:delayMsVal:延时多少ms,1ms~65535ms * 返回值:无*/void DelayMs1T(uint delayMsVal){uchar i, j;while (delayMsVal--)for (i = 0; i<10; i++)for (j = 0; j<169; j++); }。

基于51单片机的精确延时(微秒级)

基于51单片机的精确延时(微秒级)

声明:*此文章是基于51单片机的微秒级延时函数,采用12MHz晶振。

*此文章共包含4个方面,分别是延时1us,5us,10us和任意微秒。

前三个方面是作者学习过程中从书本或网络上面总结的,并非本人所作。

但是延时任意微秒函数乃作者原创且亲测无误。

欢迎转载。

*此篇文章是作者为方便初学者使用而写的,水平有限,有误之处还望大家多多指正。

*作者:Qtel*2012.4.14*QQ:97642651----------------------------------------------------------------------------------------------------------------------序:对于某些对时间精度要求较高的程序,用c写延时显得有些力不从心,故需用到汇编程序。

本人通过测试,总结了51的精确延时函数(在c语言中嵌入汇编)分享给大家。

至于如何在c 中嵌入汇编大家可以去网上查查,这方面的资料很多,且很简单。

以12MHz晶振为例,12MHz 晶振的机器周期为1us,所以,执行一条单周期指令所用时间就是1us,如NOP指令。

下面具体阐述一下。

----------------------------------------------------------------------------------------------------------------------1.若要延时1us,则可以调用_nop_();函数,此函数是一个c函数,其相当于一个NOP指令,使用时必须包含头文件“intrins.h”。

例如:#include<intrins.h>#include<reg52.h>void main(void){P1=0x0;_nop_();//延时1usP1=0xff;}----------------------------------------------------------------------------------------------------------------------2.延时5us,则可以写一个delay_5us()函数:delay_5us(){#pragma asmnop#pragma endasm}这就是一个延时5us的函数,只需要在需要延时5us时调用此函数即可。

单片机常用延时函数

单片机常用延时函数
精确的单片机常用延时函数:(c代码 误差0us 12M){即是延时函数的位置}
1、延时0.5ms
void delay0.5ms(void) //误差 0us
{
unsigned char a,b;
for(b=71;b>0;b--)
for(a=2;a>0;a--);
for(b=19;b>0;b--)
for(a=130;a>0;a--);
}
7、延时10ms
void delay10ms(void) //误差 0us
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=38;b>0;b--)
for(a=214;a>0;a--);
_nop_; //if Keil,require use intrins.h
}
13、延时500ms
1·void delay500ms(void) //误差 0us
{
unsigned char a,b,c;
for(a=130;a>0;a--);
}
12、延时200ms
void delay200ms(void) //误差 0us
{
unsigned char a,b,c;
for(c=4;c>0;c--)
for(b=116;b>0;b--)
for(c=23;c>0;c--)
for(b=152;b>0;b--)
for(a=70;a>0;a--);
}
2·void Delay500ms()

51单片机delay()延时的用途和用法讲解

51单片机delay()延时的用途和用法讲解

{ unsigned int i; for(i=0;i<uiDelayShort;i++) { ; //一个分号相当于执行一条空语句 }
}
/* 注释八: * delay_long(unsigned int uiDelayLong)是大延时函数, * 专门用在上电初始化的大延时, * 此函数的特点是能实现比较长时间的延时,细分度取决于内嵌 for 循环的次数, * uiDelayLong 的数值的大小就代表里面执行了多少次 500 条空指令的时间。 * 数值越大,延时越长。时间精度不要刻意去计算,感觉差不多就行。 */ void delay_long(unsigned int uiDelayLong) {
unsigned int i; unsigned int j; for(i=0;i<uiDelayLong;i++) {
for(j=0;j<500;j++) //内嵌循环的空指令数量 { ; //一个分号相当于执行一条空语句 }
}பைடு நூலகம்}
void initial_myself() //初始化单片机 {
led_dr=0; //LED 灭 } void initial_peripheral() //初始化外围 {
delay()延时的用途讲解
(1)硬件平台:基于朱兆祺 51 单片机学习板。
(2)实现功能:让一个 LED 闪烁。
(3)源代码讲解如下:
#include "REG52.H"
void initial_myself(); void initial_peripheral();
void delay_short(unsigned int uiDelayshort); void delay_long(unsigned int uiDelaylong); void led_flicker();

单片机中延时算法和nop函数的使用

单片机中延时算法和nop函数的使用
对于循环语句同样可以采用for,do…while,while结构来完
成,每个循环体内的变量仍然采用无符号字符变量。
unsigned char i,j
for(i=255;i&gt;0;i--)
for(j=255;j&gt;0;j--);

unsigned char i,j
i=255;
采用软件定时的计算方法
利用指令执行周期设定,以下为一段延时程序:
指令 周期
MOV 1
DJNZ 2
NOP 1
采用循环方式定时,有程序:
MOV R5,#TIME2 ;周期1
......
......
//============
......
......
_nop_(); //引用库函数
敬礼。
我一直都是借助仿真软件编。一点一点试时间。
C语言最大的缺点就是实时性差,我在网上到看了一些关于延时的讨论,其中有篇文章
51单片机 Keil C 延时程序的简单研究,作者:InfiniteSpace Studio/isjfk
}
产生的汇编
C:0x0800 7F05 MOV R7,#0x05
C:0x0802 7E84 MOV R6,#0x84
C:0x0804 7D96 MOV R5,#0x96
C:0x0806 DDFE DJNZ R5,C:0806
NOP指令为单周期指令,可由晶振频率算出延时时间,对于12M晶振,延时1uS。
对于延时比较长的,要求在大于10us,采用C51中的循环语句来实现。
在选择C51中循环语句时,要注意以下几个问题
第一、定义的C51中循环变量,尽量采用无符号字符型变量。

单片机延时函数

单片机延时函数

单⽚机延时函数1.51单⽚机延时,晶振为11.0592MHz(1)粗略延时void delay_ms(uint x){uint i,j;for(i=x;i>0:i--)for(j=110;j>0;j--);}(2)定时器延时void delay_ms(uint i){TMOD=0x01; //设置定时器⼯作模式while(i != 0){TR0=1; //开启定时器TH0=(65535-1000)/256; //赋初值TL0=(65535-1000)%256;while(TF0 != 1); //溢出标志TF0=0;i--;}TR0=0; //关闭定时器}2.stm32l151C8T6延时,外部晶振8MHz(1)粗略延时void delay_us(uint32_t time) //us延时{uint32_t i=4\*time;while(i--);}void delay_us(uint32_t time) //ms延时{uint32_t i=4000\*time;while(i--);}(2)使⽤nop延时通过使⽤__NOP()函数进⾏延时,因为使⽤了8M晶振4倍频,所以是32MHz,所以⼀个nop约等于1/32us,所以使⽤32个nop函数为⼀个us,然后根据需要的定时时间进⾏计算。

void delay_us(uint32_t time) //us延时{uint32_t i=0;for(i=0;i(3)利⽤SysTick延时void delay_init() //初始化{SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟fac_us=SystemCoreClock/8000000; //为系统时钟的1/8 4fac_ms=1000\*fac_us;}void delay_us(uint16_t nus) //延时us{uint32_t ui_tmp=0x00;SysTick->LOAD=nus\*fac_us;SysTick->VAL=0x00;SysTick->CTRL=0x01;do{ui_tmp=SysTick->CTRL;}while((ui_tmp&0x01) && (!(ui_tmp & (1<<16))));SysTick->CTRL=0x00;SysTick->VAL=0x00;}void delay_ms(uint16_t nms) //延时ms{uint32_t ui_tmp=0x00;SysTick->LOAD=nms\*fac_ms;SysTick->VAL=0x00;SysTick->CTRL=0x01;do{ui_tmp=SysTick->CTRL;}while((ui_tmp&0x01) && (!(ui_tmp&(1<<16))));SysTick->VAL=0x00;SysTick->CTRL=0x00;}void SysTick_Handler(void){flag=~flag;}(4)定时器延时void TIM3_Int_Init(uint16_t arr,uint16_t psc){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//设置在下⼀个更新事件装⼊活动的⾃动重装载寄存器周期的值,计数10000为1s;TIM_TimeBaseStructure.TIM_Period = arr;//设置⽤来作为TIMx时钟频率除数的预分频值,10kHz的计数频率TIM_TimeBaseStructure.TIM_Prescaler = psc;//设置时钟分割:TDIS = Tck_timTIM_TimeBaseStructure.TIM_ClockDivision = 0;//设置TIM向上计数模式TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//初始化TIMx的时间基数单位TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);//使能指定的TIM3中断,允许更新中断TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//TIM3中断NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;//抢占优先级 0 级NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//从优先级 3 级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//IRQ通道被使能NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//初始化外设NVIC寄存器NVIC_Init(&NVIC_InitStructure);//使能TIMx外设TIM_Cmd(TIM3,ENABLE);}void TIM3_IRQHandler(void){if(TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET) //检查指定的TIM中断发⽣与否 {TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除TIMx的中断待处理位if(flag==0){flag=1;GPIO_ResetBits(GPIOB,GPIO_Pin_0) ;}else{flag=0;GPIO_SetBits(GPIOB,GPIO_Pin_0);}}}注意:定时时间的计算定时器时钟为:CK_CLK预分频数值:PSC⾃动装载寄存器数值:ARR进⼊中断的次数:timet=time\*(ARR+1)\*(PSC+1)/(CK_CLK)。

51单片机的几种精确延时

51单片机的几种精确延时
的方法来实现,因此,循环嵌套的方法常用于达到ms级的延时。
对于循环语句同样可以采用for,do…while,while结构来完
成,每个循环体内的变量仍然采用无符号字符变量。
unsigned char i,j
for(i=255;i>0;i--)
for(j=255;j>0;j--);

unsigned char i,j
{unsigned char b,c;
b="j";
c="k";
do{
do{
do{k--};
while(k);
k="c";
j--;};
while(j);
j=b;
i--;};
while(i);
在实际应用中,定时常采用中断方式,如进行适当的循环可实现几秒甚至更长时间的延时。使用定时器/计数器延时从程序的执行效率和稳定性两方面考虑都是最佳的方案。但应该注意,C51编写的中断服务程序编译后会自动加上PUSH ACC、PUSH PSW、POP PSW和POP ACC语句,执行时占用了4个机器周期;如程序中还有计数值加1语句,则又会占用1个机器周期。这些语句所消耗的时间在计算定时初值时要考虑进去,从初值中减去以达到最小误差的目的。
51单片机的几种精确延时实现延时
51单片机的几种精确延时实现延时通常有两种方法:一种是硬件延时,要用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时;另一种是软件延时,这种方法主要采用循环体进行。
1使用定时器/计数器实现精确延时
单片机系统一般常选用11.059 2 MHz、12 MHz或6 MHz晶振。第一种更容易产生各种标准的波特率,后两种的一个机器周期分别为1μs和2μs,便于精确延时。本程序中假设使用频率为12 MHz的晶振。最长的延时时间可达216=65 536μs。若定时器工作在方式2,则可实现极短时间的精确延时;如使用其他定时方式,则要考虑重装定时初值的时间(重装定时器初值占用2个机器周期)。

51单片机延时函数

51单片机延时函数

51单片机延时函数在嵌入式系统开发中,51单片机因其易于学习和使用、成本低廉等优点被广泛使用。

在51单片机的程序设计中,延时函数是一个常见的需求。

通过延时函数,我们可以控制程序的执行速度,实现定时器功能,或者在需要的时候进行延时操作。

本文将介绍51单片机中常见的延时函数及其实现方法。

一、使用for循环延时这种方法不精确,但是对于要求不高的场合,可以用来估算延时。

cvoid delay(unsigned int time){unsigned int i,j;for(i=0;i<time;i++)for(j=0;j<1275;j++);}这个延时函数的原理是:在第一个for循环中,我们循环了指定的时间次数(time次),然后在每一次循环中,我们又循环了1275次。

这样,整个函数的执行时间就是time乘以1275,大致上形成了一个延时效果。

但是需要注意的是,这种方法因为硬件和编译器的不同,延时时间会有很大差异,所以只适用于对延时时间要求不精确的场合。

二、使用while循环延时这种方法比使用for循环延时更精确一些,但是同样因为硬件和编译器的不同,延时时间会有差异。

cvoid delay(unsigned int time){unsigned int i;while(time--)for(i=0;i<1275;i++);}这个延时函数的原理是:我们先进入一个while循环,在这个循环中,我们循环指定的时间次数(time次)。

然后在每一次循环中,我们又循环了1275次。

这样,整个函数的执行时间就是time乘以1275,大致上形成了一个延时效果。

但是需要注意的是,这种方法因为硬件和编译器的不同,延时时间会有差异,所以只适用于对延时时间要求不精确的场合。

三、使用定时器0实现精确延时这种方法需要在单片机中开启定时器0,并设置定时器中断。

在中断服务程序中,我们进行相应的操作来实现精确的延时。

这种方法需要使用到单片机的定时器中断功能,相对复杂一些,但是可以实现精确的延时。

单片机的几种延时函数

单片机的几种延时函数

摘要实际‎的单片机应‎用系统开发‎过程中,由‎于程序功能‎的需要,经‎常编写各种‎延时程序,‎延时时间从‎数微秒到数‎秒不等,对‎于许多C5‎1开发者特‎别是初学者‎编制非常精‎确的延时程‎序有一定难‎度。

本文从‎实际应用出‎发,讨论几‎种实用的编‎制精确延时‎程序和计算‎程序执行时‎间的方法,‎并给出各种‎方法使用的‎详细步骤,‎以便读者能‎够很好地掌‎握理解。

关‎键词 K‎e il C‎51 精‎确延时‎程序执行时‎间引言‎单片机因具‎有体积小、‎功能强、成‎本低以及便‎于实现分布‎式控制而有‎非常广泛的‎应用领域[‎1]。

单片‎机开发者在‎编制各种应‎用程序时经‎常会遇到实‎现精确延时‎的问题,比‎如按键去抖‎、数据传输‎等操作都要‎在程序中插‎入一段或几‎段延时,时‎间从几十微‎秒到几秒。

‎有时还要求‎有很高的精‎度,如使用‎单总线芯片‎D S18B‎20时,允‎许误差范围‎在十几微秒‎以内[2]‎,否则,芯‎片无法工作‎。

用51汇‎编语言写程‎序时,这种‎问题很容易‎得到解决,‎而目前开发‎嵌入式系统‎软件的主流‎工具为C语‎言,用C5‎1写延时程‎序时需要一‎些技巧[3‎]。

因此,‎在多年单片‎机开发经验‎的基础上,‎介绍几种实‎用的编制精‎确延时程序‎和计算程序‎执行时间的‎方法。

‎实现延时通‎常有两种方‎法:一种是‎硬件延时,‎要用到定时‎器/计数器‎,这种方法‎可以提高C‎P U的工作‎效率,也能‎做到精确延‎时;另一种‎是软件延时‎,这种方法‎主要采用循‎环体进行。

‎1使用‎定时器/计‎数器实现精‎确延时‎单片机系统‎一般常选用‎11.05‎9 2 M‎H z、12‎MHz或‎6 MHz‎晶振。

第一‎种更容易产‎生各种标准‎的波特率,‎后两种的一‎个机器周期‎分别为1 ‎μs和2 ‎μs,便于‎精确延时。

‎本程序中假‎设使用频率‎为12 M‎H z的晶振‎。

最长的延‎时时间可达‎216=6‎5 536‎μs。

单片机的延时与中断问题及解决方法

单片机的延时与中断问题及解决方法

单片机的延时与中断问题及解决方法单片机作为嵌入式系统中非常重要的组成部分,在许多应用中都需要进行延时和中断处理。

延时和中断是单片机中常见的问题,它们直接关系到系统的稳定性和性能。

本文将重点介绍单片机中延时和中断的问题,并提出解决方法。

一、延时问题延时是指在程序执行过程中需要暂停一段时间,以便等待某些条件满足或者执行某些特定的操作。

在单片机中,延时通常需要通过软件实现,也就是在程序中加入延时函数。

常见的延时函数包括循环延时和定时器延时。

1. 循环延时循环延时是指通过循环来实现延时的方式。

具体做法是在程序中使用一个循环来反复执行空操作,从而消耗一定的时间。

下面是一个简单的循环延时函数:```cvoid delay(unsigned int ms){unsigned int i, j;for(i = 0; i < ms; i++)for(j = 0; j < 1000; j++);}```这个函数中,外层循环控制延时的毫秒数,内层循环则是用来消耗时间的。

通过这样的方式可以实现一定量级的延时。

循环延时的精度和稳定性都不够理想,特别是在频繁调用的情况下,容易导致系统性能下降。

2. 定时器延时定时器是单片机中常见的外设之一,它可以生成精确的时间延时。

通过设置定时器的时钟源和计数值,可以实现微秒级甚至更小单位的延时。

在单片机中,通常会使用定时器来实现较为精确的延时操作。

下面是一个使用定时器来实现延时的示例:```cvoid delay_us(unsigned int us){TMOD = 0x01; // 设置定时器为工作方式1TH0 = 0xFF - us / 256; // 设置定时器初值TL0 = 0xFF - us % 256; // 设置定时器初值TR0 = 1; // 启动定时器while(!TF0); // 等待定时器溢出TR0 = 0; // 停止定时器TF0 = 0; // 清除溢出标志}```这段代码中,我们使用定时器0来实现微秒级的延时操作。

51单片机延时函数

51单片机延时函数

C程序中可使用不同类型的变量来进行延时设计。

经实验测试,使用unsigned char类型具有比unsigned int更优化的代码,在使用时应该使用unsigned char作为延时变量。

以某晶振为12MHz 的单片机为例,晶振为12MHz即一个机器周期为1us。

一. 500ms延时子程序程序: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--);}计算分析:程序共有三层循环一层循环n:R5*2 = 81*2 = 162us DJNZ 2us二层循环m:R6*(n+3) = 202*165 = 33330us DJNZ2us + R5赋值 1us = 3us三层循环: R7*(m+3) = 15*33333 = 499995us DJNZ 2us + R6赋值1us = 3us循环外: 5us子程序调用2us + 子程序返回 2us + R7赋值 1us = 5us延时总时间= 三层循环+ 循环外= 499995+5 = 500000us =500ms计算公式:延时时间=[(2*R5+3)*R6+3]*R7+5二. 200ms延时子程序程序:{unsigned char i,j,k;for(i=5;i>0;i--)for(j=132;j>0;j --)for(k=150;k>0;k --);}三. 10ms延时子程序程序:{unsigned char i,j,k;for(i=5;i>0;i--)for(j=4;j>0;j--)for(k=248;k>0;k --);}四. 1s延时子程序程序: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 --);}关于单片机C语言的精确延时,网上很多都是大约给出延时值没有准确那值是多少,也就没有达到精确高的要求,而本函数克服了以上缺点,能够精确计数出要延时值且精确达到1us,本举例所用CPU为STC12C5412系列12倍速的单片机,只要修改一下参数值其它系例单片机也通用,适用范围宽。

单片机的延时计算

单片机的延时计算
译器用下面的指令组合来完成的
MOVR7,#0FFH
LOOP2:MOVR6,#0FFH
LOOP1:DJNZR6,LOOP1
DJNZR7,LOOP2
这些指令的组合在汇编语言中采用DJNZ指令来做延时用,
因此它的时间精确计算也是很简单,假上面变量i的初
值为m,变量j的初值为n,则总延时时间为:m×(n×T+T),
{unsigned char b,c;
b="j";
c="k";
do{
do{
do{k--};
while(k);
k="c";
j--;};
while(j);
j=b;
i--;};
while(i);
}
这精确延时子程序就被C51编译为有下面的指令组合完成
delay延时子程序如下:
MOV R6,05H
MOV R4,03H
一. 500ms延时子程序
程序:
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--);
}
产生的汇编:
C:0x0800 7F0F MOV R7,#0x0F
C:0x0802 7ECA MOV R6,#0xCA
刚刚又学了一条,用_nop_();时记得加上#include <intrins.h>头文件
如:
//==================
#include <intrins.h> //包含库函数

stm32 cubemx 延时函数

stm32 cubemx 延时函数

stm32 cubemx 延时函数
在STM32单片机的开发中,经常需要使用延时函数来实现一些功能,比如LED闪烁、按键消抖等等。

在STM32 CubeMX中,也可以很方便地使用延时函数来实现这些功能。

首先,我们需要在工程中添加头文件“stm32f4xx_hal.h”。

这个头文件中包含了HAL库的函数声明和一些宏定义。

接下来,在main函数中添加以下代码:
```
HAL_Init();
```
这行代码用来初始化HAL库。

接着,在while循环中添加以下代码:
```
HAL_Delay(1000);
```
这行代码用来实现延时,单位为毫秒。

上面的代码表示延时1秒钟。

当然,我们也可以自己实现延时函数。

以下是一个简单的延时函数示例:
```
void Delay(uint16_t time)
{
uint16_t i,j;
for(i=0;i<time;i++)
for(j=0;j<3000;j++);
}
```
这个函数的作用是延时一段时间,time参数表示延时的时间,单位为毫秒。

以上就是在STM32 CubeMX中使用延时函数的方法。

需要注意的是,在使用延时函数时,要避免影响系统的其他功能,最好使用定时器或者中断等方式来实现延时。

8位单片机微妙延时函数

8位单片机微妙延时函数

在单片机编程中,延时函数是非常重要的部分,它可以帮助我们控制程序的执行速度和节奏。

下面是一个基于8位单片机的微妙延时函数的示例。

假设我们使用的是8位单片机,如AT89C51,并且我们使用C语言进行编程。

这个延时函数将使用循环来达到延时的效果。

```c
#include <reg51.h> // 包含单片机特定的头文件
// 延时函数,单位为微秒
void delay(unsigned int time) {
unsigned int i, j;
for (i = 0; i < time; i++) {
for (j = 0; j < 125; j++); // 假设单片机的晶振频率为12.5MHz
}
}
```
这个函数的基本原理是通过循环延迟来达到延时的效果。

在每次循环中,我们使用一个空的for循环来消耗时间,这个循环的次数正好是所需延迟时间的倒数。

这里我们假设单片机的晶振频率为12.5MHz,这是许多8位单片机常见的频率。

需要注意的是,延时函数的具体实现会根据单片机型号、晶振频率、系统时钟等不同而有所差异。

在某些情况下,可能需要更精确或更适合的延时算法。

另外,对于大规模的应用,通常建议使用专门的时间库或者操作系统提供的延时函数,这样可以避免手动编写复杂的延时逻辑。

最后,要注意的是延时函数只是实现时间控制的一个手段,具体的实现需要根据具体的需求和环境来决定。

例如,如果你的应用需要高精度的延时,那么可能需要使用更复杂的方法,如定时器中断等。

单片机delay函数用法

单片机delay函数用法

单片机delay函数用法1. 引言在单片机编程中,延时函数是一项非常重要的功能。

通过延时函数,我们可以控制程序在执行过程中的时间间隔,以实现各种需要时间控制的功能。

本文将详细介绍单片机中延时函数的用法。

2. 延时函数的原理延时函数的原理是通过软件实现的。

在单片机中,可以使用定时器或循环控制来实现延时功能。

定时器是单片机中的一个硬件模块,通过设置定时器的计数值和时钟源,可以实现精确的定时功能。

而循环控制是通过在程序中加入循环,让程序在指定的时间内空转一段时间,从而实现延时的效果。

3. 延时函数的分类延时函数可以根据其实现的方式进行分类。

常见的延时函数有以下几种:3.1 定时器延时函数定时器延时函数是通过使用定时器模块来实现的。

通过设置定时器的相关参数,可以实现准确的延时功能。

定时器延时函数的优点是精确度高,但需要花费一定的时间和精力来配置定时器。

3.2 循环延时函数循环延时函数是通过在程序中加入循环来实现延时的效果。

循环延时函数的原理是让程序在指定的时间内进行循环,从而实现一段时间的延时。

循环延时函数的优点是简单易实现,但由于程序在延时期间需要不断进行循环,可能会占用较多的处理器资源。

3.3 软件中断延时函数软件中断延时函数是通过使用软件中断的方式实现延时功能。

在延时函数中,可以设置软件中断的定时器,当定时器计数值达到预设值时,触发软件中断,从而实现延时效果。

软件中断延时函数的优点是不需要额外的硬件支持,但在延时期间无法进行其他操作。

4. 常见的延时函数4.1 _delay_ms函数_delay_ms函数是一个常见的延时函数,用于实现以毫秒为单位的延时。

该函数的原型为:void _delay_ms(unsigned int ms);参数ms表示需要延时的毫秒数。

该函数的实现原理是通过循环控制来实现延时的效果。

使用_delay_ms函数时,需要注意以下几点:•延时时间的精确度取决于单片机的主频和循环次数。

stc15w4k48s4延时函数

stc15w4k48s4延时函数

stc15w4k48s4延时函数STC15W4K48S4是一款由深圳市富泰宏微电子有限公司生产的单片机。

该芯片基于8031芯片的核心,在功能上进行了扩展和优化,使其成为一款功能强大、可靠性高的单片机。

其中,STC15W4K48S4延时函数是该单片机中的一个重要功能。

在单片机的程序设计中,经常需要进行一些延时操作,以确保程序能够按照要求执行。

STC15W4K48S4延时函数就是针对这个需求而编写的。

STC15W4K48S4延时函数的实现方法主要有两种。

一种是使用循环来进行延时,即在程序中使用一个循环进行空转,从而达到延时的效果。

另一种是使用定时器来进行延时,即设置一个定时器,并在定时器到达预定时间后进行中断处理。

无论是哪种实现方法,STC15W4K48S4延时函数的使用都非常简单。

首先需要定义延时的时长,然后调用相应的函数即可。

例如,如果需要延时100毫秒,可以使用以下代码:```void delay_ms(unsigned int i){while(i--){delay_us(990);}}void delay_us(unsigned int i){while(i--);}```以上代码定义了两个函数,delay_ms()函数用于实现毫秒级的延时,而delay_us()函数用于实现微秒级的延时。

在delay_ms()函数中,通过循环调用delay_us()函数来实现延时。

delay_us()函数中的while循环会进行i次空转,从而实现了微秒级的延时。

总体来说,STC15W4K48S4延时函数是一款非常实用的单片机功能。

它不仅能够满足程序设计中常见的延时需求,而且还非常简单易用,可以大大提高程序设计的效率和可靠性。

在实际应用中,程序员只需要根据具体的需求选择合适的延时函数,并用适当的参数调用即可。

stc12c5a60s2延时函数

stc12c5a60s2延时函数
{
uint a,b,c;
for(a=t;a》0;a--)
for(b=10;b》0;b--)
for(c=85;c》0;c--);
}
网上找到的一个C语言延时程序:
/********************(STC12C5608AD12MHZz=1时精确延时
1ms)
*******************/
stc12c5a60s2延时函数
STC12C5A60S2/AD/PWM系列单片机是宏晶科技生产的单时钟/机器
周期(1T)的单片机,是高速/低功耗/超强抗干扰的新一代8051单片机,指
令代码完全兼容传统8051,但速度快8-12倍。内部集成MAX810专用复位
电路,2路PWM,8路高速10位A/D转换(250K/S),针对电机控制,强干
for(b=20;b》0;b--)
for(c=95;c》0;c--);
}
void Delay(uint t)//@12MHz
{
uint a,b,c;
for(a=t;a》0;a--)
for(b=10;b》0;b--)
for(c=95;c》0;c--);
}
void Delay(uint 来自)//@11.0952MHz扰场合。
软件延时并不精确,是用一个叫dpjxjl的小软件自动生成,以1MS
例:STC的1T单片机12MHz
关于STC12C5A60S2延时函数
这款芯片是1T时钟的8051单片机,下面是我自己整出来的延时函

按晶振高低排列:
void Delay(uint t)//@24MHz
{
uint a,b,c;
for(a=t;a》0;a--)

rh850延时函数

rh850延时函数

rh850延时函数Rh850延时函数是指用于实现延时操作的函数。

在Rh850单片机中,延时函数可以根据不同的需求,设置延时的时间长度,用于控制程序的执行速度。

下面将从以下几个方面进行介绍:1.延时函数的作用:延时函数主要是为了控制程序的执行速度,使程序在执行过程中能够暂停一段时间,并按照预定的时间长度继续执行。

在实际的应用中,延时函数可以用于稳定时序、调整频率、控制设备的工作时间等。

2.延时函数的实现原理:在Rh850单片机中,延时函数主要通过软件延时的方式实现。

具体的实现方式可以分为两种:软件循环延时和硬件定时器延时。

在软件循环延时中,延时函数首先获取当前的系统时钟频率,然后通过循环语句实现延时。

具体的延时时间=需要延时的时间/系统时钟频率。

这种方式的延时时间相对较长,不适用于需要高精度的应用。

而在硬件定时器延时中,延时函数通过设置定时器的计数值和计数模式实现延时。

具体的延时时间=定时器的计数值*定时器的计数周期。

这种方式的延时时间相对较短,适用于需要高精度的应用。

3.延时函数的编写:在Rh850单片机中,编写延时函数需要了解系统的时钟频率和定时器的工作原理。

在软件循环延时中,可以使用for循环或while循环实现延时。

在硬件定时器延时中,需要先初始化定时器的配置,并将计数值和计数模式设置为合适的值。

延时函数的编写需要考虑以下几点:延时时间的精度、延时时间的长短、延时时间的单位等。

在编写延时函数时,应该根据实际需求选择合适的延时方式和参数。

4.延时函数的注意事项:在使用延时函数时,需要注意以下几点:延时函数的调用位置、延时函数的调用频率、延时函数的并发性等。

延时函数的调用位置应该在合适的位置,以保证程序的正确执行。

延时函数的调用频率应该根据实际需求设置,以避免延时时间过长或过短。

延时函数的并发性要考虑多任务情况下的延时问题,以避免产生冲突或延时错乱。

总结起来,Rh850延时函数是用于实现延时操作的函数。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C:0x0010FEMOVR6,A//1T
C:0x0011EEMOVA,R6//1T
C:0x0012C3CLRC//1T
C:0x00139FSUBBA,DlyT //1T
C:0x00145003JNCC:0019//2T
C:0x00160E INCR6//1T
C:0x001780F8SJMPC:0011//2T 可以看出,0x000F~0x0017一共8条语句,分析语句可以发现并不是每条语句都执行DlyT次。核心循环只有0x0011~0x0017共6条语句,总共8个机器周期,第1次循环先执行“CLR A”和“MOV R6,A”两条语句,需要2个机器周期,每循环1次需要8个机器周期,但最后1次循环需要5个机器周期。DlyT次核心循环语句消耗(2+DlyT×8+5)个机器周期,当系统采用12 MHz时,精度为7 μs。 当采用while (DlyT--)循环体时,DlyT的值存放在R7中。相对应的汇编代码如下: C:0x000FAE07MOVR6, R7//1T
void Dly1ms(void) {
unsigned int i,j;
while (1) {
T_point = 1;
for(i=0பைடு நூலகம்i<2;i++){
for(j=0;j<124;j++){;}
}
T_point = 0;

汇编语言程序段

#pragma endasm 延时函数可设置入口参数,可将参数定义为unsigned char、int或long型。根据参数与返回值的传递规则,这时参数和函数返回值位于R7、R7R6、R7R6R5中。在应用时应注意以下几点: ◆ #pragma asm、#pragma endasm不允许嵌套使用;
摘要 实际的单片机应用系统开发过程中,由于程序功能的需要,经常编写各种延时程序,延时时间从数微秒到数秒不等,对于许多C51开发者特别是初学者编制非常精确的延时程序有一定难度。本文从实际应用出发,讨论几种实用的编制精确延时程序和计算程序执行时间的方法,并给出各种方法使用的详细步骤,以便读者能够很好地掌握理解。关键词 Keil C51 精确延时 程序执行时间引言 单片机因具有体积小、功能强、成本低以及便于实现分布式控制而有非常广泛的应用领域[1]。单片机开发者在编制各种应用程序时经常会遇到实现精确延时的问题,比如按键去抖、数据传输等操作都要在程序中插入一段或几段延时,时间从几十微秒到几秒。有时还要求有很高的精度,如使用单总线芯片DS18B20时,允许误差范围在十几微秒以内[2],否则,芯片无法工作。用51汇编语言写程序时,这种问题很容易得到解决,而目前开发嵌入式系统软件的主流工具为C语言,用C51写延时程序时需要一些技巧[3]。因此,在多年单片机开发经验的基础上,介绍几种实用的编制精确延时程序和计算程序执行时间的方法。 实现延时通常有两种方法:一种是硬件延时,要用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时;另一种是软件延时,这种方法主要采用循环体进行。1 使用定时器/计数器实现精确延时 单片机系统一般常选用11.059 2 MHz、12 MHz或6 MHz晶振。第一种更容易产生各种标准的波特率,后两种的一个机器周期分别为1 μs和2 μs,便于精确延时。本程序中假设使用频率为12 MHz的晶振。最长的延时时间可达216=65 536 μs。若定时器工作在方式2,则可实现极短时间的精确延时;如使用其他定时方式,则要考虑重装定时初值的时间(重装定时器初值占用2个机器周期)。 在实际应用中,定时常采用中断方式,如进行适当的循环可实现几秒甚至更长时间的延时。使用定时器/计数器延时从程序的执行效率和稳定性两方面考虑都是最佳的方案。但应该注意,C51编写的中断服务程序编译后会自动加上PUSH ACC、PUSH PSW、POP PSW和POP ACC语句,执行时占用了4个机器周期;如程序中还有计数值加1语句,则又会占用1个机器周期。这些语句所消耗的时间在计算定时初值时要考虑进去,从初值中减去以达到最小误差的目的。2 软件延时与时间计算 在很多情况下,定时器/计数器经常被用作其他用途,这时候就只能用软件方法延时。下面介绍几种软件延时的方法。2.1 短暂延时 可以在C文件中通过使用带_NOP_( )语句的函数实现,定义一系列不同的延时函数,如Delay10us( )、Delay25us( )、Delay40us( )等存放在一个自定义的C文件中,需要时在主程序中直接调用。如延时10 μs的延时函数可编写如下: void Delay10us( ) {
for(i=0;i<1;i++){
for(j=0;j<124;j++){;}
}
}
}
void main (void) {
Dly1ms();
} 把P1.0接入示波器,运行上面的程序,可以看到P1.0输出的波形为周期是3 ms的方波。其中,高电平为2 ms,低电平为1 ms,即for循环结构“for(j=0;j<124;j++) {;}”的执行时间为1 ms。通过改变循环次数,可得到不同时间的延时。当然,也可以不用for循环而用别的语句实现延时。这里讨论的只是确定延时的方法。2.4 使用反汇编工具计算延时时间 对于不熟悉示波器的开发人员可用Keil C51中的反汇编工具计算延时时间,在反汇编窗口中可用源程序和汇编程序的混合代码或汇编代码显示目标应用程序。为了说明这种方法,还使用“for (i=0;i<DlyT;i++) {;}”。在程序中加入这一循环结构,首先选择build taget,然后单击start/stop debug session按钮进入程序调试窗口,最后打开Disassembly window,找出与这部分循环结构相对应的汇编代码,具体如下: C:0x000FE4CLRA//1T
◆ 在程序的开头应加上预处理指令#pragma asm,在该指令之前只能有注释或其他预处理指令;
◆ 当使用asm语句时,编译系统并不输出目标模块,而只输出汇编源文件;
◆ asm只能用小写字母,如果把asm写成大写,编译系统就把它作为普通变量;
◆ #pragma asm、#pragma endasm和 asm只能在函数内使用。 将汇编语言与C51结合起来,充分发挥各自的优势,无疑是单片机开发人员的最佳选择。2.3 使用示波器确定延时时间 熟悉硬件的开发人员,也可以利用示波器来测定延时程序执行时间。方法如下:编写一个实现延时的函数,在该函数的开始置某个I/O口线如P1.0为高电平,在函数的最后清P1.0为低电平。在主程序中循环调用该延时函数,通过示波器测量P1.0引脚上的高电平时间即可确定延时函数的执行时间。方法如下: sbit T_point = P1^0;
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
} Delay10us( )函数中共用了6个_NOP_( )语句,每个语句执行时间为1 μs。主函数调用Delay10us( )时,先执行一个LCALL指令(2 μs),然后执行6个_NOP_( )语句(6 μs),最后执行了一个RET指令(2 μs),所以执行上述函数时共需要10 μs。 可以把这一函数当作基本延时函数,在其他函数中调用,即嵌套调用\[4\],以实现较长时间的延时;但需要注意,如在Delay40us( )中直接调用4次Delay10us( )函数,得到的延时时间将是42 μs,而不是40 μs。这是因为执行Delay40us( )时,先执行了一次LCALL指令(2 μs),然后开始执行第一个Delay10us( ),执行完最后一个Delay10us( )时,直接返回到主程序。依此类推,如果是两层嵌套调用,如在Delay80us( )中两次调用Delay40us( ),则也要先执行一次LCALL指令(2 μs),然后执行两次Delay40us( )函数(84 μs),所以,实际延时时间为86 μs。简言之,只有最内层的函数执行RET指令。该指令直接返回到上级函数或主函数。如在Delay80μs( )中直接调用8次Delay10us( ),此时的延时时间为82 μs。通过修改基本延时函数和适当的组合调用,上述方法可以实现不同时间的延时。2.2 在C51中嵌套汇编程序段实现延时 在C51中通过预处理指令#pragma asm和#pragma endasm可以嵌套汇编语言语句。用户编写的汇编语言紧跟在#pragma asm之后,在#pragma endasm之前结束。 如:#pragma asm
C:0x00111F DECR7//1T
C:0x0012EE MOVA,R6//1T
C:0x001370FAJNZC:000F//2T 循环语句执行的时间为(DlyT+1)×5个机器周期,即这种循环结构的延时精度为5 μs。 通过实验发现,如将while (DlyT--)改为while (--DlyT),经过反汇编后得到如下代码: C:0x0014DFFE DJNZR7,C:0014//2T 可以看出,这时代码只有1句,共占用2个机器周期,精度达到2 μs,循环体耗时DlyT×2个机器周期;但这时应该注意,DlyT初始值不能为0。 这3种循环结构的延时与循环次数的关系如表1所列。表1 循环次数与延时时间关系单位:μs注意:计算时间时还应加上函数调用和函数返回各2个机器周期时间。2.5 使用性能分析器计算延时时间 很多C程序员可能对汇编语言不太熟悉,特别是每个指令执行的时间是很难记忆的,因此,再给出一种使用Keil C51的性能分析器计算延时时间的方法。这里还以前面介绍的for (i=0;i<124;i++)结构为例。使用这种方法时,必须先设置系统所用的晶振频率,选择Options for target中的target选项,在Xtal(MHz)中填入所用晶振的频率。将程序编译后,分别在_point = 1和T_point = 0处设置两个运行断点。选择start/stop debug session按钮进入程序调试窗口,分别打开Performance Analyzer window和Disassembly window。运行程序前,要首先将程序复位,计时器清零;然后按F5键运行程序,从程序效率评估窗口的下部分可以看到程序到了第一个断点,也就是所要算的程序段的开始处,用了389 μs;再按F5键,程序到了第2个断点处也就是所要算的程序段的结束处,此时时间为1 386 μs。最后用结束处的时间减去开始处时间,就得到循环程序段所占用的时间为997 μs。 当然也可以不用打开Performance Analyzer window,这时观察左边工具栏秒(SEC)项。全速运行时,时间不变,只有当程序运行到断点处,才显示运行所用的时间。3 总结 本文介绍了多种实现并计算延时程序执行时间的方法。使用定时器进行延时是最佳的选择,可以提高MCU工作效率,在无法使用定时器而又需要实现比较精确的延时时,后面介绍的几种方法可以实现不等时间的延时: 使用自定义头文件的优点是,可实现任意时间长短的延时,并减少主程序的代码长度,便于对程序的阅读理解和维护。编写延时程序是一项很麻烦的任务,可能需要多次修改才能满足要求。掌握延时程序的编写,能够使程序准确得以执行,这对项目开发有着重要的意义。本文所讨论的几种方法,都是来源于实际项目的开发经验,有着很好的实用性和适应性。
相关文档
最新文档