程序用了int0中断,但中断处理过程不够简练,里面用了很影响速度的WORD型变量,还有那么多条件语句,速度跟不上,有效脉宽(可变部分)本来就只有1000us,中断如果用了50us,输出自然受干扰比较厉害。
据我的经验,最好还是调用BASCOM里的 pulsein 功能,即用轮询方式测量脉宽,当然轮询方式解PPM码的缺点是,当所有脉宽都测完后,距离下一个信号周期已经比较近了,可能用pulseout功能向舵机输出信号的时候比较局促,必须采用同时向4-5个舵机同时开始发高电平,然后各自在正确的时间降为低电平,当时我用的是很可怜的TINY13,内部RC主频9.6M,解出4个通道,稳稳的不会抖。
如果一定要用中断,最好在中断里全部使用汇编,可参考以下我在电调里使用的方式,但要注意,程序里使用的是TCNT0,最高约60级精度,一般情况下足够用了:
config timer0=timer , prescale = 256
isr_int0:
'For mega8
in r2, sreg '保存 SREG,在我的程序里其它地方没使用r2及r18,故不用PUSH,POP,节省了若干时钟周期
in r18,mcucr 'get int0 state
in r0,tcnt0 'get tcnt0
inc r18 'goggle r16.0
andi r18,1 'erash r16.1-7
sts {newrcin},r18 'newrcin 为一 BYTE 值,1或0,表明是否收到新的脉冲信号
mul r0,r18 '硬件乘法器
sts {pwmctlppm} ,r0 'PWMCTLPPM 为有效脉冲长度值,BYTE 类
ori r18,2
!out mcucr,r18 '改变 MCUCR.ISC00 值,即改变下次脉冲触发条件
clr r18
!out tcnt0,r18 'tcnt0 =0
wdr '喂狗,也可以不用
!out sreg , r2 '恢复 SREG
return
另外,在BASCOM里,用 bit 类值运算,速度很慢,建议全部改为 BYTE 类,可提高效率。转载
|