请问用循环延时还是用定时器比较好?或者有其他的方法!谢谢!
时间会有不准的现象,头好大啊,大很多了
用定时器,或者systick
建议用定时器循环装载这样
比如你定时器定时上限是100秒,那么你就让它循环36次触发一小时延时事件,这样比较好
單片機的話還是推薦用定時器ISR,宣告變數一秒觸發ISR一次時遞增即可,之後進行時/分/秒換算,空檔時間可以設計其他應用
以上供參考
延时的确不是一个好方法,它意味着这段时间内什么事情都不能操作了。
如果还考虑功耗等因素,一个比较好的方法是使用定时器,这样MCU的负载非常小。很多单片机的定时器允许设置分频系数,这样定时器就有一个很大的动态范围。有些单片机甚至可以将两个定时器级联,将两个8位的定时器组合成16位或者将两个16位组合成32位的。即使不支持级联模式,也可以将一个定时器的输出作为另外一个定时器的输出。
几个小时 的话,单片机上用什么都无所谓的,都可以实现。关键是什么,是精度,你要多么精确呢?
使用循环不准,是必然的,使用定时器会准一点,但是其频率是在主频上分频的,其定时误差也是很大的,尤其是在几个小时时,误差可以达到几秒到几十秒吧,还要看你的晶振的精度,以及你程序上的处理。
所以还是建议用外部的RTC芯片,RX8025、DS1302、DS1307都可以,就是个I2C的通讯。
肯定用定时器比较好啊,而且最好接上外部晶振,看定时基数,11.0592MHz的晶振的话,貌似可以最小精确到5ms基本无误差,12MHz的晶振的话貌似可以最小精确到1ms基本无误差。
定时器的详细使用可以参考这个帖子:
I51开发板 第六讲:定时器之配置篇//www.icxbk.com/community/forum.php?mod=viewthread&tid=65517(出处: ICKEY BBS)
里面有详细说明及例程:
}
这种补偿是我这2周弄得,在主函数总补偿,缺点精度低。想要高精度就给你个想法:往定时器里补偿,因为没空所以我没整这个方案。希望你能理解我的程序
void timerinit(void) { TMCON=0x03; //------ 11 ;Timer0和Tiemr1选择时钟分频,Fosc/4=4Mhz;1/4us TMOD=0x11; //0001 0001 ;Timer0和Timer1设置工作方式1:16位定时器 TH0=(65536-40000)/256; //40000*1/4us=10ms TL0=(65536-40000)%256; TR0=0; ET0=1; //Timer0使能 TR0=1; //启动Timer0 TH1 = (65536 - 4000)/256; //4000*1/4us=1ms 用于定时处理 TL1 = (65536 - 4000)%256; TR1 = 0; ET1 = 1; //Timer1使能 TR1 =1; //启动Timer1 IPT0=1; //T0中断优先权,IPT0=1代表T0中断优先权为高 } void timer0()interrupt 1 //Timer0向量号 1 { //上次无水-->制水output(); TH0=(65536-40000)/256; //再次装入初值 TL0=(65536-40000)%256; //10ms if(++t0_1000ms==100) { t0_1000ms=0; btimer1s=1; if(++t1_2s==2) { t1_2s=0; btimer2s=1;//2s到达,TimeDeal()统计时间用 } if(btimeall==105)//补偿时间计数开始 { timegain++; } } } void TimeDeal(void) { if(btimer2s) //2s定时到 { btimer2s=0; //清零 if(++vJDQ1Tint5>=30)//当vJDQ1Tint5=30时,说明时间到达1min { vJDQ1Tint5=0;//清零 ++vJDQ1Runmin1;//加1 ++timeall; } //① if(vJDQ1Runmin1>=60)//vJDQ1Runmin=120时,说明时间到达2hour { vJDQ1Runmin1=0; //清零 ++vJDQ1Runhour1; //加一 ++vJDQ1Runhourbak1;//加一 } if(timeall>=105)//时间补偿用,105min 16s提前了1min { btimeall=1; if(timegain>=16)//16s<-------------补偿前设置为0,目的测试误差 { timeall=0; btimeall=0; vJDQ1Runmin1--; } } } }
定时器RTC