最近想要给小车添加航模遥控器遥控功能,毕竟航模遥控器拿在手里还是很有质感,手感很不错的。选择使用ppm信号,ppm信号相关参考:PPM相关 Arduino中micros()函数返回一个单位为无符号长整形的变量表示开机时间,符号为us。用于测量某段时间很是方便,上文分析的飞控代码中也是使用micros()函数对ppm信号进行解码,所以萌生了在51上封装类似函数的想法。和arduino不同的是,millis()函数本例返回值为浮点型 使用STC15W4K56S4单片机,24MHz主频,定时器进行12分频。
unsigned int times_L=0;
unsigned int times_H=0;
unsigned int xdata channelnum[3][8];
extern unsigned int xdata channel[8];
void Timer1Init(void)
{
AUXR &= 0xBF;
TMOD &= 0x0F;
TL1 = 0x00;
TH1 = 0x00;
TF1 = 0;
ET1=1;
TR1 = 1;
}
void time1() interrupt 3{
if(times_L==65535){
times_L=0;
times_H++;
}
else times_L++;
}
unsigned long int micros(){
unsigned char TH,TL;
TL=TL1;
TH=TH1;
return (times_L<<15)+(TH<<7)+(TL>>1);
}
float millis(){
unsigned char TH,TL;
TL=TL1;
TH=TH1;
return (times_H*2147483.648)+(times_L*32.768)+(TH*0.128)+(TL*0.0005);
}
void int0_init(){
IT0 = 1;
EX0 = 1;
}
void int0() interrupt 0{
unsigned long int now;
unsigned int diff;
static unsigned long int last;
static unsigned char num=0,ch=0;
now=micros();
diff=now-last;
last=now;
if(diff>3000||ch>7){
num++;
if(num>=3){
num=0;
ch_filtering();
}
ch=0;
}
else if(diff>900&&diff<2100){
channelnum[num][ch]=diff;
ch++;
}
}
void ch_filtering(){
unsigned char i;
for(i=0;i<8;i++)channel[i]=(channelnum[0][i]+channelnum[1][i]+channelnum[2][i])/3;
}
不过与参考文章不同,实测FS-IA6B接收机低电平时间为400us 网上有的实例使用两个外部中断或者使用电平变化方式进入中断,即无论有上升沿还是下降沿都进行中断,这时低电平固定时间不同可能会使最终计算结果不准确。通道值为低电平时间加高电平时间,所以只使用下降沿或上升沿中断可直接测得通道值。
|