本帖最后由 wind_west 于 2023-6-17 17:22 编辑

视频演示效果:



1、为红外解码启动定时器


当前选择的模块,是费了很大心思的,选择了一个十分好的模块,如图:
image.png
因为发射和接收模块,价格很好-9个十分(0.9元/个)。选好了模块,接下来就是使用定时器来驱动发射模块了。

当前配置了GPT定时器后,无法编译通过。单片机Flash不够报错,已经很久没有体验到单片机Flash不够而报错的感觉了。

forum.jpg

错误:

d:/renesas_e2_studio/setup_fsp_v3_2_0_e2s_v2021-07/toolchains/gcc_arm/9_2020q2/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/bin/ld.exe: oled12864.elf section .text' will not fit in region FLASH'
d:/renesas_e2_studio/setup_fsp_v3_2_0_e2s_v2021-07/toolchains/gcc_arm/9_2020q2/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/bin/ld.exe: region `FLASH' overflowed by 3364 bytes

修改代码,减少数组定义,解决掉编译错误。

1.1、查阅RTOS的手册中关于定时器的资料

forum.jpg

根据这里的意思,可以定位到GPT定时器中断。

forum.jpg

RTSO的手中,有章节介绍怎样配置GPT定时器,那就说明RTOS和GPT定时器外设不冲突。

forum.jpg

1.2、使用RTOS手册中的代码成功启用定时器

定时器配置:

forum.jpg

forum.jpg

代码启用定时器(没有采用PPT资料中的方式开启定时器):

//------------time0 -参数手册《e2_快速上手指南.pdf》

    g_timer.p_api->open(g_timer.p_ctrl, g_timer.p_cfg);
    g_timer.p_api->start(g_timer.p_ctrl);
   
   
   
    //定时器回调函数
    void gpt_callback(timer_callback_args_t *p_args) {
    (void)p_args;

    if(counterGptTime ==1){
        R_IOPORT_PinWrite (&g_ioport_ctrl, BSP_IO_PORT_01_PIN_04, BSP_IO_LEVEL_HIGH);///<点亮
    }else if(counterGptTime ==2){
        counterGptTime =0;
        R_IOPORT_PinWrite (&g_ioport_ctrl, BSP_IO_PORT_01_PIN_04, BSP_IO_LEVEL_LOW);///<熄灭
    }
    counterGptTime++;
}


2、解码数据
2.1、解码数据-1ms

修改GPT定时器的中断,通过在定时器中判断引脚电平的方式来解码红外数据。当前获取到的数据,异常。
空调26℃→

forum.jpg



重复解码,修改打印的次数:

forum.jpg

forum.jpg

forum.jpg

解码数据异常,查看示波器的采样波形:

forum.jpg



当前ms级的中断无法有效解码,优化方向:红外信号的检测任务需要微妙级别的定时器中断。


2.2、解码数据-10us

修改GPT定时器的中断的时间,中断间隔时间10us,抓取的数据如下:

forum.jpg

forum.jpg

现在对比开头的几行数据(前面4行),解码已经很准确,解码的时间误差在x*10us之内。


2.3、精确分析

1650us的高电平解码:在误差范围内。

forum.jpg

650us的高电平解码:在误差范围内。

forum.jpg

抓取比较长的数据,第37个长时间高电平脉冲:在误差范围内。

forum.jpg

比较典型的9ms低电平解码:在误差范围内。

forum.jpg

接下来可以根据红外信号解码的数据,还原红外信号的发送。

解码主要代码(当前的解码和发射都是使用同一个定时器,所以将定时器的周期修改为:26us -38KHZ):

void infraredKeyValueDetect(void)
{

    R_IOPORT_PinRead (&g_ioport_ctrl, BSP_IO_PORT_01_PIN_02, &infrared_data.p_port_value_port_102);
    infrared_data.counter++;
    if (infrared_data.p_port_value_port_102_last != infrared_data.p_port_value_port_102)
    { ///<电平如果发生翻转,记录高电平时间
        if (infrared_data.p_port_value_port_102 & BSP_IO_LEVEL_HIGH)
        { ///<上升沿时间
             if((infrared_data.data_index_low <148)&&(infrared_data.counter>1)){///<防止数组越界,26us的电平是异常电平
                 infrared_data.data_record_low[infrared_data.data_index_low++] = infrared_data.counter;
             }
            infrared_data.counter =0;
        }
        else
        { ///<下降沿时间
            if((infrared_data.data_index_hight <148)&&(infrared_data.counter>1)){
             infrared_data.data_record_hight[infrared_data.data_index_hight++] = infrared_data.counter;
            }
            infrared_data.counter =0;
        }
    }
    infrared_data.p_port_value_port_102_last = infrared_data.p_port_value_port_102;                    ///<保留上一次的GPIO电平值
    ///<任务每一次循环:间隔时间26us ->函数放在定时器回调函数!
    if(infrared_data.counter > 1923){///<50ms秒钟空闲
        infrared_data.counter =0;
    }
}

3、MCU还原遥控器信号

红外发送有问题的原因,在红外发送二极管上不能检测到波形,原因:runStatus变量为bool型,没有进入下面的逻辑。

forum.jpg

现在改为static int8_t runStatus = 0;,示波器能够检测到波形,如图:

forum.jpg

但是程序运行会卡死,在RTOS中加大了相关任务的堆栈。

在红外发射引脚上,示波器能够抓取到,波形的起始位置有一个大概9ms的低电平,如图:

forum.jpg

分析:波形反过来。

修改后,抓取要发送的信号进行比对:解码的信号和还原的信号,在波形时间上没有明显差异。


forum.jpg


但是还原出来的信号和遥控器的信号还是有差异。

还原的信号和原始信号对比:还原出来的信号和遥控器的信号,在空闲的时候,还是有差异。

还原信号:

forum.jpg

初始信号:

forum.jpg

修改解码逻辑-将空闲状态取消,还原信号如下:

forum.jpg

小结:当前只能确保红外发射管上的波形,接收管上的波形后面再确认。


相关链接:
【瑞萨 RA2E1】+ 点亮LED(1)
【瑞萨 RA2E1】+ 硬件IIC驱动LCD和LM75温度传感器(2)
【瑞萨 RA2E1】+ 基于U8G2显示菜单(3)
【瑞萨 RA2E1】+ 红外解码(4)
【瑞萨 RA2E1】+ 红外发射(5)
【瑞萨 RA2E1】+ 空调控制项目-总结帖(6)