0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

CW32L012/F030灵眸X1智能小车——板载红外接收开发

CW32生态社区 来源:CW32生态社区 作者:CW32生态社区 2026-01-05 16:52 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

红外通信介绍

在光谱中波长自760nm至400um的电磁波称为红外线,它是一种不可见光。红外线通信的例子我们每个人应该都很熟悉,目前常用的家电设备几乎都可以通过红外遥控的方式进行遥控,比如电视机、空调、投影仪等,都可以见到红外遥控的影子。这种技术应用广泛,相应的应用器件都十分廉价,因此红外遥控是我们日常设备控制的理想方式。

红外通讯原理

红外光是以特定的频率脉冲形式发射,接收端收到到信号后,按照约定的协议进行解码,完成数据传输。在消费类电子产品里,脉冲频率普遍采用 30KHz 到 60KHz 这个频段,NEC协议的频率就是38KHZ。 这个以特定的频率发射其实就可以理解为点灯,不要被复杂的词汇难住了,就是控制灯的闪烁频率(亮灭),和刚学单片机完成闪烁灯一样的意思,只不过是灯换了一种类型,都是灯。

接收端的原理: 接收端的芯片对这个红外光比较敏感,可以根据有没有光输出高低电平,如果发送端的闪烁频率是有规律的,接收端收到后输出的高电平和低电平也是有规律对应的,这样发送端和接收端只要约定好,那就可以做数据传输了。

红外线传输协议可以说是所有无线传输协议里成本最低,最方便的传输协议了,但是也有缺点,距离不够长,速度不够快;当然,每个传输协议应用的环境不一样,定位不一样,好坏没法比较,具体要看自己的实际场景选择合适的通信方式。

NEC协议介绍

NEC协议是众多红外线协议中的一种(这里说的协议就是他们数据帧格式定义不一样,数据传输原理都是一样的),我们购买的外能遥控器、淘宝买的mini遥控器、电视机、投影仪几乎都是NEC协议。 像格力空调、美的空调这些设备使用的就是其他协议格式,不是NEC协议,但是只要学会一种协议解析方式,明白了红外线传输原理,其他遥控器协议都可以解出来。

NEC协议一次完整的传输包含: 引导码、8位地址码、8位地址反码、8位命令码、8位命令反码。这里我们主要讲解如何接收红外发送端发送的NEC协议内容。

图片

引导码:由9ms的低电平+4.5ms的高电平组成。

图片

4个字节的数据: 地址码+地址反码+命令码+命令反码。 这里的反码可以用来校验数据是否传输正确,有没有丢包。

重点: NEC协议传输数据位的时候,0和1的区分是依靠收到的高、低电平的持续时间来进行区分的。这是解码关键。

数据发送0码:0.56ms低电平+ 0.56ms的高电平。

图片

数据发送1码:0.56ms低电平+1.68ms的高电平

wKgZPGlVHeiAXGzOAABrxrR9HUg381.jpg

所以,收到一个数据位的完整时间表示方法是这样的:

    收到数据位0:   0.56ms低电平+ 0.56ms的高电平
    收到数据位1:  0.56ms低电平+1.68ms的高电平

还有一个重复码,它是由一个 9ms 的低电平和一个 2.5ms 的高电平组成。当一个红外信号连续发送时,可以通过发送重复码的方式快速发送。

wKgZPGlbe12AH8IyAAIVd671ZIc268.jpg

电路设计

当红外线接收头感应到有红外光就输出低电平,没有感应到红外光就输出高电平。因此我们配置红外引脚为外部中断下降沿触发方式,当红外引脚有下降沿时,我们马上进入中断处理并接收红外信号。

红外接收电路如图,连接到CW32L012/F030的PB10引脚。

图片

工程代码:

引脚配置如下:

