芯查查logo
  • 数据服务
    1. 新产品
    2. 物料选型
    3. 查替代
    4. 丝印反查
    5. 查品牌
    6. PCN/PDN
    7. 查方案
    8. 查代理
    9. 数据合作
  • SaaS/方案
      SaaS产品
    1. 供应链波动监控
    2. 半导体产业链地图
    3. BOM管理
    4. 解决方案
    5. 汽车电子
    6. 政府机构
    7. 数据API
  • 商城
  • 行业资讯
    1. 资讯
    2. 直播
  • 论坛社区
    1. 论坛
    2. 学习
    3. 测评中心
    4. 活动中心
    5. 积分商城
  • 查一下
  • 开通会员
阿方
创作者认证
萤火工场CEM5861G-M11 使用RA6E2监测人体存在

本次点灯使用 RA 生态工作室的 RA-Eco-RA6E2 开发板

Demo e² Studio 项目可以在附件找到

RA-Eco-RA6E2-64PIN-V1.0实物图.jpg


目标

利用 CEM5861G-M11 毫米波雷达检测人体存在,实现:
目标存在点亮 LED2,目标移动点亮 LED1

系统框图

系统框图png

如何准确接收串口数据?

CEM5861G 在上电后会源源不断向上位机发送数据,我们需要用一种方式准确读取串口数据

QQ2025718-215539-HD.gif.jpg

我使用了状态机实现对数据帧的同步

首先,我定义了枚举变量 uart_rx_state_t,其中有三个状态

  • STATE_FIND_HEAD1 正在寻找帧头第一位 0x55
  • STATE_FIND_HEAD2 正在寻找帧头第二位 0xA5
  • STATE_RECV_PAYLOAD 正在接收剩余数据
typedef enum
{
    STATE_FIND_HEAD1   = 0,   // 找帧头第一位 0x55
    STATE_FIND_HEAD2   = 1,   // 找帧头第二位 0xA5
    STATE_RECV_PAYLOAD = 2    // 接收剩余数据
} uart_rx_state_t;

可以画出状态转移图:
图片3 (2).png

将它写为代码:

void hal_entry(void)
{
    /* TODO: add your own code here */
    uint32_t idx = 0;

    UART9_Init();
    R_IOPORT_Open(&g_ioport_ctrl, g_ioport.p_cfg);

    printf("Hello, CEM5861G!\r\n");

    R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_13, BSP_IO_LEVEL_LOW);
    R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_07, BSP_IO_LEVEL_LOW);

    while (1)
    {
        switch (cem_state)
        {
            case STATE_FIND_HEAD1:    // 找第帧头第一位 0x55
            {
                if (R_SCI_UART_Read(&g_uart9_ctrl, &cem_rx_byte, 1) == FSP_SUCCESS)
                {
                    if (cem_rx_byte == 0x55)
                        cem_state = STATE_FIND_HEAD2;
                }
                break;
            }
            case STATE_FIND_HEAD2:    //找第帧头第二位 0xA5
            {
                if (R_SCI_UART_Read(&g_uart9_ctrl, &cem_rx_byte, 1) == FSP_SUCCESS)
                {
                    if (cem_rx_byte == 0xA5)       // 帧头 OK,接下来接收余下 16 字节
                    {
                        cem_frame[0] = 0x55;
                        cem_frame[1] = 0xA5;
                        idx = 2;
                        cem_state = STATE_RECV_PAYLOAD;
                    }
                    else if (cem_rx_byte == 0x55)  // 还是 0x55,继续找 0xA5
                    {
                        ;
                    }
                    else                           // 异常,重新找 0x55
                    {
                        cem_state = STATE_FIND_HEAD1;
                    }
                }
                break;
            }
            case STATE_RECV_PAYLOAD:  // 接收剩余 16 字节完成一帧
            {
                fsp_err_t err = uart_read_exact(&cem_frame[idx], CEM_FRAME_LEN - idx);
                if (err != FSP_SUCCESS)  //读取出错,重新开始
                {
                    cem_state = STATE_FIND_HEAD1;
                    break;
                }

                // 开始校验
                uint8_t sum = 0;
                for (uint32_t i = 0; i < CEM_FRAME_LEN - 1; i++)  
                    sum += cem_frame[i];
                sum &= 0xFF;

                if (sum != cem_frame[CEM_FRAME_LEN - 1])  // 校验失败,丢掉这一帧
                {
                    // 校验失败,丢掉这一帧
                    printf("Checksum Error: sum=%02X, frame[17]=%02X\r\n", sum, cem_frame[CEM_FRAME_LEN - 1]);
                    cem_state = STATE_FIND_HEAD1;  
                    break;
                }

                // 校验通过,使用第 9 个数据字节 DATA[1] 做控制
                uint8_t data1 = cem_frame[3 + 5];

                // P113[LED2]: 目标存在否
                if (data1 == 0x00)       // 目标不存在 - 灭
                    R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_13, BSP_IO_LEVEL_LOW);
                else                     // 目标存在   - 亮
                    R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_13, BSP_IO_LEVEL_HIGH);

                // P207[LED1]: 目标状态
                if (data1 == 0x01)       // 目标移动   - 亮
                    R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_07, BSP_IO_LEVEL_HIGH);
                else if (data1 == 0x02)  // 目标存在   - 灭
                    R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_07, BSP_IO_LEVEL_LOW);

                // 输出数据帧
                for (int i = 0; i < CEM_FRAME_LEN; i++)
                    printf("%02X ", cem_frame[i]);
                printf("\r\n");

                cem_state = STATE_FIND_HEAD1;
                break;
            }
        }
    }

