完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
最近在做stm8s003红外解码的程序,调试了几天,目前遇到一个难点迟迟未解决,就是:第一次按下遥控器按键,没有反应,接下来的每一次按下按键都能正常工作,不知道是什么原因呢?为什么每次上电后第一次没有反应?还请各位前辈指教一下!!!
不知道程序那里出了问题? #include "stm8s.h" /* Private defines -----------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ /* ********************************************************************************************************* * * 模块名称 : 红外遥控解码 * 引导码 地址码 地址反码 数据码 数据反码 9+4.5ms c0-c07 c0-c07 c0-c07 c0-c07 ********************************************************************************************************* */ #define LED_GPIO_PORT (GPIOC) #define LED_GPIO_PINS1 (GPIO_PIN_5) #define LED_GPIO_PINS2 (GPIO_PIN_6) #define REMOTE_ID 1 //红外遥控识别码(ID) u8 Ir_Status=0; //红外接收处理状态 u8 Ir_Receive_Count=0; //红外接收数据位计数 u32 Ir_Receive_Data=0; //32位的红外接收数据 u8 Ir_receive_ok=0; //红外接收完成标志 void Delay(u32 __IO nCount) { while(nCount!=0) nCount--; } /* ******************************************************************************** GPIO初始化 ******************************************************************************** */ void GPIO_Config(void) { GPIO_Init(GPIOB, GPIO_PIN_4, GPIO_MODE_IN_PU_IT); //PB4 GPIO_Init(LED_GPIO_PORT, (GPIO_Pin_TypeDef)LED_GPIO_PINS1, GPIO_MODE_OUT_PP_LOW_FAST);//PC5 GPIO_Init(LED_GPIO_PORT, (GPIO_Pin_TypeDef)LED_GPIO_PINS2, GPIO_MODE_OUT_PP_LOW_FAST);//PC6 } /* ******************************************************************************** 定时器初始化 ******************************************************************************** */ void TIM2_Config(void) { TIM2_DeInit(); TIM2_TimeBaseInit(TIM2_PRESCALER_2, 60000);//定时器设置1M的计数频率,1US的分辨率 ,计时60ms TIM2_ClearFlag(TIM2_FLAG_UPDATE); TIM2_ITConfig(TIM2_IT_UPDATE, ENABLE); TIM2_Cmd(DISABLE); } /* ******************************************************************************** 外部中断初始化 ******************************************************************************** */ void EXTIB_Config(void) { disableInterrupts(); EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOB, EXTI_SENSITIVITY_FALL_ONLY);//下降沿中断 enableInterrupts(); } /* ******************************************************************************** 红外解码初始化函数 ******************************************************************************** */ void Ir_Init(void) { GPIO_Config(); EXTIB_Config(); TIM2_Config(); } /* ******************************************************************************** 定时器溢出中断内处理 ******************************************************************************** */ void TIM_IT_Updata_Handdle(void) { TIM2_Cmd(DISABLE); Ir_Status=0; TIM2_ClearITPendingBit(TIM2_IT_UPDATE); TIM2_SetCounter(0); //TIM2_Cmd(DISABLE); // GPIO_WriteHigh(GPIOC,GPIO_PIN_5); } /* ******************************************************************************** 红外接收数据处理函数 ******************************************************************************** */ u8 Ir_Process(void) { u8 Ir_num=0; //最终处理后的键值返回值 u8 Address_H,Address_L; //地址码,地址反码 u8 Data_H,Data_L; //数据码,数据反码 if(Ir_receive_ok==1) //接收完成 { Address_H=Ir_Receive_Data>>24; //得到地址码 Address_L=(Ir_Receive_Data>>16)&0xff; //得到地址反码 //if((Address_H==(u8)~Address_L)&&(Address_H==REMOTE_ID))//检验遥控识别码(ID)及地址 if((Address_H==(u8)~Address_L))//检验遥控识别码(ID)及地址 { Data_H=Ir_Receive_Data>>8; //得到数据码 Data_L=Ir_Receive_Data; //得到数据反码 if(Data_H==(u8)~Data_L) //接收数据码正确 { Ir_num=Data_H; //正确键值 Ir_Receive_Data=0; } } } return Ir_num; //返回键值 } /* ******************************************************************************** 红外接收中断处理函数 ******************************************************************************** */ void Ir_Receive_Handle(void) { u16 Interval_tim=0;//两个下降沿间隔时间 switch(Ir_Status) { case 0://第一个下降沿,定时器开始计数 Ir_Status=1; TIM2_Cmd(ENABLE); //Enable TIM2 TIM2_SetCounter(0); //定时器计数值清零 break; case 1://第二个下降沿,定时器关闭,读取定时器计数值 TIM2_Cmd(DISABLE); Interval_tim=0; Interval_tim=TIM2_GetCounter(); //读取定时器计数值 TIM2_SetCounter(0); //定时器计数值清零 TIM2_Cmd(ENABLE); //Enable TIM2 //GPIO_WriteHigh(GPIOC,GPIO_PIN_5);//正常 if( (Interval_tim>=12500)&&(Interval_tim<=14500) )//判断引导码是否正确9+4.5ms { Ir_Status=2; //进入下一状态 } else //引导码错误,从新接收 { Ir_Status=0; Ir_Receive_Count=0; } break; case 2://开始32位数据的接收 TIM2_Cmd(DISABLE); Interval_tim=0; Interval_tim=TIM2_GetCounter(); TIM2_SetCounter(0); TIM2_Cmd(ENABLE); //Enable TIM2 if( (Interval_tim>=1000)&&(Interval_tim<=1300) ) //间隔1.12ms ->0 { Ir_Receive_Data=Ir_Receive_Data<<1; Ir_Receive_Count++; } else if( (Interval_tim>=2000)&&(Interval_tim<=2600) ) //间隔2.25ms ->1 { Ir_Receive_Data=Ir_Receive_Data<<1; Ir_Receive_Data=Ir_Receive_Data|0x0001; Ir_Receive_Count++; } else//不是0,1 接收错误,从新接收 { Ir_Status=0; Ir_Receive_Data=0; Ir_Receive_Count=0; } //超出接收数据位数,接收下一个 while(Ir_Receive_Count==32) { Ir_receive_ok=1;//红外接收完成 Ir_Status=0; Ir_Receive_Count=0; break; } break; default : break; } } /* ******************************************************************************** ******************************************************************************** */ //当红外接收到信号进入中断,运行定时器执行程序,红外未收到信号空闲时无中断定时器关闭 void main(void) { uint8_t key_val; Ir_Init(); while(1) { if( Ir_receive_ok == 1 ) //一帧红外数据接收完成 { key_val = Ir_Process(); Ir_receive_ok=0; //不同的遥控器面板对应不同的键值 0-9 switch( key_val ) { } } } } /*****************************/ INTERRUPT_HANDLER(EXTI_PORTB_IRQHandler, 4) { /* In order to detect unexpected events during development, it is recommended to set a breakpoint on the following instruction. */ disableInterrupts(); Ir_Receive_Handle(); enableInterrupts(); } /*****************************/ INTERRUPT_HANDLER(TIM2_UPD_OVF_BRK_IRQHandler, 13) { /* In order to detect unexpected events during development, it is recommended to set a breakpoint on the following instruction. */ TIM_IT_Updata_Handdle(); }[/code] |
|
相关推荐
9个回答
|
|
本帖最后由 andy_wsj 于 2015-10-29 22:05 编辑
凑巧我去年也做过一个stm8s003的红外接收 就上面的代码而言,我看到的差别在于,程序开始运行的时候,TIM2是关闭的 第一次按键之后,TIM2是关闭的,然后进case 0,清零打开TIM2,这一次是不正确的 之后每一次,TIM2都没有关闭,每一个case最后都TIM2_Cmd(ENABLE);了,后面每一次都正确 我就觉得,如果上电初始化就打开TIME2,是不是每一次就正确了呢?你可以试试。 说说我的做法,你可以参考: 区别在于,我没有使用定时器中断,我就设置定时器的周期也是1us,让它自动加,然后溢出 16位的定时器可以表达65.535ms,因此收到的引导码时间计数一定小于65535 红外输入引脚产生中断的时候,我用代码描述 if( start_flag ) { time1 = TIM2_CNT; //开始的时候,记录时刻1 start_flag = 0; time = 0; return; } else { time2 = TIM2_CNT; //第二次的时刻 if(time2 >= time1) //计算时间 { time = time2 -time1; } else { time = 0xFFFF - (time1 - time2) + 1; //定时器溢出时这样算 } time1 = TIM2_CNT; //更新当前时刻,为下一个码做准备 } ......... 后面就是用time去比较各种码的时间,跟你后面的代码差不多 就是不需要TIME2中断了。也不用开关TIM2,就直接读,然后注意溢出,还有重装载值是0xFFFF TIME2是16位吗?我记得不是很清楚了,当时我选用的是16位那个
最佳答案
|
|
|
|
|
|
谢谢了,按你的建议改了,真的可以了,之前一直在改其他地方,没有注意到定时器的问题,看来以后检查程序要细心一点了。还有你的程序也参考了
|
|
|
|
可以发改新的代码出来参考一下吗,我现在也在做红外遥控,急需
|
|
|
|
感谢楼主这个代码 我的红外解码也做成功了 按照你的代码键值显示是数字的有3位数
|
|
|
|
改好的代码能发一份给我吗,万分感谢
|
|
|
|
好文章,顶。刚***。
|
|
|
|
你好楼主,我按照你的键值处理程序,怎么返回的都是0000呀
|
|
|
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1276 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
1209 浏览 3 评论
2288 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
1372 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
1799 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-29 07:28 , Processed in 0.701495 second(s), Total 58, Slave 51 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号