//红外引脚初始化
void infrared_goio_config(void)
{
    IR_RCC_GPIO_ENABLE();      // 使能GPIO时钟
    GPIO_InitTypeDef GPIO_InitStruct;                   // GPIO初始化结构体
    GPIO_InitStruct.Pins  = IR_PIN;                     // GPIO引脚
    GPIO_InitStruct.Mode  = GPIO_MODE_INPUT_PULLUP;     // 上拉输入
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;            // 速度高
    GPIO_InitStruct.IT    = GPIO_IT_FALLING;            // 下降沿触发中断
    GPIO_Init(IR_PORT, &GPIO_InitStruct);               // 初始化
    // 清除PB0中断标志
    GPIOA_INTFLAG_CLR(EXTI_BV);
    // 使能NVIC
    NVIC_EnableIRQ(EXTI_IRQ);
}

红外信号的数据,全部是以时间长度来确定数据是0还是1,而最小的单位要求有560us,已经达到了us级的测量。

获取低电平时间的实现代码如下:

//获取红外低电平时间
//以微秒us作为时间参考
void get_infrared_low_time( uint32_t *low_time )
{
    uint32_t time_val = 0;
    while( GPIO_ReadPin(IR_PORT, IR_PIN) == 0 )
    {
        if( time_val>= 500 )
        {
            *low_time = time_val;
            return;
        }
        delay_us(20);
        time_val++;
    }
    *low_time = time_val;
}

当引脚为低电平时,将进入 while 循环,直到不为低电平时就结束循环。在循环之中不断的让时间变量time_val累加, 每加一次需要经过20us。当time_val变量累加时间大于 500 * 20 = 10000us = 10ms时,判断为超时,强行结束该函数,防止阻碍系统运行。

获取高电平时间的代码同理:

//获取红外高电平时间
//以微秒us作为时间参考
void get_infrared_high_time(uint32_t *high_time)
{
    uint32_t time_val = 0;
    while( GPIO_ReadPin(IR_PORT, IR_PIN) == 1 )
    {
        if( time_val >= 250 )
        {
            *high_time = time_val;
            return;
        }
        delay_us(20);
        time_val++;
    }
    *high_time = time_val;
}

引导码与重复码判断

引导码是由一个 9ms 的低电平和一个 4.5ms 的高电平组成。每当接收到一个红外信号时,第一个数据就是引导码。我们通过判断红外信号的第一个数据是否是引导码,来决定是否要进行后面的数据接收处理。

重复码是由一个 9ms 的低电平和一个 2.5ms 的高电平组成。当我们的红外遥控一直按住按键时,就会发出重复码,我们可以检测重复码,来确定是否要连续触发重复动作,比如长按开机,长按加速等等。

/******************************************************************
 * 函 数 名 称:guide_and_repeat_code_judgment
 * 函 数 说 明:引导 和 重复 码 判断
 * 函 数 形 参:无
 * 函 数 返 回:1:不是引导码   2:重复码  0:引导码
 * 作       者:LC
 * 备       注:以20微秒us作为时间参考
                引导码:由一个 9ms 的低电平和一个 4.5ms 的高电平组成
                重复码:由一个 9ms 的低电平和一个 2.5ms 的高电平组成
******************************************************************/
uint8_t guide_and_repeat_code_judgment(void)
{
    uint32_t out_time=0;
    get_infrared_low_time(&out_time);
    //time>10ms             time < 8ms
    if((out_time > 500) || (out_time < 400))
    {
        return 1;
    }
    get_infrared_high_time(&out_time);
    // x >5ms  或者 x< 2ms
    if((out_time > 250) || (out_time < 100))
    {
        return 1;
    }
    //如果是重复码  2ms < time < 3ms
    if((out_time > 100) && (out_time < 150))
    {
        return 2;
    }
    return 0;
}

完整红外数据接收

具体接收流程:【判断是否接收到引导码】->【接收数据】->【判断数据是否正确】。

