开发板:正点原子阿波罗
创建工程
使能USART
开启DMA
配置中断
以上配置好之后,点击生成工程
一、接收、发送指定长度数据
指定接收、发送的数据长度为1
定义一个接收缓冲区
char tx_buffer[10];
编写中断回调函数
当触发接收中断时,将接收到的数据通过DMA发送出去
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART1) {
//函数要使用DMA方式的
HAL_UART_Transmit_DMA(&huart1,tx_buffer,1);
}
}
当触发发送中断时,使用DMA接收一下
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART1) {
函数要使用DMA方式的
HAL_UART_Receive_DMA(&huart1,tx_buffer,1);
}
}
使能接收中断
在main.c中
编译、下载进去就能看到效果
二、接收、发送不定长度数据
接收不定长度时,需要判断USART什么时候为空闲状态,当触发空闲中断时,证明此时已经接收全部数据,需要
用到的函数有
HAL_UART_DMAStop(UART_HandleTypeDef *huart); //停止DMA传输
__HAL_DMA_GET_COUNTER(__HANDLE__); //得到DMA传输了多少数据
__HAL_UART_CLEAR_IDLEFLAG(__HANDLE__); //清除空闲标志
HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size); //使用DMA的方式发送
HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); //使用DMA的方式接收
使能空闲中断
在 MX_USART1_UART_Init() 函数中添加
/* USER CODE BEGIN USART1_Init 2 */
//使能空闲中断
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
/* USER CODE END USART1_Init 2 */
定义一个接收缓冲区
/* USER CODE BEGIN 0 */
#define RXSIZE 1024 /
uint8_t rx_buffer[RXSIZE] = {0};
uint16_t RxNum = 0;
/* USER CODE END 0 */
编写USART1中断
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
//判断空闲标志
if (__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) == SET) {
//清除空闲中断标志
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
//停止DMA
HAL_UART_DMAStop(&huart1);
//接收了多长的数据
RxNum = RXSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
//将接收到的数据再发送出去
HAL_UART_Transmit_DMA(&huart1,rx_buffer,RxNum);
}
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
编写中断回调函数
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART1) {
RxNum = 0;
//清空一个缓冲区
memset(rx_buffer,0,RXSIZE);
//使能接收
HAL_UART_Receive_DMA(&huart1,rx_buffer,RXSIZE);
}
}
使能接收中断
在main.c中
若是不添加这句则无法进入中断
编译、下载进去就能看到效果