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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值