#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif
}

更好的读取串口数据

为了更好的读取串口数据,这里使用阻塞读取来实现读取指定长度的数据

fsp_err_t uart_read_exact(uint8_t *buf, uint32_t len)
{
    uint32_t got = 0;
    while (got < len)
    {
        fsp_err_t err = R_SCI_UART_Read(&g_uart9_ctrl, &buf[got], len - got);
        if (err != FSP_SUCCESS)
            return err;
        got += (len - got);
    }
    return FSP_SUCCESS;
}

看看效果

358701632cdd46cd337f95f2abb6073c (1) - 副本.gif.png

视频

详细可查看本视频:
https://www.bilibili.com/video/BV1Zpunz8Ea9/

工程附件
CEM5861G_Demo.zip
CEM5826-M11
版块: 萤火工场
2025/07/18 23:20
  • 举报
😁😂😃😄😅😆😉😊😋😌😍😏😒😓😔😖😘😚😜😝😞😠😡😢😣😤😥😨😩😪😫😭😰😱😲😳😵😷😸😹😺😻😼😽😾😿🙀🙅🙆🙇🙈🙉🙊🙋🙌🙍🙎🙏✂✅✈✉✊✋✌✏✒✔✖✨✳✴❄❇❌❎❓❔❕❗❤➕➖➗➡➰🚀🚃🚄🚅🚇🚉🚌🚏🚑🚒🚓🚕🚗🚙🚚🚢🚤🚥🚧🚨🚩🚪🚫🚬🚭🚲🚶🚹🚺🚻🚼🚽🚾🛀Ⓜ🅰🅱🅾🅿🆎🆑🆒🆓🆔🆕
@好友

全部评论

加载中
游客登录通知
已选择 0 人
自定义圈子
移动
发布帖子
发布动态
发布问答
最新帖子
芯查查技术沙龙第4期—ADI智能音频解决方案分享完美落幕LDO串联或并联二极管有什么用?电路保护与特殊应用解析缝纫机伺服0.3秒启停稳如磐石:三招驯服“针位漂移”顽疾伺服电机过载预警:从电流纹波揪出轴承暗伤的猎杀方案芯片丝印反查求助
热门版块
查看更多
电子元器件
维修技术
问型号
问技术
问行情
麦博大学堂
汽车电子工程师论坛
工业电子专区
新手入门指南
单片机/MCU论坛

4

收藏

分享

微信扫码
分享给好友

评论