zoukankan      html  css  js  c++  java
  • HAL库_串口接收/发送_阻塞+中断

    标准库中打开串口的函数:

    USART_Cmd(USART1, ENABLE);

    标准库中打开中断的函数:需要单独设置被打开的中断的类型

    USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);    

    在HAL中,打开串口和中断合并成了一个函数:发送就打开发送中断,接收就打开接收中断

    HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
    
    HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

    标准库和HAL库中都有阻塞式发送接收和非阻塞式发送接收(中断或DMA)

    标准库中阻塞式发送和接收函数

    void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
    uint16_t USART_ReceiveData(USART_TypeDef* USARTx)

    HAL库中阻塞式发送和接收

    HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
    
    HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

    阻塞式发送和接收在使用上都没有太大的差别,发送就等着发送完,HAL中阻塞式发送函数的第4个参数Timeout,可以设置一个超时时间,超时后没发完就不再阻塞。

    接收没有差别。超时时间根据systic的计数频率和计数值确定

    中断式发送和接收

    先说接收

    标准库中接收的话需要自己在中断函数里面判断中断类型,清标志位

    在HAL中void HAL_UART_IRQHandler(UART_HandleTypeDef *huart);这个库函数帮我们完成了中断类型判断和清除标志位,我们只需要在具体的函数中写逻辑即可。

    上面这个库函数判断出不同的类型,然后调用不同的回调函数,我们处理接收中断回调函数HAL_UART_TxCpltCallback即可。

    全部回调函数如下:

    1 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);
    2 void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);
    3 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
    4 void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);
    5 void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);
    6 void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart);
    7 void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart);
    8 void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart);

    发送和接收中断的一些问题:

    HAL_UART_Transmit_IT(huart11,datass,2 ); 
    HAL_UART_Receive_IT(&huart1,recivedatass,3);

    关于中断式发送和接收,可以看到这两个函数的第3个参数,是设置要接收多少个、发送多少个字节。发送的中断就不用说了,有个全部发送完成和发送一半。

    接收的话,每接收到一个字节就会产生一个接收中断,但是我们可能需要接收完3个字节的数据才想处理一次。HAL_UART_IRQHandler内部做了判断,当接收到3个字节后才会调用一个回调函数 HAL_UART_RxCpltCallback

    实验:使用串口中断每接收到3个字节后,在中断回调函数中使用串口中断式发送2个字节的字符串“TR”,当发送完成后,在发送完成中断中翻转LED。

    main.c :打开串口并开启接收中断

        uint8_t datass[100] ="TR";
        uint8_t recivedatass[100]="";

     HAL_UART_Receive_IT(&huart1,recivedatass,3);
     
     HAL_Delay(2000);

    接收中断回调函数

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart11)
    {
        HAL_UART_Transmit_IT(huart11,datass,2 );
     
        HAL_UART_Receive_IT(&huart1,recivedatass,3);//再次打开接收中断,以便下次继续接收
    }

    发送完成中断回调函数

    void HAL_UART_TxCpltCallback(UART_HandleTypeDef* huart11)
    {
        
        HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);
        HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
        //HAL_UART_Transmit_IT(&huart1,datass,2);
    }

    遇到的问题:

    接到几次就会卡死,后来发现是HAL_UART_IRQHandler函数内部每接收到一个字节就会关闭接收中断,如果我们还要继续接收,则需要在接收中断回调函数中打开接收中断。

    而在发送完成中断中不用打开发送中断。打开了会死循环发送。

    CUbeMx配置串口

     

  • 相关阅读:
    excel经典图表
    excel数据透视表
    excel常用快捷键和技巧
    excel常用公式--时间序列类
    excel常用公式--计算统计类
    excel常用公式--逻辑运算类
    excel常用公式--关联匹配类
    FileWriter字符输出流和FileReader字符输出流
    FileOutputStream字节输出流和FileInputStream输入流(切记:out是输出到本地中,in是输入到程序中)这里介绍大文件和小文件的读取方式
    DataInputStream(二进制输入流)和DataOutputStream二进制输出流(注意:in是从本地文件输入到程序中,out是从程序输出到本地种)
  • 原文地址:https://www.cnblogs.com/1024E/p/13347732.html
Copyright © 2011-2022 走看看