目录
功能说明:USART1和USART3启动中断收发并开启DMA,实现二者之间的互传数据。
一、STM32CubeMX下的图形化配置
本文以STM32F103ZET6为例。
1、配置调试下载接口、时钟源接口
![](https://i-blog.csdnimg.cn/blog_migrate/0ba9f3025a72717f0fa5bb9b7b6be519.png)
![](https://i-blog.csdnimg.cn/blog_migrate/22eb62d791f424e4402c06d970a6c2a4.png)
2、配置串口外设
如图配置USART1(USART3外设一样,没区别)
![](https://i-blog.csdnimg.cn/blog_migrate/eeaaf05176b4204b277dd8bd64fbbffb.png)
![](https://i-blog.csdnimg.cn/blog_migrate/e974f894de63603eacc4447f266dd403.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b7fb6dbc03ea778323009c25ae73c9f2.png)
3、配置时钟树
![](https://i-blog.csdnimg.cn/blog_migrate/3efc07bd508f2a5a676c74e6c308702b.png)
4、工程基本设置
![](https://i-blog.csdnimg.cn/blog_migrate/43360a89ac3a6953f84dee2fcbeab850.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ccecdf9e0923da6a59ceb38fa36e755e.png)
5、生成代码工程
二、Keil下的代码编辑
1、编辑usart.c文件
在USART1的初始化函数中加入如下两行代码(USRT3同理,注意参数的改变)
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
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;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //enable IDLE interrupt
HAL_UART_Receive_DMA(&huart1, pc_buffer, pc_buffer_len); //enable interrupt receive once
/* USER CODE END USART1_Init 2 */
}
其中的用户变量:pc_buffer_len为宏定义1024;pc_buffer为uint8_t类型的数组,数组长度为pc_buffer_len。
2、编辑stm32f1xx_it.c文件
在USART1和USART3的中断函数中加入用户功能代码
/**
* @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)) != RESET)
{
// Pause DMA transport
HAL_UART_DMAStop(&huart1);
// Calculate the number of received data
uint8_t rx_valid_len = pc_buffer_len - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
// Process data
while(HAL_UART_Transmit_DMA(&huart3, pc_buffer, rx_valid_len) == HAL_BUSY){}
// Next time DMA receive
__HAL_UART_CLEAR_IDLEFLAG(&huart1); // clear the IDLE flag
HAL_UART_Receive_DMA(&huart1, pc_buffer, pc_buffer_len);
}
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
/**
* @brief This function handles USART3 global interrupt.
*/
void USART3_IRQHandler(void)
{
/* USER CODE BEGIN USART3_IRQn 0 */
if((__HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE)) != RESET)
{
// Pause DMA transport
HAL_UART_DMAStop(&huart3);
// Calculate the number of received data
uint8_t rx_valid_len = ins_buffer_len - __HAL_DMA_GET_COUNTER(&hdma_usart3_rx);
// Process data
while(HAL_UART_Transmit_DMA(&huart1, ins_buffer, rx_valid_len) == HAL_BUSY){}
// Next time DMA receive
__HAL_UART_CLEAR_IDLEFLAG(&huart3); // clear the IDLE flag
HAL_UART_Receive_DMA(&huart3, ins_buffer, ins_buffer_len);
}
/* USER CODE END USART3_IRQn 0 */
HAL_UART_IRQHandler(&huart3);
/* USER CODE BEGIN USART3_IRQn 1 */
/* USER CODE END USART3_IRQn 1 */
}
其中的用户变量:ins_buffer_len为宏定义1024;ins_buffer为uint8_t类型的数组,数组长度为ins_buffer_len。
三、烧录运行,观察试验现象
![](https://i-blog.csdnimg.cn/blog_migrate/09c4d7dcd375b1a3bf3dfaa4eece164b.gif)