STM32F072B_DISCOVERY开发板飞利浦RC-5(SAA3010)协议红外遥控器解码源程序

2014年03月17日 23:53    发布者:sanqing
      基于免费申请的STM32F072B_DISCOVERY开发板 对常用飞利浦RC-5(SAA3010)协议红外遥控器解码的测试,附源码供有需要的朋友参考。
SAA3010是使用RC-5编码,有2位起始位、1位控制位、系统码占5位、指令码占6位, 一帧数据共占14位。其控制位每按一次
按键便会翻转一次,在编制发射程序的时候一定要注意。
电路连接很简单说明如下。
脚连接说明:
1、串口使用STM32F072B_DISCOVERY开发板的USART1,管脚接PA9(TX)、PA10(RX)。
2、一体化红外接收头数据输出端连接STM32F072B_DISCOVERY开发板的PA8管脚。

功能说明:
       红外遥控器的发射信号经一体化红外接收头数据端输出,由STM32F072B_DISCOVERY开发板的PA8端口采样(PA8配置为外部中断下降沿触发),由SysTick系统滴答定时器延时每20us采集一次,通过计数的方式得到一帧的所有低电平时间、高电平时间。通过对高、低电平时间的长短分析得出数据码IrDA_receive_Code,使用printf语句由《串口调试助手》显示RC-5红外编码格式的14位编码。
       系统上电后LED3(红色)闪烁,已说明接收系统正在运行中。按遥控按键,LED4(橙色)点亮,说明已进入中断解码,解码完成后LED4(橙色)熄灭。
中断函数如下(其他部分与NEC解码基本相同。请参阅
STM32F072B_DISCOVERY开发板NEC红外编码格式解码程序源码
http://www.eechina.com/thread-127802-1-1.html)
//////////PA8外部中断函数//////////////////////////////////////////////////////////////
void EXTI4_15_IRQHandler(void)
{
        u8 Data;
        u8 flag=0;                  //进入低电平时间为1.688ms(TimL>=75 && TimL<=90)标志:flag=1

        if(EXTI_GetITStatus(EXTI_Line8) != RESET)
  {
    /* Toggle LED4 */
    GPIO_SetBits(GPIOC, GPIO_Pin_8);
                TimL=IrDA_receive_timeL();//获得第一个低电平时间
                TimH=IrDA_receive_timeH();//获得第一个高电平时间
               
                if(TimL>=35 && TimL<49 && TimH>=35 && TimH<49)        //TimL、TimH:0.7ms--0.98ms(标准:0.844ms)
                {
                        IrDA_receive_Code=1;        //RC-5编码判断低电平获得数据,第一位起始码为1                                       
                        while(1)                                          
                        {
                                if(IrDA_IN==0)
                                {
                                        TimL=IrDA_receive_timeL();//获得此次低电平时间
/******************************************************************************/                                       
                //RC-5编码一位数据:“1”接收为:先高电平0.844ms+低电平0.844ms
                //RC-5编码一位数据:“0”接收为:先低电平0.844ms+高电平0.844ms
                //如果接收的低电平为1.688ms,则说明接收了一个高电平和一个低电平,即数据位2
                //只有前次低电平时间为1.688ms(TimL>=75 && TimL<=90),后面的短的低电平为“0”,其他情况均为“1”
/******************************************************************************/
                                        if(TimL>=35 && TimL<=49)        //0.7ms--0.98ms(标准:0.844ms)
                                        {
                                                if(flag==1)
                                                {
                                                        Data=0;//收到数据 0
                                                        IrDA_receive_Code<<=1;
                                                        IrDA_receive_Code+=Data;                                
                                                }
                                                else
                                                {
                                                        Data=1;//收到数据 1
                                                        IrDA_receive_Code<<=1;
                                                        IrDA_receive_Code+=Data;
                                                }
                                        }
                                        else if(TimL>=75 && TimL<=90) //1.5ms--1.8ms(标准:1.688ms)
                                        {
                                                flag=1;
                                                Data=2;//收到两位数据1和0,即 2
                                                IrDA_receive_Code<<=2;          //数据码左移2位
                                                IrDA_receive_Code+=Data;
                                        }
                                        else                        //信号异常(可能是干扰)
                                        {
                                                printf("红外编码接收异常,请重按遥控按键 TIMEL=%d\r\n",TimL);
                                                break;
                                        }               

                                }
                                if(IrDA_IN==1)
                                {
                                        TimH=IrDA_receive_timeH();//获得此高低电平时间
                                        if(TimH>=75 && TimH<=90) flag=0;                                 
                                        if(TimH>=1800)        //末位高电平时间超过36ms说明解码完成,退出解码循环
                                        {

                                                IrDA_receive_flag=1;
//                                                printf("接收RC-5编码为   :%X\r\n",IrDA_receive_Code);
                                                break;
                                        }
                                }                                
                        }               
                }
                else
                {
                        printf("非RC-5编码\r\n");
                }
        }
        delay_ms(500);//延时-防止按键时间过长,再次进入中断
        GPIO_ResetBits(GPIOC, GPIO_Pin_8);
//         EXTI->PR=1<<8;  //清除LINE8上的中断标志位
        /* Clear the EXTI line 8 pending bit */
        EXTI_ClearITPendingBit(EXTI_Line8);
//        EXTI->IMR&=0XFFFFFEFF;;//  关闭line8 BITx上的中断(此为红外中断)
}
系统时钟配置:
采用内部HSI(8Mhz)作为时钟源,经PLL6倍频到48Mhz输出。AHB clock = SYSCLK、APB clock = HCLK
注:如不配置,采用系统默认的HSI(8Mhz)时钟,由于指令周期长了(指令周期占用时间长)采集出的时间与实际偏差较大。

附件: 使用MDK-ARM 5.10编译
133725


该文章有附件资料,如需下载请访问 电脑版

网友评论

锋尚 2014年03月18日
感谢分享啊,好东西啊!!!!
yzb0414 2014年03月20日
感谢分享
qqfishbaby 2014年03月22日
感谢楼主 ! 编译器用的是keil哪个版本? 我的版本怎么没有stm32f072的
lkl0305 2014年03月22日
多谢分享啊:)
lkl0305 2014年03月22日
qqfishbaby 发表于 2014-3-22 10:31 static/image/common/back.gif
感谢楼主 ! 编译器用的是keil哪个版本? 我的版本怎么没有stm32f072的

看这个帖子:)http://www.eechina.com/thread-127306-1-1.html
MDK5.1中有
sanqing 2014年03月22日
qqfishbaby 发表于 2014-3-22 10:31 static/image/common/back.gif
感谢楼主 ! 编译器用的是keil哪个版本? 我的版本怎么没有stm32f072的

使用MDK-ARM 5.10编译。六楼的链接有下载地址。
lianyihu 2014年07月03日
这种帖子一定要支持!!
mcu_wolf 2014年07月19日
感谢楼主分享。。。:lol
lygpetter 2014年08月06日
楼主辛苦了!:)
longor1991 2015年07月13日
很不错,楼主辛苦了
lr00168 2015年12月06日
感谢楼主 !学习中,,,
wenlyben 2018年05月10日
感谢分享,支持楼主