OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6130|回复: 5

分享一个超简单的不占用过多资源的红外解码程序

[复制链接]

5

主题

26

帖子

0

精华

高级会员

Rank: 4

积分
777
金钱
777
注册时间
2015-3-14
在线时间
74 小时
发表于 2020-8-23 14:21:43 | 显示全部楼层 |阅读模式
      由于最近案子的缘故,需要一个红外解码的程序。在网上也看到了其他人写的程序,当然也看到了原子哥的STM32F103的例程。感觉他们的解码要么复杂,要么采用了高大上的输入捕获功能,这样的解码方式感觉不太友好。于是自己思索一番,编写了一个基于定时循环执行的解码程序,就是只要定期执行就能解码的程序。这样的解码程序最大的优点就是不占用CPU资源,不需要延时函数,另外移植起来也是so easy!      解码程序主要使用了两个外部变量,一个是ir_decode_ok_flag 解码成功标志位,一个是ir_code[4]码值保存变量。
     使用方法,就是定时100us执行一次就可以了。当然其他定时时间间隔也是可以的,需要修改一下同步码、位码的时间上下限值。
解码函数主体部分:
本代码,引导码 4.5ms低电平 + 4.5ms高电平
                    位码0: 560us低电平 + 560us高电平
                    位码1 :560us低电平 + 1680us高电平
#define IR_IN    PAin(2)    // IR引脚


// 红外解码程序,100us定期执行就可以了
void Ir_Decode(void)
{
    static unsigned char l_cnt = 0;                            // 低电平时间计数
    static unsigned char h_cnt = 0;                            // 高电平时间计数
    static unsigned char l_cnt_save = 0;                       // 保存低电平时长
    static unsigned char h_cnt_save = 0;                       // 保存高电平时长
    static unsigned char falling_edge_valid_flag = RESET;      // IR电平由高变低标志位
    static unsigned char rcv_sync_ok_flag = RESET;             // 同步码接收成功标志位
    static unsigned char bit_value = 0;                        // 位解码值
    static unsigned char bit_rcv_cnt = 0;                      // 位接收个数变量
   
    if( RESET == IR_IN )
    {
        if( 0 == l_cnt )    // IR由高变低后立马记录上次测得的高电平时长
        {
            h_cnt_save = h_cnt;
            falling_edge_valid_flag = SET;
        }
        
        
        l_cnt ++;
        if( l_cnt > 250 )    // 防止计数溢出
        {
            l_cnt = 250;
        }
        h_cnt = 0;  // 计数清零
    }
    else
    {
        if( 0 == h_cnt )   // IR由低变高后立马记录上次测得的低电平时长
        {
            l_cnt_save = l_cnt;
        }
        
        h_cnt ++;
        if( h_cnt > 250 )   // 防止计数溢出
        {
            h_cnt = 250;
        }
        l_cnt = 0;  // 计数清零
        
    }
   
    if( SET == falling_edge_valid_flag )
    {
        falling_edge_valid_flag = RESET;
        
        /* 位解码 */
        if( ((l_cnt_save >= 3)&&(l_cnt_save <= 7)) &&            // 560us低电平, 560us高电平
            ((h_cnt_save >= 3)&&(h_cnt_save <= 7)) )
        {
            bit_value = 0;
        }
        else if( ((l_cnt_save >= 3)&&(l_cnt_save <= 7)) &&      // 560us低电平,1680us高电平
                  ((h_cnt_save >= 15)&&(h_cnt_save <= 18)) )
        {
            bit_value = 1;
        }
        else
        {                    
            bit_value = 2;
        }
        
        if( SET == rcv_sync_ok_flag )
        {
            if((1 == bit_value) || (0 == bit_value) )
            {
                if( bit_rcv_cnt < 8 )
                {
                    ir_code[0] |= (bit_value<< (bit_rcv_cnt%8));
                }
                else if( bit_rcv_cnt < 16 )
                {
                    ir_code[1] |= (bit_value<< (bit_rcv_cnt%8));
                }
                else if( bit_rcv_cnt < 24 )
                {
                    ir_code[2] |= (bit_value<< (bit_rcv_cnt%8));
                }
                else if( bit_rcv_cnt < 32 )
                {
                    ir_code[3] |= (bit_value<< (bit_rcv_cnt%8));
                }
               
                if( bit_rcv_cnt >= 31 )
                {
                    ir_decode_ok_flag = SET;
                    rcv_sync_ok_flag = RESET;
                }
               
                bit_rcv_cnt ++;
            }
            else
            {
                rcv_sync_ok_flag = RESET;                               // 位接收错误,重新解码
            }
        }


        if( ((l_cnt_save >= 42)&&(l_cnt_save <= 46))  &&
            ((h_cnt_save >= 42)&&(h_cnt_save <= 46)) )            // 同步码,4.5ms低电平,4.5ms高电平
        {
            rcv_sync_ok_flag = SET;
            bit_rcv_cnt = 0;
            ir_code[0] = 0;
            ir_code[1] = 0;
            ir_code[2] = 0;
            ir_code[3] = 0;
        }        
    }     
}
解码串口打印结果:
串口数据.png

Ir_Decode红外解码程序.zip (7.07 MB, 下载次数: 180)
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

17

主题

237

帖子

0

精华

高级会员

Rank: 4

积分
925
金钱
925
注册时间
2012-2-27
在线时间
393 小时
发表于 2020-8-25 11:36:45 | 显示全部楼层
回复 支持 反对

使用道具 举报

2

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
175
金钱
175
注册时间
2020-5-9
在线时间
58 小时
发表于 2020-11-19 15:18:03 | 显示全部楼层
大佬,我要是想解NEC编码的波是不是把同步码的4.5ms低电平改成9ms就行了
回复 支持 反对

使用道具 举报

5

主题

26

帖子

0

精华

高级会员

Rank: 4

积分
777
金钱
777
注册时间
2015-3-14
在线时间
74 小时
 楼主| 发表于 2020-12-10 17:53:52 | 显示全部楼层
是的,根据NEC编码定义修改下
回复 支持 反对

使用道具 举报

7

主题

88

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
273
金钱
273
注册时间
2015-1-10
在线时间
69 小时
发表于 2021-7-9 14:19:46 | 显示全部楼层
感谢分享
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2016-11-16
在线时间
30 小时
发表于 2021-8-11 10:45:17 | 显示全部楼层
感谢分享,红外遥控!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 05:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表