3、添加HAL库UART DMA 发送函数代码
(1)STM32 HAL函数库的串口DMA相关函数如下:
- HAL_UART_Transmit();串口发送数据,使用超时管理机制
- HAL_UART_Receive();串口接收数据,使用超时管理机制
- HAL_UART_Transmit_IT();串口中断模式发送
- HAL_UART_Receive_IT();串口中断模式接收
- HAL_UART_Transmit_DMA();串口DMA模式发送
- HAL_UART_Transmit_DMA();串口DMA模式接收
- HAL_UART_DMAPause() 暂停串口DMA
- HAL_UART_DMAResume(); 恢复串口DMA
- HAL_UART_DMAStop(); 结束串口DMA
复制代码
(2)添加串口DMA发送log代码:
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
- HAL_Delay(500);
- HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);//控制LED1闪烁
- HAL_UART_Transmit_DMA(&huart1, (uint8_t *)"hello world,this is usart dma send and receive...\r\n", sizeof("hello world,this is usart dma send and receive...\r\n"));//发送提示
- }
- /* USER CODE END 3 */
复制代码
4、添加HAL库UART DMA 接收函数代码
(1)DMA接收设置前铺垫知识点:
STM32的IDLE的中断产生条件:在串口无数据接收的情况下,不会产生,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一但接收的数据断流,没有接收到数据,即产生IDLE中断停止。
(2)初始化中断接收配置:
uart.c添加代码如下:
- /* USER CODE BEGIN 0 */
- volatile uint8_t rx_len=0; //接收一帧数据的长度
- volatile uint8_t recv_end_flag; //接收一帧数据结束的标志位
- uint8_t rx_buffer[100]={0}; //接收一帧数据的数组大小
- /* USER CODE END 0 */
复制代码
- /* USART1 init function */
- void MX_USART1_UART_Init(void)
- {
- huart1.Instance = USART1;
- huart1.Init.BaudRate = 115200;
- huart1.Init.WordLength = UART_WORDLENGTH_8B;
- huart1.Init.StopBits = UART_STOPBITS_1;
- huart1.Init.Parity = UART_PARITY_NONE;
- huart1.Init.Mode = UART_MODE_TX_RX;
- huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
- huart1.Init.OverSampling = UART_OVERSAMPLING_16;
- huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
- huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
- if (HAL_UART_Init(&huart1) != HAL_OK)
- {
- Error_Handler();
- }
- /* USER CODE BEGIN 2 */
- __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中断
- HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE); //DMA接收函数
- /* USER CODE END 2 */
- }
复制代码
uart.h添加代码如下:
- /* USER CODE BEGIN Private defines */
- extern UART_HandleTypeDef huart1;
- extern DMA_HandleTypeDef hdma_usart1_rx;
- extern DMA_HandleTypeDef hdma_usart1_tx;
- #define BUFFER_SIZE 100
- extern volatile uint8_t rx_len ; //接收数据的长度
- extern volatile uint8_t recv_end_flag; //接收数据完成标志位
- extern uint8_t rx_buffer[100]; //接收数据存放数组
- /* USER CODE END Private defines */
复制代码
main.c添加代码如下:
- /* Private includes ----------------------------------------------------------*/
- /* USER CODE BEGIN Includes */
- #include<string.h> //添加字符串头文件
- /* USER CODE END Includes */
- /* USER CODE BEGIN 0 */
- /*******************************************
- *函数名:DMA_Usart_Send
- *功能说明: 串口发送功能函数
- *形 参: buf,len
- *返 回 值: 无
- ********************************************/
- void DMA_Usart_Send(uint8_t *buf,uint8_t len)
- {
- if(HAL_UART_Transmit_DMA(&huart1, buf,len)!= HAL_OK) //判断是否发送正常,如果出现异常则进入异常中断函数
- {
- Error_Handler(); //异常提醒
- }
- }
- /*******************************************
- * 函 数 名: DMA_Usart1_Read
- * 功能说明: 串口接收功能函数
- * 形 参: Data,len
- * 返 回 值: 无
- ********************************************/
- void DMA_Usart1_Read(uint8_t *Data,uint8_t len)
- {
- HAL_UART_Receive_DMA(&huart1,Data,len); //重新打开DMA接收
- }
- /* USER CODE END 0 */
复制代码
main.c while(1)循环中添加代码如下:
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
- if(recv_end_flag == 1) //接收完成标志,如果串口有数据接收,则执行该部分
- {
- DMA_Usart_Send(rx_buffer, rx_len);
- HAL_Delay(200);
- DMA_Usart_Send((uint8_t *)"\r\n", sizeof((uint8_t *)"\r\n"));
- rx_len = 0; //清除计数
- recv_end_flag = 0; //清除接收结束标志位
- memset(rx_buffer,0,rx_len);
- }
- else //如果外部没有数据,则执行该部分
- {
- HAL_UART_Transmit_DMA(&huart1, (uint8_t *)"hello world,this is usart dma send and receive...\r\n", sizeof("hello world,this is usart dma send and receive...\r\n"));
- HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0); //控制LED1闪烁
- HAL_Delay(500);
- }
- HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE); //重新打开DMA接收
- }
- /* USER CODE END 3 */
复制代码
stm32f1xx_it.c中添加代码如下:
- /* Private typedef -----------------------------------------------------------*/
- /* USER CODE BEGIN TD */
- #include "usart.h"
- /* USER CODE END TD */
- /**
- * @brief This function handles USART1 global interrupt.
- */
- void USART1_IRQHandler(void)
- {
- /* USER CODE BEGIN USART1_IRQn 0 */
- uint32_t tmp_flag = 0;
- uint32_t temp;
- tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位
- if((tmp_flag != RESET)) //idle标志被置位
- {
- __HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除标志位
- HAL_UART_DMAStop(&huart1);
- temp = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx); // 获取DMA中未传输的数据个数
- rx_len = BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
- recv_end_flag = 1; // 接受完成标志位置1
- }
- /* USER CODE END USART1_IRQn 0 */
- HAL_UART_IRQHandler(&huart1);
- /* USER CODE BEGIN USART1_IRQn 1 */
- /* USER CODE END USART1_IRQn 1 */
- }
复制代码
(3)至此,串口DMA收发数据需要添加的代码已经完成。
5、设置编程仿真下载模式
(1)选择Options for target ...>>Debug>>J-Link/J-JTRACE Cortex,点击Settings>>选择Port(SW),可以看到搜索成功SW Device,表示芯片可用,可以下载。
|