基于STM32CUBEMX STM32F411CEY6TR单片机实现串口DMA的收发
基于STM32CUBEMX STM32F411CEY6TR单片机实现串口DMA的收发
利用stm32 cubemx生成基础工程,配置如下
1.配置文件存储位置,生成.c和.h文件
2.时钟配置,选择外部时钟,主频72MHz
3 串口配置和DMA配置
基于基础工程,增加一些处理
1.修改DMA初始化的位置,放于串口初始化后面
2.uart.c和uart.h的修改
1.uart.c 的修改
主要是重写了一个回调函数 USAR_UART_IDLECallback,新增一个函数处理接收到的数据
user_uart1_send()
/* USER CODE BEGIN 1 */
unsigned char uart1_getdata_flag = 0; //作为串口1收到数据的标志位
static unsigned char send_data[4] = {0xAA,0x55,0x0,0x0a};
void USAR_UART_IDLECallback(UART_HandleTypeDef *huart,uint8_t rxlen)
{
if(huart == &huart1) //判断是否为串口1产生中断
{
// HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_15);
memcpy(UART1_RX_Data,UART1_RX_BUF,rxlen); //将UART1_RX_BUF的数据复制到UART1_RX_Data中,最后两位是标志不是数据
uart1_getdata_flag = 1;
// HAL_UART_Transmit_DMA(&huart1, UART1_RX_BUF,rxlen);//将接收到的不定长数据发送到上位机
rxlen = 0;//清除数据长度计数
HAL_UART_Receive_DMA(&huart1,UART1_RX_BUF,UART1_RX_SIZE);//重新打开DMA接收
}
}
void user_uart1_send(void)
{
if(uart1_getdata_flag == 1)
{
uart1_getdata_flag = 0;
if(UART1_RX_Data[0] == 0x66)
{
if(UART1_RX_Data[5] == 0x01 || UART1_RX_Data[5] == 0x02)
{
send_data[2] = UART1_RX_Data[5];
HAL_UART_Transmit_DMA(&huart1, send_data,4);
}
}
}
}
/* USER CODE END 1 */
2.uart.h的修改
声明回调函数和发送函数,并将接收数据的数组外接出来
/* USER CODE BEGIN Private defines */
#define UART1_RX_SIZE 100
extern uint8_t UART1_RX_BUF[50]; //串口接收缓存
extern uint8_t UART1_RX_LEN; //接收到的数据量
extern uint8_t UART1_RX_Data[50]; //数据缓存
/* USER CODE END Private defines */
void MX_USART1_UART_Init(void);
void MX_USART2_UART_Init(void);
/* USER CODE BEGIN Prototypes */
void USAR_UART_IDLECallback(UART_HandleTypeDef *huart,uint8_t rxlen);
void user_uart1_send(void);
/* USER CODE END Prototypes */
3.USART1_IRQHandler()需要增加几行代码
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET))
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除空闲状态标志
HAL_UART_DMAStop(&huart1); //关闭DMA传输
UART1_RX_LEN = UART1_RX_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx); //计算接收到的数据长度
USAR_UART_IDLECallback(&huart1,UART1_RX_LEN); //调用回调函数
}
/* USER CODE END USART1_IRQn 1 */
}