云计算百科
云计算领域专业知识百科平台

嵌入式之串口通信

提示:CubeMx实现串口通信、代码实现

文章目录

  • 一、CubeMx实现串口通信
  • 二、代码实现
    • 1.发送
    • 2.接受
  • 三、常用电平标准

提示:以下是本篇文章正文内容,下面案例可供参考

一、CubeMx实现串口通信

在这里插入图片描述

  • 波特率配置:常用115200、9600等 含义:115200 指的就是串口的波特率为 115200 bit/s,也就是理论上每秒可以传输 115200 个二进制位
  • 但是,实际通信,串口需要: 1位起始位 (低电平)+ 8位数据位 + 0/1位奇偶校验位(可有可无) + 1位停止位(高电平)

    1 个 Byte = 8 个 bit,在串口通信的常见配置(8 位数据位 + 1 位停止位 + 无校验)下,每传输 1 个字节的有效数据,实际需要发送 1(起始位)+8(数据位)+1(停止位)=10 bit。 按 115200 bit/s 计算,实际每秒能传输的有效字节数约为 115200 ÷ 10 = 11520 Byte/s,也就是约 11.25 KB/s。

  • 异步通信 串口只有两根线,tx、rx(交叉连接),无时钟线,通过波特率同步
  • 在这里插入图片描述 3. 中断 通过中断接收外部发送的消息,提高CPU的利用率。

    二、代码实现

    1.发送

    代码如下(示例):

    // 发送以'\\0'结尾的字符串,利用strlen计算长度
    uint8_t tx_str[] = "串口发送测试\\r\\n";
    // 发送字符串,超时时间100ms
    HAL_UART_Transmit(&huart1, tx_str, strlen((char*)tx_str), 100);

    // 简化写法(直接传字符串)
    HAL_UART_Transmit(&huart1, (uint8_t*)"Hello World!\\r\\n", 14, 100);
    // 注:"Hello World!\\r\\n" 共14个字节(含换行符),也可用strlen计算

    2.接受

    代码如下(示例):

    > 首先在main函数里初始化要开启串口空闲中断

    // 开启串口空闲中断接收(核心函数)
    HAL_UARTEx_ReceiveToIdle_IT(&huart1, uart_rx, 50);

    /**
    * @brief 串口空闲中断回调函数(仅保留LED控制解析)
    * @param huart: 串口句柄
    * @param Size: 实际接收字节数
    * @retval 无
    */

    void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
    {
    if(huart->Instance == USART1)
    {
    // 1. 保存接收数据长度
    uint16_t uart_rx_len = Size;
    // 2. 清空解析临时变量,避免残留
    char cmd_key[10] = {0}; // 指令关键字(如SET_LED)
    int led_state = 1; // LED状态参数
    char echo_buf[64] = {0}; // 回显缓存

    // 3. 核心:用sscanf解析串口数据
    // 格式:SET_LED:0/1 (控制LED)
    int ret1 = sscanf((char*)uart_rx_buf, "%9[^:]:%d", cmd_key, &led_state);

    // 4. 根据解析结果执行LED控制逻辑
    if(ret1 == 2) // 解析到“关键字:数字”格式(如SET_LED:1)
    {
    if(strcmp(cmd_key, "SET_LED") == 0)
    {
    // 执行LED控制逻辑
    if(led_state == 0)
    {
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
    sprintf(echo_buf, "[OK] LED已关闭\\r\\n");
    }
    else if(led_state == 1)
    {
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
    sprintf(echo_buf, "[OK] LED已打开\\r\\n");
    }
    else
    {
    sprintf(echo_buf, "[ERROR] LED参数错误(仅0/1)\\r\\n");
    }
    }
    else
    {
    sprintf(echo_buf, "[ERROR] 未知指令:%s\\r\\n", cmd_key);
    }
    }
    else // 解析失败(格式错误)
    {
    sprintf(echo_buf, "[ERROR] 指令格式错误!\\r\\n");
    sprintf(echo_buf + strlen(echo_buf), "支持格式:SET_LED:0/1\\r\\n");
    }

    // 5. 回显处理结果
    HAL_UART_Transmit(&huart1, (uint8_t*)echo_buf, strlen(echo_buf), 100);

    // 6. 清空缓冲区,重新开启空闲中断(关键)
    memset(uart_rx_buf, 0, UART_RX_BUF_SIZE);
    HAL_UARTEx_ReceiveToIdle_IT(&huart1, uart_rx_buf, UART_RX_BUF_SIZE);
    }
    }

    /**
    * @brief 串口错误回调函数
    * @retval 无
    */

    void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
    {
    if(huart->Instance == USART1)
    {
    memset(uart_rx_buf, 0, UART_RX_BUF_SIZE);
    HAL_UARTEx_ReceiveToIdle_IT(&huart1, uart_rx_buf, UART_RX_BUF_SIZE);
    HAL_UART_Transmit(&huart1, (uint8_t*)"[ERROR] 串口接收错误!\\r\\n", 24, 100);
    }
    }

    > 在串口回调函数还要开启串口空闲中断

    **

    sscanf (uart_rx,“%3s-%3s”,数组1, 数组2); 例如发送 123-456 123存进数组1 456存进数组2

    **

    三、常用电平标准

    在这里插入图片描述

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 嵌入式之串口通信
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!