//接收红外数据
void receiving_infrared_data(void)
{
    uint16_t group_num = 0,data_num = 0;
    uint32_t time=0;
    uint8_t bit_data = 0;
    uint8_t ir_value[5] = {0};
    uint8_t guide_and_repeat_code = 0;
    //等待引导码
    guide_and_repeat_code = guide_and_repeat_code_judgment();
    //如果不是引导码则结束解析
    if(  guide_and_repeat_code == 1 ) return;
    //共有4组数据
    //地址码+地址反码+命令码+命令反码
    for(group_num = 0; group_num < 4; group_num++ )
        {
        //接收一组8位的数据
        for( data_num = 0; data_num < 8; data_num++ )
        {
            //接收低电平
            get_infrared_low_time(&time);
            //如果不在0.56ms内的低电平,数据错误
            if((time > 60) || (time < 20))
            {
                return ;
            }
            time = 0;
            //接收高电平
            get_infrared_high_time(&time);
            //如果是在1200us< t< 2000us范围内则判断为1
            if((time >=60) && (time < 100))
            {
                bit_data = 1;
            }
            //如果是在200us< t< 1000us范围内则判断为0
            else if((time >=10) && (time < 50))
            {
                bit_data = 0;
            }
            //groupNum表示第几组数据
            ir_value[ group_num ] < <= 1;
            //接收的第1个数为高电平;在第二个for循环中,数据会向右移8次
            ir_value[ group_num ] |= bit_data;
            //用完时间要重新赋值
            time=0;
        }
    }
    //判断数据是否正确,正确则保存数据
    infrared_data_true_judgment(ir_value);
}

判断数据是否正确,可以通过将正常数据取反,与反码比较。如果不一致说明数据不对。

typedef struct INFRARED_DATA{
    uint8_t AddressCode;            //地址码
    uint8_t AddressInverseCode;     //地址反码
    uint8_t CommandCode;            //命令码
    uint8_t CommandInverseCode;     //命令反码
}_INFRARED_DATA_STRUCT_;
_INFRARED_DATA_STRUCT_ InfraredData;
//红外数据是否正确判断
uint8_t infrared_data_true_judgment(uint8_t *value)
{
    //判断地址码是否正确
    if( value[0] != (uint8_t)(~value[1]) )  return 0;
    //判断命令码是否正确
    if( value[2] != (uint8_t)(~value[3]) )  return 1;
    //串口输出查看接收到的数据
    printf("%x %x %x %xrn",value[0],value[1],value[2],value[3]);
    //保存正确数据
    InfraredData.AddressCode        = value[0];
    InfraredData.AddressInverseCode = value[1];
    InfraredData.CommandCode        = value[2];
    InfraredData.CommandInverseCode = value[3];
}
//获取红外发送过来的命令
uint8_t get_infrared_command(void)
{
    return InfraredData.CommandCode;
}
//清除红外发送过来的数据
void clear_infrared_command(void)
{
    InfraredData.CommandCode = 0x00;
}

最后,记得在外部中断服务函数中,调用红外接收函数。

void EXTI_HANDLER(void)
{
        if(IR_PORT->ISR_f.EXTI_PIN)   // 中断标志位
        {
                if(GPIO_ReadPin(IR_PORT, IR_PIN) == GPIO_Pin_RESET)  // 如果是低电平
                {
                        //接收一次红外数据
                        receiving_infrared_data();
                }
                GPIOA_INTFLAG_CLR(EXTI_BV); // 清除标志位
        }
}

最后在main函数中编写以下代码(delay_us函数不在此展开说明)

uint8_t val;
int main(void)
{
        OLED_Init();//初始化
        infrared_goio_config();//红外初始化
        OLED_ShowString(1,1,"hello");//OLED显示字符串
        while(1)
        {
                val=get_infrared_command();//接收红外发过来的数据
                OLED_ShowHexNum(2,1,val,2);//显示数据
        }
}

工作现象

将代码烧入开发板之后,可以观察到以下现象

OLED显示屏第一行第一列显示字符串hello

未按下遥控器,第二行显示00

