完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
|
|
相关推荐
16个回答
|
|
|
|
|
|
|
|
|
还是使用外部的时钟芯片吧,不然的话,每次都有小的误差,总体时间上会有很大的误差的
|
|
|
|
|
|
|
|
|
|
|
|
用定时器做
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
云汉达人
延时的确不是一个好方法,它意味着这段时间内什么事情都不能操作了。 如果还考虑功耗等因素,一个比较好的方法是使用定时器,这样MCU的负载非常小。很多单片机的定时器允许设置分频系数,这样定时器就有一个很大的动态范围。有些单片机甚至可以将两个定时器级联,将两个8位的定时器组合成16位或者将两个16位组合成32位的。即使不支持级联模式,也可以将一个定时器的输出作为另外一个定时器的输出。 |
|
|
|
|
|
云汉达人 邀请回答
几个小时 的话,单片机上用什么都无所谓的,都可以实现。关键是什么,是精度,你要多么精确呢? 使用循环不准,是必然的,使用定时器会准一点,但是其频率是在主频上分频的,其定时误差也是很大的,尤其是在几个小时时,误差可以达到几秒到几十秒吧,还要看你的晶振的精度,以及你程序上的处理。 所以还是建议用外部的RTC芯片,RX8025、DS1302、DS1307都可以,就是个I2C的通讯。 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
云汉达人 邀请回答
肯定用定时器比较好啊,而且最好接上外部晶振,看定时基数,11.0592MHz的晶振的话,貌似可以最小精确到5ms基本无误差,12MHz的晶振的话貌似可以最小精确到1ms基本无误差。 定时器的详细使用可以参考这个帖子: I51开发板 第六讲:定时器之配置篇 http://www.icxbk.com/community/forum.php?mod=viewthread&tid=65517 (出处: ICKEY BBS) 里面有详细说明及例程: |
|
|
|
|
|
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--; } } } } 这种补偿是我这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--; } } } }
|
|
|
|
|
|
|
|
|
|
|
|
用rc充放电实现比较好
|
|
|
|
|
只有小组成员才能发言,加入小组>>
1018 浏览 1 评论
1849 浏览 0 评论
1830 浏览 1 评论
3254 浏览 5 评论
3581 浏览 9 评论
1021浏览 1评论
1850浏览 1评论
如何知道嵌入式电子控制单元 (ECU) 中的RAM使用情况?
1360浏览 1评论
1852浏览 0评论
1178浏览 0评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-2 00:49 , Processed in 1.212453 second(s), Total 104, Slave 84 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
1936