在学习红外遥控实验的时候遇到了下面问题,发给原子哥,几天了也没回复我,可能比较忙吧!
再一次在这发帖求助,希望大家一起学习交流!
我用探索者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;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>