按下遥控器之后,第二行显示接收到的数据


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 智能小车
    +关注

    关注

    87

    文章

    566

    浏览量

    83555
  • 红外通信
    +关注

    关注

    1

    文章

    56

    浏览量

    10317
  • 红外模块
    +关注

    关注

    0

    文章

    17

    浏览量

    9921
  • CW32
    +关注

    关注

    1

    文章

    326

    浏览量

    1994
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    CW32L012/F030X1智能小车——板载WS2812驱动示例

    WS2812是一种广泛使用的地址可控制的RGB LED模块,其内置驱动电路和控制芯片,允许用户通过单线信号控制多个LED的颜色和亮度。
    的头像 发表于 01-05 16:35 3491次阅读
    <b class='flag-5'>CW32L012</b>/<b class='flag-5'>F030</b><b class='flag-5'>灵</b><b class='flag-5'>眸</b><b class='flag-5'>X1</b><b class='flag-5'>智能</b><b class='flag-5'>小车</b>——<b class='flag-5'>板载</b>WS2812驱动示例

    CW32L012/F030X1智能小车——超声波模块配置

    SR04超声波模块是一款广泛应用的测距传感器,主要用于使用超声波测量物体与传感器之间的距离。它是一个成本低廉、精度较高且易于使用的传感器,常用于机器人、智能家居、无人机、汽车防撞系统等项目。
    的头像 发表于 01-05 16:54 3169次阅读
    <b class='flag-5'>CW32L012</b>/<b class='flag-5'>F030</b><b class='flag-5'>灵</b><b class='flag-5'>眸</b><b class='flag-5'>X1</b><b class='flag-5'>智能</b><b class='flag-5'>小车</b>——超声波模块配置

    CW32L012/F030X1智能小车——使用NRF24L01通信

    NRF24L01所使用的通讯协议为SPI,SPI又可分为软件SPI和硬件SPI。
    的头像 发表于 04-01 16:49 2628次阅读
    <b class='flag-5'>CW32L012</b>/<b class='flag-5'>F030</b><b class='flag-5'>灵</b><b class='flag-5'>眸</b><b class='flag-5'>X1</b><b class='flag-5'>智能</b><b class='flag-5'>小车</b>——使用NRF24<b class='flag-5'>L</b>01通信

    CW32L012/F030X1智能小车——使用蓝牙模块通讯

    主控板配套的是一款低功耗蓝牙模块,适用于短距离无线通信。该模块通常被用于各种嵌入式项目,如物联网(IoT)设备、手机配件、智能家居设备、医疗设备等。
    的头像 发表于 04-01 16:54 3419次阅读
    <b class='flag-5'>CW32L012</b>/<b class='flag-5'>F030</b><b class='flag-5'>灵</b><b class='flag-5'>眸</b><b class='flag-5'>X1</b><b class='flag-5'>智能</b><b class='flag-5'>小车</b>——使用蓝牙模块通讯

    坚持继续布局32位MCU,进一步完善产品阵容,96Mhz主频CW32L012新品发布!

    基于CW32L01x系列低功耗微控制器家族的全新成员:CW32L012系列产品。 CW32L012基于ARM® Cortex-M0+内核,主频高达96MHz,同时集成了CORDIC硬件单元、扩展算术运算单元
    发表于 07-16 16:32

    **CW32L012****开发评估板的第一个程序**

    CW32L012****开发评估板的第一个程序 最近以15.99在CW32生态社区入手了这块CW32L012开发评估板,我迫不及待的烧录进电
    发表于 11-22 00:09

    CW32L012小型机器人控制评估板活动 四足机器人+智能小车 开箱评测

    CW32L012活动相关资料链接:https://dwi41yhz703.feishu.cn/wiki/B1Ihw31ebiX0vkkhQr2cINnkn1g 小型机器人+智能小车
    发表于 11-24 23:44

    CW32F030CxTx StartKit用户使用手册

    VBUS 供电,3.3V 供电(LD1117AS33TR),外接 1.65V ~ 5.5V 供电 •CW32F030-StdPeriph-Lib 软件包提供全面免费的固件库和例程 •支持多种集成开发环境,IAR ™,Keil®
    发表于 09-15 08:28

    CW32模块使用 红外接收模块

    静态电流3-5uA,动态电流3-5mA。 以上信息见厂家资料文件 三、移植过程 我们的目标是将例程移植至CW32F030C8T6开发板上【能够实现红外信号接收的功能】。首先要获取资料
    的头像 发表于 01-23 13:16 1170次阅读
    <b class='flag-5'>CW</b>32模块使用 <b class='flag-5'>红外接收</b>模块

    使用芯源CW32的CW32L012开发评估板做了spi屏幕驱动

    CW32生态社区以极高的性价比入手了这块CW32L012开发评估板,开发板以底板、核心板、1.77寸TFT显示屏构成,所有的IO口都引出了排针,这点好评,使用杜邦线可以非常方便的连接
    的头像 发表于 11-21 11:34 923次阅读
    使用芯源<b class='flag-5'>CW</b>32的<b class='flag-5'>CW32L012</b><b class='flag-5'>开发</b>评估板做了spi屏幕驱动

    CW32L012小机器人的电机控制

    线的大功率调速,电机的控制性能直接决定了系统的响应速度、运行精度、能耗效率与稳定性。这里分享CW32L012小机器人的正反转、调速的电机控制 电机的正反转 从配套的开发板资料介绍中可以知道,这是电机的驱动芯片RZ7899 从立创商城下载该芯片的数据
    的头像 发表于 11-21 13:18 2639次阅读
    <b class='flag-5'>CW32L012</b>小机器人的电机控制

    CW32L012与STM32F103的三角运算性能对比

    没有硬件浮点运算单元。 但在运算三角函数时,CW32L012支持CORDIC算法。 二、 三角运算性能具体分析 1:标准库浮点运算(如 math.h 的 sinf, cosf) 这是最常用但也是最慢的方式。 STM32F103C
    的头像 发表于 12-29 15:32 2621次阅读
    <b class='flag-5'>CW32L012</b>与STM32<b class='flag-5'>F</b>103的三角运算性能对比

    CW32L012与STM32G431的CORDIC三角函数运算性能对比

    CORDIC协处理器的三角运算性能对比。对比结果出乎意料。 一、硬件架构 二、运算100W次SIN30度与COS30度的代码实现 1.CW32L012 CW32L012的CORDIC提供某些数学函数
    的头像 发表于 12-29 15:55 2935次阅读
    <b class='flag-5'>CW32L012</b>与STM32G431的CORDIC三角函数运算性能对比

    CW32L012/F030X1智能小车--电机正反转控制

    RZ7899是一种高性能电机驱动芯片,广泛应用于各种电机控制场合,特别是在步进电机和直流电机的驱动中。
    的头像 发表于 04-02 16:48 1199次阅读
    <b class='flag-5'>CW32L012</b>/<b class='flag-5'>F030</b><b class='flag-5'>灵</b><b class='flag-5'>眸</b><b class='flag-5'>X1</b><b class='flag-5'>智能</b><b class='flag-5'>小车</b>--电机正反转控制

    CW32L012/F030X1智能小车--电机调速控制

    PWM(Pulse Width Modulation脉宽调制)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号任然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有,要么完全无。比如我们的电压输出是5v的,那么经过改变PWM的占空比,可以达到在一定时间内输出3.3V或者1.3V的效果
    的头像 发表于 04-02 16:49 1349次阅读
    <b class='flag-5'>CW32L012</b>/<b class='flag-5'>F030</b><b class='flag-5'>灵</b><b class='flag-5'>眸</b><b class='flag-5'>X1</b><b class='flag-5'>智能</b><b class='flag-5'>小车</b>--电机调速控制