MM32L0136 接收 CEM5826 数据并绘制图像

分享作者:Mr_Fang
作者昵称:Mr_Fang
评测品牌:灵动微电子
评测型号:MM32EVBL0136
发布时间:2025-11-17 15:03:03
0
概要
串口接收 CEM5826-M11 毫米波雷达数据,在 OLED 屏幕上绘制速度折线图并根据速度数据判断人体靠近或远离状态
开源口碑分享内容

串口接收 CEM5826-M11 毫米波雷达数据,在 OLED 屏幕上绘制速度折线图并根据速度数据判断人体靠近或远离状态

接线图

开发环境配置

开发环境配置方法可参考MM32:配置开发环境和点亮第一颗LED

程序编写

本项目自 STM32 项目移植而来

串口接收程序 usart.c

需要特别注意的:MM32中串口相关均为UART,这与STM32的USART不同!

void uart_init(u32 bound)

初始化串口1

void uart_init(u32 bound){
    // 初始化结构体
    GPIO_InitTypeDef GPIO_InitStructure;
    UART_InitTypeDef UART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    // 启用串口1的RCC时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_UART1, ENABLE);

    // 初始化串口
    // 按照CEM5826的文档设置串口:波特率115200,8位数据位,1位停止位,校验位和流控为None
    UART_StructInit(&UART_InitStructure);
    UART_InitStructure.BaudRate = bound;
    UART_InitStructure.WordLength = UART_WordLength_8b;    
    UART_InitStructure.StopBits = UART_StopBits_1;
    UART_InitStructure.Parity = UART_Parity_No;
    UART_InitStructure.HWFlowControl = UART_HWFlowControl_None;
    UART_InitStructure.Mode = UART_Mode_Rx | UART_Mode_Tx;

    UART_Init(UART1, &UART_InitStructure);

    // 启用GPIOA的RCC时钟
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);

    //UART1_TX   PA9
    GPIO_StructInit(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_High;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    //UART1_RX      PA10
    GPIO_StructInit(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);  

    // 抢占优先级
    NVIC_InitStructure.NVIC_IRQChannel = UART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0x01;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    UART_ITConfig(UART1, UART_IT_RX, ENABLE);
    UART_Cmd(UART1, ENABLE);

}

void UART1_IRQHandler(void)

接收数据,将数据缓存在 USART_RX_BUF

void UART1_IRQHandler(void)
{
    u8 Res;
    if(UART_GetITStatus(UART1, UART_IT_RX) != RESET)
    {
        Res = UART_ReceiveData(UART1);

        if((USART_RX_STA & 0x8000) == 0)
        {
            if(USART_RX_STA & 0x4000)
            {
                if(Res != 0x0a) USART_RX_STA = 0;
                else USART_RX_STA |= 0x8000;
            }
            else
            {    
                if(Res == 0x0d) USART_RX_STA |= 0x4000;
                else
                {
                    USART_RX_BUF[USART_RX_STA & 0X3FFF] = Res ;
                    USART_RX_STA++;
                    if(USART_RX_STA > (USART_REC_LEN - 1)) USART_RX_STA = 0;
                }         
            }
        }
    }
}

SPI OLED 库 oled.c

void OLED_Init(void)

OLED 初始化

void OLED_Init(void)
{
    // 初始化结构体
    GPIO_InitTypeDef  GPIO_InitStructure;

    // 启用RCC时钟
     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

    // 启用GPIO口,推挽输出模式、高速
    // PB10 ---- SCL
    // PB11 ---- SDA
    // PB7  ---- RES
    // PB8  ---- DC
    // PB9  ---- CS
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_High;
     GPIO_Init(GPIOB, &GPIO_InitStructure);
     GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9);

    // ...
    // OLED 初始化命令
    // ...
}

主程序 main.c

void main(void)

int main(void)
{
    // 初始化
    int i = 0, j = 0, str;
    float v, vData[20];
    char temp[USART_REC_LEN], showStr[20];

    delay_init();
    uart_init(115200);
    OLED_Init();

    OLED_Coloiurn(0);       // 关闭反色显示(0-正常, 1-反色)
    OLED_DisplayTurn(0);    // 关闭翻转显示(0-正常, 1-翻转)

    // 显示 iCEasy LOGO
    OLED_ShowPicture(0, 0, 128, 64, BMP1, 1);
    OLED_Refresh();
    delay_ms(500);

    OLED_Clear();

    while(1)
    {
        // 将串口收到的数据缓存到 temp
        if(USART_RX_STA != 0)
        {
            for(i = 0; i < USART_REC_LEN; i++)
                temp[i] = USART_RX_BUF[i];
        }

        // 从收到的数据中提取速度和强度
        sscanf(temp, "v=%f km/h, str=%d", &v, &str);

        // 将速度存入数组
        vData[j] = v;

        // 画图
        if(j > 0)
            OLED_DrawLine((j - 1) * 6, 40 - (vData[j - 1]*5) / 2, j * 6, 40 - (vData[j]*5) / 2, 1);

        // 在 OLED 上显示字符串
        sprintf(showStr, "v=%.1fkm/h, t=%.1fs ", vData[j], 0.1*j);

        OLED_ShowString(2, 0, showStr, 8, 1);

        // 判断远离或靠近
        if(v > 0)
        {
            OLED_ShowChinese(92,46,0,16,1);
            OLED_ShowChinese(108,46,1,16,1);
        }
        else
        {
            OLED_ShowChinese(92,46,2,16,1);
            OLED_ShowChinese(108,46,3,16,1);
        }

        OLED_Refresh();

        // 恢复继续接收串口数据
        USART_RX_STA = 0;
        for(i = 0; i < USART_REC_LEN; i++)
            USART_RX_BUF[i] = 0;

        delay_ms(100);
        if(j++ == 20){ j = 0; OLED_Clear(); }

    }
}

一些图片

资源下载

⟱ 程序

MM32EVBL0136_CEM5826.zip

⟱ 出厂固件

MM32EVBL0136.hex


全部评论
暂无评论
0/144