HK32F030MF4P6 红外遥控接收例程

这段代码主要展示了红外遥控的接收和解码实现。通过初始化GPIO和定时器,设置红外数据输入脚,并定义了解码红外信号的函数,包括同步码检测、数据位解码等。解码过程遵循NEC红外编码协议,对引导码、地址码和数据进行解析。

 应用场景

#ifndef __RED_H
#define __RED_H 
#include "main.h"

  
#define RDATA  PDin(4)     //红外数据输入脚
#define IR_IN  GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_4)   // PC3 红外接收DQ引脚
//红外遥控识别码(ID),每款遥控器的该值基本都不一样,但也有一样的.
//我们选用的遥控器识别码为0
#define REMOTE_ID 0                 

extern u8 ir_code[4];      // 解码值保存变量
extern u8 ir_decode_ok_flag;    // 解码成功标志位

void ALR_Remote_Init(void);    //红外传感器接收头引脚初始化
void Ir_Decode(void);         
#endif

#include "remote.h"

u8 ir_code[4];      // 解码值保存变量
u8 ir_decode_ok_flag = RESET;    // 解码成功标志位
//红外遥控初始化
//设置IO以及定时器4的输入捕获
void ALR_Remote_Init(void)                  
{  
    GPIO_InitTypeDef GPIO_InitStructure;
    
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Schmit = GPIO_Schmit_Disable;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

    GPIO_Init(GPIOD, &GPIO_InitStructure);
         
}

/*
    NEC红外编码: 引导码 + 地址码 + 地址码(取反) + 数据 + 数据(取反)
      引导吗:0.56ms(低电平) + 2.25ms(高电平)
       数据1: 0.56ms(低电平) + 1.12ms(高电平)
*/
// 红外解码程序,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 <= 9)) &&            // 560us低电平, 560us高电平
            ((h_cnt_save >= 3)&&(h_cnt_save <= 9)) )
        {
            bit_value = 0;
        }
        else if( ((l_cnt_save >= 3)&&(l_cnt_save <= 9)) &&      // 560us低电平,1680us高电平
                  ((h_cnt_save >= 14)&&(h_cnt_save <= 20)) )
        {
            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 >= 87)&&(l_cnt_save <= 93))  &&
            ((h_cnt_save >= 42)&&(h_cnt_save <= 48)) )            // 同步码,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;
        }        
    }     
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值