AVR单片机常用的延时函数

合集下载

AVR133 使用AVR单片机产生长延时

AVR133 使用AVR单片机产生长延时

AVR133: 使用AVR单片机产生长延时翻译:邵子扬 2006年12月14日shaoziyang@1背景当使用单片机的应用需要执行一个长延时时,设计者可以选择多种解决方法。

一个解决方法是使用硬件定时器。

因为典型定时器只有16位或24位,这个方法需要系统时钟足够低来产生长延时。

例如,一个运行在1 MHz系统时钟的24位定时器可以产生数十秒的延时。

这对于很多应用来说还不够,此外这个方法对于系统性能有影响。

另外一个方法使用软件计数一定数目的定时器溢出。

但是它使软件变得复杂,同时在等待长延时时不能进入低功耗模式。

第三种方法是使用一个很低频率的外部振荡器,定时器设置成外部触发的计数器,这可以产生很长的延时。

但是这也增加了系统的成本,因为还需要使用其他的器件。

这里介绍的方法显示了怎样用AVR AT90系列单片机(AT90S2313、AT90S4414和AT90S8515)产生和处理长延时。

只使用片内定时器而无需软件处理,这样在延时期间单片机内核可以进入低功耗模式。

因为定时器使用系统时钟来计时,所以无需其他外部器件。

因为有长延时的能力,例如,运行在20MIPS的AVR单片机可以产生长达半小时的延时。

2应用下面列出了一些需要使用到长延时的应用:●人机接口的超时●环境测量(噪声等级、污染)●管理和过程控制3AVR单片机的定时器/计数器下面小节简要的说明了AVR单片机定时器的用法。

更多详细资料请参考相关的单片机数据手册。

3.1定时器/计数器AT90系列单片机提供了两个通用定时器/计数器,一个8位和一个16位。

每个定时器/计数器有独立的10位预分频器,可以用做基于内部时钟的定时器或基于外部触发的计数器。

3.2定时器/计数器预分频图1显示了定时器/计数器的预分频器,可以选择4个不同的预分频:CK/8、CK/64、CK/256、CK/1024,这里CK是振荡器时钟。

对于两个定时器/计数器,可以选择CK或者外部信号作为时钟源。

AVR软件延时精确计算指导

AVR软件延时精确计算指导

