|
相关连接:
匠人DIY旋转时钟全程实播(连载1:电机的选择与安装)
匠人DIY旋转时钟全程实播(连载2:指针板的供电方式)
匠人DIY旋转时钟全程实播(连载3:指针板原理图V01)
匠人DIY旋转时钟全程实播(连载4:一些细节考虑)
匠人DIY旋转时钟全程实播(连载6:指针板状态表v01)
匠人DIY旋转时钟全程实播(连载7:旋转时钟之裸奔照)
参与社区讨论
------------------------------------------------------------------------------------------------------------
匠人DIY旋转时钟全程实播(连载8:转速自适应算法)
------------------------------------------------------------------------------------------------------------
今天谈一下,如何控制显示速度,让显示速度与电机转速合拍。
一般的思路都是:检测电机旋转一周的时间,然后除以180(分辨点),得到一个时间作为显示切换的中断时间。但这样做就要用到除法了。匠人另辟蹊径,想了个算法。详情如下:
程序匠人 发表于 2008-1-2 17:12 侃单片机 ←返回版面  |
7楼: 在中断中调用除法,可能不是好办法 |
PIC没有乘/除法指令。虽然,picc会用内部函数代替除法指令,但毕竟速度和消耗资源方面都不理想。所以,在中断中调用除法,可能会有问题。
匠人正在写程序,目前考虑的也是这个问题。正在考虑尽量不用到乘除法,具体算法还没有成型,程序也还没有写好。待程序调通后,会公布。
欢迎协同讨论 | |
xwj 发表于 2008-1-3 00:24 侃单片机 ←返回版面  |
9楼: 哈哈,你不用除法怎么“根据速度计算出 1°所需要的时间”呢? |
程序匠人 发表于 2008-1-3 10:33 侃单片机 ←返回版面  |
14楼: 不用除法也可以计算出 1°所需要的时间 |
答复xwj ,不用除法也可以计算出 1°所需要的时间。 匠人已经有了初步的想法,待程序调通经过验证后公布。 | |
to fzj :关键是TIME1的初值如何计算呢?
你的算法用到了“/180”的除法,而且是双字节除单字节。匠人不知道你的系统频率是多少。不知道你有没有计算过这个除法要消耗多少时间?
匠人用的“自适应”算法是“逼近法”,算法如下: 1、预选确定一个“TIME1初值”。 2、对每个周期(电机旋转一周)内,TIME1中断的次数进行计数 3、每次过零时去判断,该周期内TIME1中断的次数是〉180次,还是<180次了,并调节“TIME1初值”(递增、递减)。 4、电机刚启动时,由于“TIME1初值”并不符合实际需要,所以显示会有点不正常。经过几秒钟后,“TIME1初值”逐渐逼近实际需要后,显示就正常了。 5、整个算法,不需要用到乘除法。
具体的调节程序如下:
//================ //INT中断 //================ if ( INTE && INTF ) { INTF = 0 ; //清除中断标志 //调整单列显示时间设置值 if ( TIMR1_JSQ > 180 ) { if ( TIMR1_JSQ > 190 ) { if ( TIMR1_JSQ > 220 ) { DISP_TIME_SET = DISP_TIME_SET - 4 ; } else DISP_TIME_SET = DISP_TIME_SET - 2 ; } else DISP_TIME_SET = DISP_TIME_SET - 1 ; if ( DISP_TIME_SET < 400 ) DISP_TIME_SET = 400 ; //钳位 } else if ( TIMR1_JSQ < 180 ) { if ( TIMR1_JSQ < 170 ) { if ( TIMR1_JSQ < 140 ) { DISP_TIME_SET = DISP_TIME_SET + 4 ; } else DISP_TIME_SET = DISP_TIME_SET + 2 ; } else DISP_TIME_SET = DISP_TIME_SET + 1 ;
if ( DISP_TIME_SET > 65100 ) DISP_TIME_SET = 65100 ; //钳位 }
//计数器处理 TIMR1_JSQ = 0 ; //TIMR1溢出计数器 = 0 DISP_LINE = DISP_LINE_ADJ ; //显示列计数器(0~179)=校正值 }
|