在学习红外遥控实验的时候遇到了下面问题,发给原子哥,几天了也没回复我,可能比较忙吧!
再一次在这发帖求助,希望大家一起学习交流!
我用探索者F4的红外遥控带代码,在主循环里扫描
if(Remote_Scan())
{
GPIO_SetBits(GPIOF,GPIO_Pin_8);//BEEP
delay_ms(20);
}
else
GPIO_ResetBits(GPIOF,GPIO_Pin_8);
也就是如果有按键动作蜂鸣器就会短暂响下,可是我结果我按下按键蜂鸣器就长鸣一下,如果按住按键不放就会一直响。
我仔细分析了代码
if(RmtSta&0x80)//上次有数据被接收到了
{
RmtSta&=~0X10; //取消上升沿已经被捕获标记
if((RmtSta&0X0F)==0X00)RmtSta|=1<<6;//标记已经完成一次按键的键值信息采集
if((RmtSta&0X0F)<14)RmtSta++;
else
{
RmtSta&=~(1<<7);//清空引导标识
RmtSta&=0XF0; //清空计数器
}
}
发现如果没有连发码,在过140ms之后就认为完成一次完整的按键接收了,可是 RmtSta&=~(1<<7);//清空引导标识
就不立即响应了,必须要等下次定时器溢出进入 if(RmtSta&0x80)里,进行按键信息采集完成标记,以让主循环响应,可是,之前超时的时候已经清空了引导标识,所有必须等到下一次按键开始捕获的时候才让执行上一次的动作。
如果收到连发码就会立即响应连发码,想问下我的分析对不对?我很纠结这。
按键完成一次信息收集最起码要100ms以上,收到完成标记之后,就算主循环扫描立即响应,打开蜂鸣器发声并延时20ms,在这20ms中如果又发生按键或者在接受连发码,接收连发码或者按键的时间至少100ms,也就是说假设是主循环很快开始也至少会是响20ms后停80ms,然后再响20ms.这与结果不服,我在Remote_Scan(void)里添加printf()打印按键的结果,波特率设置460800,每次按键总是打印好几次按键值。
想问下原子哥分析下告诉我,我自己在基础上修改,之前每次捕获上升沿就给定时器置零,我绝对如果定时还用在其他地方这样做不好,就取出当前值,在捕获下降沿是在做了防溢出处理值将得到值减去之前的值,得到脉冲时间。我的结果和我分析的相符,可是我却不知是我的这样结果正确还是你的是正确的。请原子个分析下,附上代码,初始化都和参数都一样的,就中断处理有些差异
u8 REMOTE_STA;
//u8 REMOTE_RES;
u16 REMOTE_CNT;
u32 REMOTE_VAL;
void TIM1_CC_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1,TIM_IT_CC1)!=RESET)
{
if(RDATA)
{
REMOTE_CNT=TIM_GetCounter(TIM1);
TIM_OC1PolarityConfig(TIM1,TIM_ICPolarity_Falling);
REMOTE_STA|=0x40;
}
else
{
if((REMOTE_STA&0x1f)<3)//大于20ms以上不用计算
REMOTE_CNT=TIM_GetCapture1(TIM1)+((REMOTE_STA&0x1f)*10000)-REMOTE_CNT;
else REMOTE_CNT=0;
TIM_OC1PolarityConfig(TIM1,TIM_ICPolarity_Rising);
if(REMOTE_STA&0x40)//捕获完上升沿,完成下降捕获
{
if(REMOTE_STA&0x20)//收到引导码
{
if(300<REMOTE_CNT&&REMOTE_CNT<800)//560us
{
REMOTE_VAL<<=1;
REMOTE_VAL|=0;
}
else if(1400<REMOTE_CNT&&REMOTE_CNT<1800)//1680us
{
REMOTE_VAL<<=1;
REMOTE_VAL|=1;
}
else if(2200<REMOTE_CNT&&REMOTE_CNT<2700)//2500
{
//REMOTE_RES++;
REMOTE_STA|=0x80;
}
}
else if(4200<REMOTE_CNT&&REMOTE_CNT<4700)
{
REMOTE_STA|=0x20;
// REMOTE_RES=0;
}
}
REMOTE_STA&=0xA0;//清除捕获上升沿标志及计数
}
TIM_ClearITPendingBit(TIM1,TIM_IT_CC1);
}
}
void TIM1_UP_TIM10_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1,TIM_IT_Update)!=RESET)
{
if(REMOTE_STA&0x40)
REMOTE_STA++;
if(REMOTE_STA&0x20)
{
if(14<(REMOTE_STA&0x1f))//当捕获的时间大于140ms认为已经没有按键动作了
{
REMOTE_STA=0x80;//标志接收完成
REMOTE_CNT=0;//清空前一次定时器的起始值
}
}
TIM_ClearITPendingBit(TIM1,TIM_IT_Update);
}
}
u8 Remote_Scan(void)
{
u8 t1=0,t2=0;
u8 sta=0;
if(REMOTE_STA&0x80)
{
t1=REMOTE_VAL>>24;
t2=REMOTE_VAL>>16;
if((u8)~t1==t2)
{
t1=REMOTE_VAL>>8;
t2=(unsigned char)REMOTE_VAL;
if(t1==(u8)~t2)
{
sta=t1;
printf("键值:%d
",sta);
}
}
REMOTE_STA&=0x7f;
}
return sta;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
u8 Remote_Scan(void)
{
u8 sta=0;
u8 t1,t2;
if(RmtSta&(1<<6))//得到一个按键的所有信息了
{
t1=RmtRec>>24; //得到地址码
t2=(RmtRec>>16)&0xff; //得到地址反码
if((t1==(u8)~t2))//检验遥控识别码(ID)及地址
{
t1=RmtRec>>8;
t2=RmtRec;
if(t1==(u8)~t2)sta=t1;//键值正确
printf("键值:%d ",t1);
}
if((sta==0)||((RmtSta&0X80)==0))//按键数据错误/遥控已经没有按下了
{
RmtSta&=~(1<<6);//清除接收到有效按键标识
RmtCnt=0; //清除按键次数计数器
}
}
return sta;
}
只有正确收到数据并被主函数扫描到的话,就会打印收到的数据,串口设置为460800一减小误差,下面是我连按收到的数据:
键值:162[2015-10-17 06:45:26.024]
键值:162[2015-10-17 06:45:26.059]
键值:162[2015-10-17 06:45:26.094]
键值:162[2015-10-17 06:45:26.129]
键值:162[2015-10-17 06:45:26.164]
键值:162[2015-10-17 06:45:26.200]
键值:162[2015-10-17 06:45:26.235]
键值:162[2015-10-17 06:45:26.271]
键值:162[2015-10-17 06:45:26.306]
键值:162[2015-10-17 06:45:26.341]
键值:162[2015-10-17 06:45:26.376]
键值:162[2015-10-17 06:45:26.411]
键值:162[2015-10-17 06:45:26.447]
键值:162[2015-10-17 06:45:26.482]
键值:162[2015-10-17 06:45:26.517]
键值:162[2015-10-17 06:45:26.553]
键值:162[2015-10-17 06:45:26.588]
键值:162[2015-10-17 06:45:26.623]
键值:162[2015-10-17 06:45:26.658]
键值:162[2015-10-17 06:45:26.694]
键值:162[2015-10-17 06:45:26.729]
键值:162[2015-10-17 06:45:26.764]
键值:162[2015-10-17 06:45:26.801]
键值:162[2015-10-17 06:45:26.840]
键值:162[2015-10-17 06:45:26.871]
键值:162[2015-10-17 06:45:26.907]
键值:162[2015-10-17 06:45:26.942]
键值:162[2015-10-17 06:45:26.977]
从结果可以看出没隔35ms左右打印一次,我用Jlink调试了下,发现没收到一次数据会进入5次Remote_Scan(void),分析代码也发现问题的差异出现在你们的代码即使收到数据,只要按键没有结束就不会清空数据采样完成位,也就造成了主循环没个35ms进入一次Remote_Scan(void),我的代码是进入一次,清除一次,也就是每次收到就才会响应,之间有110ms的间隔,蜂鸣器响20ms,停90ms,你们的代码是35ms的间隔,响20ms,停15ms,所有停声音才会有很大的差别。
不过有个问题,即使我的代码没110ms的间隔,可是我们按键,很容易发生连发码,也就造成执行多次,我不知道是遥控的问题,还是遥控都这样,我们实际使用很不方便,有没有要消抖,或者滤波的必要?
一周热门 更多>