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配置串口

     

  • 相关阅读:
    微信JS SDK Demo
    微信JS SDK使用权限签名算法
    微信JS接口
    微信分享JS接口失效说明及解决方案
    微信支付开发(2) 扫码支付模式一
    不懂技术的人不要对懂技术的人说这很容易实现
    独立开发者经验分享
    微信公开课PRO版张小龙演讲全文
    RC4加密算法的原理及实现
    上传APP加入视频预览--精简点名
  • 原文地址:https://www.cnblogs.com/1024E/p/13347732.html
Copyright © 2011-2022 走看看