红外(IR)NEC协议驱动软件设计

1、红外遥控原理

        红外遥控原理是一种利用红外线(波长约为940纳米左右的不可见光)进行无线通信的技术,广泛应用于家用电器、多媒体设备及其他各类电子产品的遥控控制。其基本原理可以概括为以下几个步骤:

1. 信号编码:

•遥控器内部含有一个微型处理器,将用户的按键行为编码为特定的二进制数据序列。根据不同的红外遥控协议(如NEC、RC5、Sony SIRC等),数据会被转换为脉宽调制(PWM)信号,通过高低电平的持续时间(占空比)来表示二进制的0和1。

2. 红外发射:

•编码后的数据通过红外发射管(IR LED)发送出去。发射管在接收到脉冲信号后,会产生一定频率(通常为38kHz左右)的红外光脉冲信号。脉冲的高电平对应红外LED的开启,低电平对应关闭。

3. 接收与解码:

•红外接收器(如一体化的红外接收头)检测到这些红外光脉冲信号,并将其转换为电信号。

•接收器内部包含一个光电二极管,用于感应红外光强度的变化,然后经过一系列信号放大、滤波、整形等处理,还原出原始的脉冲信号。

•微控制器对接收到的脉冲信号进行解码,识别出其中的地址码、命令码及其校验码,从而执行相应的动作。

4. 协议解析与执行:

•解码后的数据按照红外遥控协议的约定进行解析,确定是哪个设备的哪个命令。

•控制设备(如电视、空调等)根据接收到的指令执行相应的操作。

总的来说,红外遥控系统实现了通过无线方式将用户指令传输给被控设备,并确保指令的正确执行。其优势在于成本较低、技术成熟且应用广泛,但也存在一定的局限性,如传输距离较短、易受角度和遮挡物影响等。

2、NEC协议

        关于NEC协议的介绍:NEC协议

3、软件方案

        结合红外遥控原理和NEC协议的规定,实现方案主要包含硬件和软件两部分,在实际的IR模块硬件设计中,一般会实现时序信号编解码流程,提高系统性能和简化软件复杂度。

        本文的软件设计将基于简单的GPIO模拟的方式:通过原理实现简单的红外发射,接收流程。总体设计如下:

方案说明:

        按照红外协议的编解码规则,整个设计中,需要保证使用38KHz的载波频率进行通信,则GPIO或PWM输出频率为38KHz,同时调整占空比,达到实际的需求。

4、代码实现

        以下代码主要作为伪代码实现基本的发射和接收逻辑。

#include <stdio.h>


/*电平定义*/
#define IR_HIGH         1
#define IR_LOW          0


/*状态机定义*/
#define IDLE            0
#define DATA_START      1
#define ADDRESS_CHECK   2
#define COMMAND_START   3
#define COMMAND_CHECK   4
#define REPEAT_CHECK    5

//获取GPIO电平值
unsigned char IR_GetGPIOLevel(void)
{
    //
}

//输出电平
void IR_SetGPIOLevel(unsigned char level)
{

}


/*延时函数*/
void IR_Delayus(unsigned int us)
{
    //
}

void IR_Delayms(unsigned int ms)
{
    //
}


/*同步码*/
void IR_OutputSYNC(void)
{
    IR_SetGPIOLevel(IR_HIGH); 
    IR_Delayms(9);    //9ms高电平脉冲
    IR_SetGPIOLevel(IR_LOW);
    IR_Delayus(4500);    //4.5ms低电平脉冲
}

/*逻辑0输出*/
void IR_Output0(void)
{
    IR_SetGPIOLevel(IR_LOW);
    IR_Delayus(560);    //560us低电平脉冲 
    IR_SetGPIOLevel(IR_HIGH);
    IR_Delayus(560);    //560us高电平脉冲
}

/*逻辑1输出*/
void IR_Output1(void)
{u
    IR_SetGPIOLevel(IR_LOW);
    IR_Delayus(560);    //560us低电平脉冲 
    IR_SetGPIOLevel(IR_HIGH);
    IR_Delayus(1690);    //1690us高电平脉冲
}

/*数据输出*/
void IR_SendData(unsigned char data)
{
    int i;
    unsigned char bit;        //LSB ---> MSB
    for(i=0; i<8; i++)
    {
        bit = (data >> i) & 0x1;
        if(bit)
            IR_Output1();
        else
            IR_Output0();
    }
}

/*信号编码*/
void IR_Encode(unsigned char addr, unsigned char cmd)
{
    IR_OutputSYNC();        //同步码
    IR_SendData(addr);        //地址
    IR_SendData(~addr);        //地址反码
    IR_SendData(cmd);        //命令
    IR_SendData(~cmd);        //命令反码
}

/*电平检测*/
unsigned int IR_GetHighTime(void)
{
    unsigned int time;

    //获取高电平时间
    //...
    return time;
}

unsigned int IR_GetLowTime(void)
{
    unsigned int time;

    //获取高电平时间
    //...
    return time;
}

/*信号解码*/
void IR_Decode()
{
    unsigned char data;
    unsigned char state = IDLE;

    while(1)
    {

        switch(state)
        {
            case IDLE:
                {
                    //判断电平时间,9ms高电平后跟4.5ms低电平
                    if()
                    {
                        state = DATA_START;    //跳到下一个状态 
                    }

                }
                break;
            case DATA_START:
                {
                    /*开始接收8位地址位。- 对每一位,检测560μs低电平和1690μs高电平(表示1)或560μs低电平和560μs高电平(表示0)。- 每接收一位,将结果累加到地址缓冲区,并进入ADDRESS_CHECK状态*/
                    state = ADDRESS_CHECK;    //跳到下一个状态
                }
                break;
            case ADDRESS_CHECK:
                {
                    /*接收并检查8位地址的反码,与之前接收到的地址位进行比较,验证是否一致。
   - 如果一致,则进入COMMAND_START状态,否则返回IDLE状态,等待新的同步信号*/
                }
                break;
            case COMMAND_START:
                {
                    /*类似于地址接收,开始接收8位命令位,并将结果累加到命令缓冲区*/
                }
                break;
            case COMMAND_CHECK:
                {
                    /*接收并检查8位命令的反码,与之前接收到的命令位进行比较,验证是否一致。
   - 如果一致,则认为本次接收的红外信号有效,触发相应的命令执行操作。
   - 不一致则返回IDLE状态,重新等待同步信号*/
                }
                break;
            case REPEAT_CHECK:
                {
                    /*如果在完成命令反码检查后,接收到的是一个单独的560μs低电平和560μs高电平组合(重复码特征),则视为重复命令,执行相应的重复命令处理。
   - 如果不是重复码特征,则返回IDLE状态,等待新的命令*/
                }
                break;
        }
    }
}



  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

K成长日志

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值