更正。
m <= 6
/***************************************************
软件准确仿真延时时间 使用AVRstudio软件仿真可以看到准确的程序运行的时间,设置中 断的方式就可以了解到。 调入AVR Studio,为观察延时时间,点击左侧Workspace中的 Processer,注意看其中的几个参数:Cycle Counter和Stop Watch,前 一个是执行周期数,即从复位开始到目前为止共执行了多少个周期,而 Stop Watch则表示从复位开始到目前为止共用去的时间数,如果 Frenance中的频率值正确,那么这个时间就是正确的。这样,我们可 以通过观察这个时间来调循环次数,将时间基本精确地调整到延时 1ms。
我们由此得到语句的条数是3+3*(n+1),这里是3+254*(3+1)= 1020条。在普通的计算中,我们可以这样认为,for循环的语句数量是 n*4+4。 AVR多数指令的执行时间是晶振频率分之一,也就是一个时钟周 期,部分指令的时钟周期是2-4个时钟周期,详细内容请查看数据手 册。那么delay(254);的总运行时间1020个时钟周期,即为1020/ (7.3728×1000000)秒,约和1020/7.3728 =138微秒。在要求不高的 延时中,就可以使用for循环来多次调用这个delay作为100微秒使用, 而不用考虑外层for循环造成的时钟周期延时。 结语:这里只是给出了一个软件延时的简单例子,并不具有很强的 使用性,实际操作中可以定义delay100us,delay1ms,delay1s等函数 直接使用。
正常编译,按照常规方法打开JTAG下载并进入调试。我们要想办法 获取程序的运行指令个数。 按下图操作调出汇编程序框:

单片机延时

单片机延时

如果用软件延时的话,那么在执行延时程序的时候就不能作其它事了,如LED、按键扫描等。

用中断则可以实现多任务。

所以中断是个很好的资源,要充分利用秒=1000毫秒(ms) 1毫秒=1/1,000秒(s)1秒=1,000,000 微秒(μs) 1微秒=1/1,000,000秒(s)1秒=1,000,000,000 纳秒(ns) 1纳秒=1/1,000,000,000秒(s)1秒=1,000,000,000,000 皮秒(ps) 1皮秒=1/1,000,000,000,000秒(s)参考资料:资料用定时器延时,有时候显得有点麻烦,我们不如考虑软件精确延时,软件延时无非就是利用for或while多重循环。

以前用到延时函数时,都是从网上下载别人写好的延时子程序。

延时5ms,400ms,1s,……,这些延时函数的函数名中都清清楚楚地标明了延时的时间,可我一直不知道这些函数是如何编写的,确切地说,是如果根据延时时间来确定循环次数的。

如果是纳秒级的延时,可以通过示波器来观察波形,或者反汇编一下,计算一下指令执行时间,但如果延时时间相对较长,示波器便无能为力了。

这几天好好看了一下Keil调试,发现Keil的功能实在是太强大了。

利用Keil uVersion的调试就可以写出精确的软件延时程序。

以下是我的简单小结,文中所有程序都是在Xtal=11.0592MHZ下测试。

比如我需要一个400ms的延时,随便写了个两重循环,外层循环5次,内层循环暂且设为5000:void Delay400Ms(void){uchar i=5;unint j;while(i--){j=5000; //通过keil调试来确定循环次数while(j--);}}在main函数中调用Delay400Ms():void main(){while(1){P1=0;Delay400ms();P1=1;}}进入uVersion的调试状态,按F10进行单步,当黄色箭头指向Delay400ms ()这条语句时记下左边窗中Sys->sec的值,如图,是0.00042426。

单片机延时函数

单片机延时函数

单⽚机延时函数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单片机延时函数

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,并设置定时器中断。

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

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

AVR软件 延时精确计算指导(不错)

AVR软件 延时精确计算指导(不错)

/*************************************************************************** 延时 M32 7.3728M 粗略计算 */ void Delay100us(uint8 x) { uint8 i; //4clock
for(i=147;x!=0;x--) while(--i); //5 * i clock
在运行到第一个中断的时候 stop watch 的值是 6.68,当运行到第二个中断的时候,stop watch 的值为 148.11,可以得到 delay(254) 这条语句的执行时间约为 148.11—6.86=141.25us。我们看到软件仿真的时钟周期是 1028 个,与上面计算的 1020 个有一定差距,因为 上面的计算我们忽略了调用程序所花的时间。
void main(void) { init_devices(); delay(254);/*计算结果,本条语句延时约 138 微秒,avr studio 仿真结果延时 141 微妙,以仿真的为 准。*/
while(1) ; }
正常编译,按照常规方法打开 JTAG 下载并进入调试。我们要想办法获取程序的运行指令个数。 按下图操作调出汇编程序框:
我们由此得到语句的条数是 3+3*(n+1),这里是 3+254*(3+1)=1020 条。在普通的计算中,我们可以这样认为,for 循环的语句 数量是 n*4+4。 AVR 多数指令的执行时间是晶振频率分之一,也就是一个时钟周期,部分指令的时钟周期是 2-4 个时钟周期,详细内容请查看数据 手册。那么 delay(254);的总运行时间 1020 个时钟周期,即为 1020/(7.3728×1000000)秒,约和 1020/7.3728 =138 微秒。在要求不 高的延时中,就可以使用 for 循环来多次调用这个 delay 作为 100 微秒使用,而不用考虑外层 for 循环造成的时钟周期延时。 结语:这里只是给出了一个软件延时的简单例子,并不具有很强的使用性,实际操作中可以定义 delay100us,delay1ms,delay1s 等函数直接使用。

单片机精确毫秒延时函数

单片机精确毫秒延时函数

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

今天主要介绍软件延时以及单片机精确毫秒延时函数。

单片机的周期介绍在电子技术中,脉冲信号是一个按一定电压幅度,一定时间间隔连续发出的脉冲信号。

脉冲信号之间的时间间隔称为周期;而将在单位时间(如1秒)内所产生的脉冲个数称为频率。

频率是描述周期性循环信号(包括脉冲信号)在单位时间内所出现的脉冲数量多少的计量名称;频率的标准计量单位是Hz(赫)。

电脑中的系统时钟就是一个典型的频率相当精确和稳定的脉冲信号发生器。

指令周期:CPU执行一条指令所需要的时间称为指令周期,它是以机器周期为单位的,指令不同,所需的机器周期也不同。

对于一些简单的的单字节指令,在取指令周期中,指令取出到指令寄存器后,立即译码执行,不再需要其它的机器周期。

对于一些比较复杂的指令,例如转移指令、乘法指令,则需要两个或者两个以上的机器周期。

通常含一个机器周期的指令称为单周期指令,包含两个机器周期的指令称为双周期指令。

时钟周期:也称为振荡周期,一个时钟周期= 晶振的倒数。

对于单片机时钟周期,时钟周期是单片机的基本时间单位,两个振荡周期(时钟周期)组成一个状态周期。

机器周期:单片机的基本操作周期,在一个操作周期内,单片机完成一项基本操作,如取指令、存储器读/写等。

机器周期=6个状态周期=12个时钟周期。

51单片机的指令有单字节、双字节和三字节的,它们的指令周期不尽相同,一个单周期指令包含一个机器周期,即12个时钟周期,所以一条单周期指令被执行所占时间为12*(1/ 晶振频率)= x s。

常用单片机的晶振为11.0592MHz,12MHz,24MHz。

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

单片机精确毫秒延时函数对于需要精确延时的应用场合,需要精确知道延时函数的具体延。

avr单片机的定时器、中断和PWM(转)

avr单片机的定时器、中断和PWM(转)

/s/blog_4aa25f130100go4v.html转中断:我的理解就是cpu执行时,遇到中断——根据对应的中断源(硬件或软件)——pc定位中断入口地址,然后根据这里的函数指针——跳转到相应的服务程序之所以上面()了硬件或软件,这里还涉及到向量中断和非向量中断:区别就在于确定中断源,如果是硬件编码了中断源的,直接跳转相应的服务函数则是向量中断。

而非向量中断指的是:如果发生中断了,但此时还不清楚是那个中断,需要查找标志位来确定跳转到那个中断区域。

可以发现向量中断肯定来的快些,这里为定时器的中断来做好准备。

再来看看avr单片机的定时器:定时器/计数1(16位)————分为普通模式,CTC模式,快速pwm模式,相位修正pwm模式,相位频率修正pwm模式,输入捕获模式。

普通模式:*1 寄存器TCCR1B(控制寄存器)7 6 5 4 3 2 1 0ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10CS12 CS11 CS10控制分频(内:预分频器):取值0-5对应了停止,无分频,8,64,256,1024当为110为下降沿驱动,111为上升沿驱动(外部):用于对外部信号的计数*2上面的计数结果放在计数寄存器TCNT1,TCNT0中(高低8位)*3中断屏蔽寄存器(TIMSK)OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1OCIE0 TOIE0TOIE1 :设置为溢出中断,置1嘿嘿,有了上面的3个寄存器就可以做秒表等了——思路为:设定控制寄存器(内分频,还是外部计数?)——装初值——设置中断方式(这里用了溢出)——打开中断注意点:装初值时需要先写高位TCNT1,再写低位TCNT0,读时相反TCCR1B=0x01;无分频TCNT1H=0x88;TCNT1L=0x88;TIMSK|=BIT(2); 再开中断SREG|=bit(7); 这样初始化oK!由于avr不像51无int code等之类定义的方法,用的是#pragma data:code 底下为存储的内容写中断也类似:#pragma interrupt_handler (中断函数名:向量号)miao:9(现在该理解向量中断吧)写好申明后就写函数体了void miao(){中断服务程序}这样作为普通用法就小功告成了总结一下就是模式,初值,中断(对应的3个寄存器)和具体C函数的写法CTC模式比较输出模式:用于输出50%占空比的方波信号,用于产生准确的连续定时信号硬件:对应了pd4,pd5输出比较b和a比较输出*1 寄存器TCCR1A(控制寄存器)功能多了寄存器也分a、b了^_^7 6 5 4 3 2 1 0com1A1 COM1A0 com1B1 COM1B0 FOC1A FOC1B W GM11 WGM10用到了4567和01 4、5控制b 6、7控制acom1A(B)1 COM1A(B)0 一般用00和01 WGM11,WGM10放在底下讲0 0 普通i/00 1 比较匹配时输出取反1 0 比较匹配时输出01 1 比较匹配时输出1*2 寄存器TCCR1B(控制寄存器)7 6 5 4 3 2 1 0ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10CS12、CS11、CS10为设置时钟源的WGM13,WGM12,WGM11,WGM10用于波形产生描述的位选择,有对应的表0-15 这里选了4:CTC-OCR1A-立即更新-最大 OCR1A (16位)输出比较寄存器-这里存放了上限值设置的目的是,计数上升到了设定的上限后就电平取反思路:先初始话,对应的复用i/o为输出——设定com1A(B)1,COM1A(B)0 为比较输出取反——设定上限值为ocr1A 就ok了0CR1A可以根据公式计算:具体公式看手册,这里因为我打不起来o(∩_∩)o...哈哈总结一下就是控制寄存器a,b以及上限的值即可产生方波快速PWM分8位9位10位快速pwm,以及自定义方式我的理解:OCR1A存放上限值,这样用上了A的功能,由上面可知A只能为方波了,且计数到这个值时取反下限值通过OCR1B来确定的,从而计数到这个值置0,从而可以发现在一个周期内 OCROB即为高电平的时间(确定占空比)如图TCCR1A=0x63;TCCR1B=0x1B; 工作方式(快速pwm15,64分频)和分频系数OcR1A=1249;OCCR1B=250; 设为100Hz PWM信号,和2毫秒的高电平时间总结一下就是控制寄存器:由上限值,和分频系数可以确定计数的时间,确定频率由下限值可以确定占空比怎么样?明白了吗?o(∩_∩)o...相位修正PWM和快速pwm一样,模式分8位9位10位快速pwm,以及自定义方式共5种对应123和10,11相位修正其实和上面的方法相同,只不过到最大值时,不是取反,而是计数--,直到到了下限时取反由上可以发现2图的区别吧,一个为到TOP后,直接置0,后者为--,且在top 不取反而是到了最小值是取的,周期故而也比快速的长了一倍,故频率为快速pwm的一半,但是占空比不变,这也是为什么叫快速pwm的原因TCCR1A=0x63;TCCR1B=0x13 工作方式(相位修正pwm11,64分频)和分频系数OcR1A=1249;OCCR1B=250; 设为100Hz PWM信号,和2毫秒的高电平时间相位频率修正PWM和相位修正的类似输入捕获。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

AVR单片机常用的延时函数
/******************************************************************** *******/
//C header files:Delay function for AVR
//MCU:ATmega8 or 16 or 32
//Version: 1.0beta
//The author:
/******************************************************************** *******/
#include<AVRdef.h>
void delay8RC_us(unsigned int time) //8Mhz内部RC震荡延时Xus
{
do
{
time--;
}
while(time>1);
}
void delay8RC_ms(unsigned int time) //8Mhz内部RC震荡延时Xms
{
while(time!=0)
{
delay8RC_us(1000);
time--;
}
}
/******************************************************************** **********/
void delay1M_1ms(void) //1Mhz延时1ms
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
void delay1M_xms(unsigned int x) //1Mhz延时xms
{
unsigned int i;
for(i=0;i<x;i++)
{
delay1M_1ms();
}
/******************************************************************** **********/
void delay2M_1ms(void) //2Mhz延时1ms
{
unsigned char a,b;
for(b=4;b>0;b--)
for(a=248;a>0;a--);
NOP();
}
void delay2M_xms(unsigned int x) //2Mhz延时xms
{
unsigned int i;
for(i=0;i<x;i++)
{
delay2M_1ms();
}
}
/******************************************************************** **********/
void delay4M_1ms(void) //4Mhz延时1ms
{
unsigned char a,b,c;
for(c=7;c>0;c--)
for(b=8;b>0;b--)
for(a=34;a>0;a--);
}
void delay4M_1us(void) //4Mhz延时1us
{
NOP();
NOP();
}
void delay4M_xms(unsigned int x) //4Mhz延时xms
{
unsigned int i;
for(i=0;i<x;i++)
{
delay4M_1ms();
}
/******************************************************************** **********/
void delay73782M_1us(void) //7.3782Mhz延时1us
{
unsigned char a;
for(a=2;a>0;a--);
}
void delay73782M_1ms(void) //7.3782Mhz延时1ms
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=254;b>0;b--)
for(a=13;a>0;a--);
}
void delay73782M_xms(unsigned int x) //7.3782Mhz延时xms
{
unsigned int i;
for(i=0;i<x;i++)
{
delay73782M_1ms();
}
}
/******************************************************************** **********/
void delay8M_1ms(void) //8Mhz延时1ms
{
unsigned char a,b,c;
for(c=11;c>0;c--)
for(b=4;b>0;b--)
for(a=89;a>0;a--);
}
void delay8M_1us(void) //8Mhz延时1us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=1;a>0;a--);
}
/********************************************************************
**********/
void delay12M_1us(void) //12Mhz延时1us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=3;a>0;a--);
}
void delay12M_1ms(void) //12Mhz延时1ms
{
unsigned char a,b;
for(b=129;b>0;b--)
for(a=45;a>0;a--);
}
void delay12M_xms(unsigned int x) //12Mhz延时xms
{
unsigned int i;
for(i=0;i<x;i++)
{
delay12M_1ms();
}
}
/******************************************************************** **********/
void delay16M_1us(void) //16Mhz延时1us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=5;a>0;a--);
}
void delay16M_1ms(void) //16Mhz延时1ms
{
unsigned char a,b,c;
for(c=17;c>0;c--)
for(b=134;b>0;b--)
for(a=2;a>0;a--);
}
void delay16M_xms(unsigned int x) //16Mhz延时xms
{
unsigned int i;
for(i=0;i<x;i++)
{
delay16M_1ms(); }
}。

相关文档
最新文档