侧边栏壁纸
    • 累计撰写 302 篇文章
    • 累计收到 527 条评论
    【5】基于STM32CubeMX-STM32串口数据收发
    我的学记|刘航宇的博客

    【5】基于STM32CubeMX-STM32串口数据收发

    刘航宇
    2022-01-21 / 2 评论 / 1,060 阅读 / 正在检测是否收录...

    目录

    串行接口相关知识点

    并行通信、串行通信的概念。
    单工、半双工、全双工的概念。
    异步串行通信:通信双方在没有同步时钟的前提下,将一个字符(包括特定的附加位)按位进行传输的通信方式。
    波特率:每秒钟传输的二进制位数,如9600bps。
    TTL电平<—->RS232:MAX3232 SP3232
    串口<———>USB接口:CH340 CP2012

    STM32芯片的串口UASRT功能十分强大,但对于日常编程而言,使用最多的还是异步串行通信。
    串口1:USART1_TX与PA9复用,USART1_RX与PA10复用。
    串口2:USART2_TX与PA2复用,USART2_RX与PA3复用。

    HAL库中串口发送的重要函数

    ////查询方式,阻塞式发送函数(初学者,推荐使用)   
    HAL_StatusTypeDef  HAL_UART_Transmit(UART_HandleTypeDef *huart,uint8_t *pData,uint16_t Size, uint32_t Timeout);
    
    参数1:huart,串口实例的指针。
    参数2:*pData,待发送数据缓冲区的指针。
    参数3:Size,待发送数据的字节数。
    参数4:Timeout,超时时间值。
    返回值:HAL_StatusTypeDef,函数执行状态。
    typedef enum
    {
      HAL_OK       = 0x00U,
      HAL_ERROR    = 0x01U,
      HAL_BUSY     = 0x02U,
      HAL_TIMEOUT  = 0x03U
    } HAL_StatusTypeDef;
    
    ////中断方式,非阻塞式发送函数
    HAL_StatusTypeDef  HAL_UART_Transmit_IT(UART_HandleTypeDef *huart,uint8_t *pData, uint16_t Size);
    参数1:huart,串口实例的指针。
    参数2:*pData,待发送数据缓冲区的指针。
    参数3:Size,待发送数据的字节数。
    返回值:HAL_StatusTypeDef,函数执行状态。
    
    ////串口发送完毕中断回调函数  
    void HAL_UART_TxCpltCallback(UART_HandleTypeDef  *huart);
    void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef  *huart)
    应用举例:使用非阻塞式的串口发送函数,将发送缓数组dat_Txd中的前5个数据发送到USART1,在数据发送完成后,翻转PB9引脚的输出电平。   
    //使用中断,非阻塞方式 
    HAL_UART_Transmit_IT(&huart1,  dat_Txd, 5);
    
    void HAL_UART_TxCpltCallback(UART_HandleTypeDef  *huart) 
    {         
        if(huart->Instance == USART1);         
        {             
            HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_9);    
        }
    }
    
     
    //使用查询,阻塞方式 
    HAL_UART_Transmit(&huart1,  dat_Txd, 5, 10000);
    HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_9);

    HAL库中串口接收的重要函数

    ////查询方式,阻塞式接收函数
         
    HAL_StatusTypeDef  HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData,  uint16_t Size, uint32_t Timeout);
    参数1:huart,串口实例的指针。
    参数2:*pData,数据接收据缓冲区的指针。
    参数3:Size,待接收数据的字节数。
    参数4:Timeout,超时时间值。
    返回值:HAL_StatusTypeDef,函数执行状态。
    
    非阻塞式接收函数(推荐使用)
    HAL_StatusTypeDef  HAL_UART_Receive_IT(UART_HandleTypeDef *huart,uint8_t *pData,uint16_t Size);
    参数1:huart,串口实例的指针。
    参数2:*pData,数据接收据缓冲区的指针。
    参数3:Size,待接收数据的字节数。
    返回值:HAL_StatusTypeDef,函数执行状态。
    
    ////串口接收完毕中断回调函数
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef  *huart);
    void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef  *huart);
    应用举例:使用非阻塞式的串口接收函数,接收USART1中的一个字节,将其保存在dat_Rxd变量中,在数据接收完成后,判断该字节,若为0x5A,则翻转PB8引脚的输出电平。
    //使用中断,非阻塞方式
    HAL_UART_Transmit_IT(&huart1,  &dat_Rxd, 1);
      
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef  *huart)    
    {        
        if(huart->Instance == USART1)    
        {       
            if(dat_Rxd == 0x5A)      
                HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);
        }
    }

    实训案例:上位机通过串口控制LED灯开关

    调试要点:

    在XMF07A或XMF07C开发板上,利用STM32CubeMX和Keil5协同开发,完成以下的功能:
    【1】开机后,向串口1发送“hello world!”。
    【2】串口1收到字节指令“0xA1”,打开LED1,发送“LED1 Open!”。
    【3】串口1收到字节指令“0xA2”,关闭LED1,发送“LED1 Closed!”。
    【4】在串口发送过程中,打开LED2作为发送数据指示灯。

    #define LED1_ON() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET)
    #define LED1_OFF() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET)
    #define LED2_ON() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET)
    #define LED2_OFF() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET)
    
    uint8_t Tx_str1[] = "hello world!\r\n";
    uint8_t Tx_str2[] = "LED1 Open!\r\n";
    uint8_t Tx_str3[] = "LED1 Closed!\r\n";
    uint8_t Rx_dat = 0;
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
        if(huart->Instance == USART1)
        {
            if(Rx_dat == 0xa1)
            {
                LED1_ON();
                
                LED2_ON();
            HAL_UART_Transmit(&huart1,Tx_str2,sizeof(Tx_str2),10000);
            LED2_OFF();
            HAL_UART_Receive_IT(&huart1,&Rx_dat,1);
            }
            else if(Rx_dat == 0xa2)
            {
            LED1_OFF();
                
            LED2_ON();
            HAL_UART_Transmit(&huart1,Tx_str3,sizeof(Tx_str3),10000);
            LED2_OFF();
            HAL_UART_Receive_IT(&huart1,&Rx_dat,1);
            }
        }
    }
    //在mian()函数中添加以下代码:
    LED2_ON();
    HAL_UART_Transmit(&huart1,Tx_str1,sizeof(Tx_str1),10000);    //向上位机发送“hello world!”
    LED2_OFF();
    HAL_UART_Receive_IT(&huart1,&Rx_dat,1);                      //启动串口1接收上位机1个字节
    18
    【6】基于STM32CubeMX-STM32定时器与串口综合训练
    « 上一篇 2022-01-23
    【4】基于STM32CubeMX-STM32定时器开发
    下一篇 » 2022-01-19

    评论 (2)

    取消
    1. 头像
      jason
      Windows 10 · Google Chrome

      b站视频上把最后一行代码用了sizeof(Rx_dat),所以注意定义“uint8_t Rx_dat = 0;”这个代码就不行,需要改成“uint8_t Rx_dat = 0x00;”因为需要发送8位数据,如用第一个就会报错(因为sizeof算出来对于1)

      回复
    2. 头像
      32
      Windows 10 · Google Chrome

      博主大大能分享一下串口调试工具吗谢谢了
      QQ

      回复