STM32F746_HAL库例程_UART+DMA+IDLE


例程概览
硬件平台 NUCLEO-F746ZG
软件平台 STM32CubeMX&MDK-ARM
软件功能 串口DMA方式接收和发送、按键外部中断响应、LED灯

第一步:STM32CubeMX配置底层并生成工程代码

STM32F746_HAL库例程_UART+DMA+IDLE_第1张图片

点击"New Project",在弹出界面点击"Board Selector",输入"nucleo-F746zg",窗口右侧显示筛选结果,双击;弹出对话框询问是否按照默认模式初始化所有外设,点击“Yes”;

STM32F746_HAL库例程_UART+DMA+IDLE_第2张图片

STM32F746_HAL库例程_UART+DMA+IDLE_第3张图片

进入图形化配置界面,关闭ETH和USB-OTG外设并将相关引脚设置为Reset State,设置PB3引脚为Reset State;引脚配置结果如下图所示

STM32F746_HAL库例程_UART+DMA+IDLE_第4张图片

点击“Clock Configuration”进入时钟配置界面,设置参数时系统时钟频率为216MHz、APB1时钟频率为54MHz、APB2时钟频率为108MHz;

STM32F746_HAL库例程_UART+DMA+IDLE_第5张图片

点击“Configuration”进入配置界面,双击"DMA",在DMA1中点击“Add”,添加USART3_RX、USART3_TX,其他参数保持默认,点击“Ok”完成DMA配置并关闭该窗口;

STM32F746_HAL库例程_UART+DMA+IDLE_第6张图片

STM32F746_HAL库例程_UART+DMA+IDLE_第7张图片

点击“NVIC”,使能USART3中断和外部中断并设置各中断优先级如下图示,点击“Ok”完成NVIC配置并关闭该窗口;

STM32F746_HAL库例程_UART+DMA+IDLE_第8张图片

USART3配置保持默认即可;

STM32F746_HAL库例程_UART+DMA+IDLE_第9张图片

点击标题栏“Project”->“Generate Code”,弹出工程设置对话框输入工程名和保存路径,选择IDE环境;

STM32F746_HAL库例程_UART+DMA+IDLE_第10张图片

点击工程设置对话框的“Code Generator”,勾选图中所示选项,可以将每个外设的初始化代码放到相应的文件中,便于维护,完成工程设置,点击“Ok”即可生成工程代码

STM32F746_HAL库例程_UART+DMA+IDLE_第11张图片

STM32F746_HAL库例程_UART+DMA+IDLE_第12张图片

第二步:在MDK-ARM中添加用户代码

在gpio.c文件中用户代码段添加按键外部中断回调函数

/* USER CODE BEGIN 2 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == USER_Btn_Pin)
	{
	  HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);
	}
}
/* USER CODE END 2 */

在usart.c文件用户代码段添加如下代码,使能USART3的IDLE中断、DMA接收以及IDLE中断回调函数,并在usart.h中添加申明

/* USER CODE BEGIN 1 */
uint16_t usart3_rx_len;
uint8_t usart3rx_buf[50];
void USER_UART_Init(void)
{
  /*使能串口空闲中断*/
  __HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);	
  HAL_UART_Receive_DMA(&huart3,usart3rx_buf,50); 

}
void UART_IDLE_Callback(UART_HandleTypeDef *huart)
{
  uint32_t tmp1, tmp2;

  tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE);
  tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_IDLE);

  if((tmp1 != RESET) && (tmp2 != RESET))
  {
    __HAL_UART_CLEAR_IDLEFLAG(huart);
    /* set uart state  ready*/
    huart->gState = HAL_UART_STATE_READY;			
    /* Disable the rx  DMA peripheral */
    __HAL_DMA_DISABLE(huart->hdmarx);
    /*Clear the DMA Stream pending flags.*/
    __HAL_DMA_CLEAR_FLAG(huart->hdmarx,__HAL_DMA_GET_TC_FLAG_INDEX(huart->hdmarx));
			
    /* Process Unlocked */
    __HAL_UNLOCK(huart->hdmarx);

    if(huart->Instance == USART3)
    {
      /* get rx data len */
      usart3_rx_len = 50 - huart->hdmarx->Instance->NDTR;
      HAL_UART_Receive_DMA(huart,usart3rx_buf,50);		
    }
  }
}
/* USER CODE END 1 */
/* USER CODE BEGIN Prototypes */
extern uint16_t usart3_rx_len;
extern uint8_t usart3rx_buf[50];
void USER_UART_Init(void);
void UART_IDLE_Callback(UART_HandleTypeDef *huart);
/* USER CODE END Prototypes */

在main.c文件中添加如下代码

  /* USER CODE BEGIN 2 */
  USER_UART_Init();
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
    HAL_GPIO_TogglePin(LD1_GPIO_Port,LD1_Pin);
    HAL_Delay(100);
    if(usart3_rx_len)
    {
      HAL_UART_Transmit_DMA(&huart3,usart3rx_buf,usart3_rx_len);
      usart3_rx_len = 0;
    }
  }
  /* USER CODE END 3 */

在stm32f7xx_it.c文件中USART3中断服务程序中添加IDLE中断回调函数

/**
* @brief This function handles USART3 global interrupt.
*/
void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */
  UART_IDLE_Callback(&huart3);
  /* USER CODE END USART3_IRQn 0 */
  HAL_UART_IRQHandler(&huart3);
  /* USER CODE BEGIN USART3_IRQn 1 */

  /* USER CODE END USART3_IRQn 1 */
}
编译工程并下载程序

第三步:实验现象

现象1:LED1不停的闪烁;

现象2:通过按用户按键可控制LED2亮灭;

现象3:打开串口调试助手,发送数据,调试助手可以接收到发送给单片机的数据,如下图示

STM32F746_HAL库例程_UART+DMA+IDLE_第13张图片

转载请注明作者和出处:https://blog.csdn.net/gefeng3


你可能感兴趣的:(STM32HAL库开发)