打印
[AVR单片机]

共享改进版GCC自带的的毫秒延时函数

[复制链接]
2742|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
古道热肠|  楼主 | 2012-8-27 22:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
玩单片机,离不开延时函数,用GCC编译器,虽然的自带的_delay_ms(uint uicount)这个库函数,但存在一个问题,这个函数的最大延时长度有限,当晶振为1M时,最长为1X4X65536uS = 200多mS,这使得应用层用起来相当的不方便,于是自定义1个功能类似的函数,不调上层调底层,就用系统自带的那个消耗4个机器周期的底层来实现延时,程序如下,经测试,性能稳定,定时准确,方便使用,共享与大家评析。

#include <avr/io.h>
#include <util/delay.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long

//_delay_loop_2(uint16_t __count);
//参数 __count 为 16bit 长度,1-65536,65536被认为是0。
//每个循环花费4个CPU周期。
//所以当晶振为1Mhz时,最长延时为262.1 ms (milliseconds)
//1*4*65536=262144 us
void Delay(uint uiDelayCount)
{
while(uiDelayCount--)
{
  _delay_loop_2(1000*(12/4)); //12为当前晶振频率
}
}



//以下部分是测试代码
//指示灯占用PC3,PC5,PC6,PC7
void InitDevice(void)
{
  DDRD=0XF7; //D0,D1,D2设置为输出端口
DDRC = 0xFD; //C4-C7设置为输出,点灯用
}

main(void)
{
// DDRA = 0xff;
// PORTA = 0xFF;
InitDevice();
while(1)
{
  PORTD &= 0xF8;
  PORTC |= 0xE8;  //PC5,PC6,PC7,PC3置高
  Delay(1000);
  PORTD |= 0x07;
  PORTC &= 0x17;
  Delay(1000);
}
}

相关帖子

沙发
古道热肠|  楼主 | 2012-8-27 22:35 | 只看该作者
此函数用单片机指令延时,不占用单片机的定时器资源,但与振荡频率相关联,需根据系统使用的真实频率做相应的调整以下一行中的频率值
                _delay_loop_2(1000*(12/4));        //12为当前晶振频率
如果是8M,就将12改成8即可

使用特权

评论回复
板凳
airwill| | 2012-8-28 21:06 | 只看该作者
楼主有心了, 顶一个

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:以VS1003B和山景SOC芯片为背景,倾心研制数字化语音录放产品. 排忧邮箱:xg_2004_sy@126.com 得意之作是做了个AVR高压编程器,用起来爽歪歪, 串口MP3录放音模块,全面进入数字录放音时代

284

主题

6411

帖子

16

粉丝