rt-thread添加uart驱动 - stm32f091RCTx

1. 在menuconfig中添加菜单选项

串口驱动的Kconfig文件在bord目录中,打开Kconfig文件,添加我们的串口选项,我们添加的是uart3的驱动依次在UART2下面添加即可,如下图:
rt-thread添加uart驱动 - stm32f091RCTx_第1张图片
保存后在env工具中执行menuconfig命令,在menuconfig的相应菜单下就看见了我们的UART3的选项,保存后重新生成mdk5工程,在rtconfig.h文件中就可以看见已经有BSP_USING_UART3 和 BSP_UART3_RX_USING_DMA的选项了
rt-thread添加uart驱动 - stm32f091RCTx_第2张图片
rt-thread添加uart驱动 - stm32f091RCTx_第3张图片

3. 驱动实现

我们使用的是HAL库,并且rt-thread在相应bsp中也为我们提供了相应的 STM32CubMx 的工程文件,我们直接使用这个工程文件来生成相应的驱动文件,我们先配置uart3
rt-thread添加uart驱动 - stm32f091RCTx_第4张图片
在生成的stm32f0xx_hal_msp.c文件中就有了uart3的初始化代码
rt-thread添加uart驱动 - stm32f091RCTx_第5张图片

4. 完善rt-thread中关于uart3的驱动部分

在uart_config.h 中完善相关配置
rt-thread添加uart驱动 - stm32f091RCTx_第6张图片
在dma_config.h 中完善相关DMA的配置,这块要特别注意,有关MDA的配置要参考 stm32f0xx_it.c 中的函数名,UART3_DMA_RX_IRQHandler, UART3_RX_DMA_IRQ 这两个宏实际上是在声明DMA中断的入口函数,下面提供一份stm32f0xx_it.c文件,大家可以参考这个文件来定义相关宏
rt-thread添加uart驱动 - stm32f091RCTx_第7张图片

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    stm32f0xx_it.c
  * @brief   Interrupt Service Routines.
  ******************************************************************************
  * @attention
  *
  * 

© Copyright (c) 2020 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */
/* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "stm32f0xx_it.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN TD */ /* USER CODE END TD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /* External variables --------------------------------------------------------*/ extern DMA_HandleTypeDef hdma_adc; extern DMA_HandleTypeDef hdma_spi1_rx; extern DMA_HandleTypeDef hdma_spi1_tx; extern DMA_HandleTypeDef hdma_usart1_rx; extern DMA_HandleTypeDef hdma_usart2_rx; extern DMA_HandleTypeDef hdma_usart3_rx; extern DMA_HandleTypeDef hdma_usart4_rx; /* USER CODE BEGIN EV */ /* USER CODE END EV */ /******************************************************************************/ /* Cortex-M0 Processor Interruption and Exception Handlers */ /******************************************************************************/ /** * @brief This function handles Non maskable interrupt. */ void NMI_Handler(void) { /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ /* USER CODE END NonMaskableInt_IRQn 0 */ /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ /* USER CODE END NonMaskableInt_IRQn 1 */ } /** * @brief This function handles Hard fault interrupt. */ void HardFault_Handler(void) { /* USER CODE BEGIN HardFault_IRQn 0 */ /* USER CODE END HardFault_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_HardFault_IRQn 0 */ /* USER CODE END W1_HardFault_IRQn 0 */ } } /** * @brief This function handles System service call via SWI instruction. */ void SVC_Handler(void) { /* USER CODE BEGIN SVC_IRQn 0 */ /* USER CODE END SVC_IRQn 0 */ /* USER CODE BEGIN SVC_IRQn 1 */ /* USER CODE END SVC_IRQn 1 */ } /** * @brief This function handles Pendable request for system service. */ void PendSV_Handler(void) { /* USER CODE BEGIN PendSV_IRQn 0 */ /* USER CODE END PendSV_IRQn 0 */ /* USER CODE BEGIN PendSV_IRQn 1 */ /* USER CODE END PendSV_IRQn 1 */ } /** * @brief This function handles System tick timer. */ void SysTick_Handler(void) { /* USER CODE BEGIN SysTick_IRQn 0 */ /* USER CODE END SysTick_IRQn 0 */ HAL_IncTick(); /* USER CODE BEGIN SysTick_IRQn 1 */ /* USER CODE END SysTick_IRQn 1 */ } /******************************************************************************/ /* STM32F0xx Peripheral Interrupt Handlers */ /* Add here the Interrupt Handlers for the used peripherals. */ /* For the available peripheral interrupt handler names, */ /* please refer to the startup file (startup_stm32f0xx.s). */ /******************************************************************************/ /** * @brief This function handles DMA1 channel 1 interrupt. */ void DMA1_Ch1_IRQHandler(void) { /* USER CODE BEGIN DMA1_Ch1_IRQn 0 */ /* USER CODE END DMA1_Ch1_IRQn 0 */ HAL_DMA_IRQHandler(&hdma_usart3_rx); /* USER CODE BEGIN DMA1_Ch1_IRQn 1 */ /* USER CODE END DMA1_Ch1_IRQn 1 */ } /** * @brief This function handles DMA1 channel 2 to 3 and DMA2 channel 1 to 2 interrupts. */ void DMA1_Ch2_3_DMA2_Ch1_2_IRQHandler(void) { /* USER CODE BEGIN DMA1_Ch2_3_DMA2_Ch1_2_IRQn 0 */ /* USER CODE END DMA1_Ch2_3_DMA2_Ch1_2_IRQn 0 */ HAL_DMA_IRQHandler(&hdma_spi1_rx); HAL_DMA_IRQHandler(&hdma_usart1_rx); /* USER CODE BEGIN DMA1_Ch2_3_DMA2_Ch1_2_IRQn 1 */ /* USER CODE END DMA1_Ch2_3_DMA2_Ch1_2_IRQn 1 */ } /** * @brief This function handles DMA1 channel 4 to 7 and DMA2 channel 3 to 5 interrupts. */ void DMA1_Ch4_7_DMA2_Ch3_5_IRQHandler(void) { /* USER CODE BEGIN DMA1_Ch4_7_DMA2_Ch3_5_IRQn 0 */ /* USER CODE END DMA1_Ch4_7_DMA2_Ch3_5_IRQn 0 */ HAL_DMA_IRQHandler(&hdma_usart2_rx); HAL_DMA_IRQHandler(&hdma_usart4_rx); HAL_DMA_IRQHandler(&hdma_spi1_tx); HAL_DMA_IRQHandler(&hdma_adc); /* USER CODE BEGIN DMA1_Ch4_7_DMA2_Ch3_5_IRQn 1 */ /* USER CODE END DMA1_Ch4_7_DMA2_Ch3_5_IRQn 1 */ } /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

看一下这个文件应该怎样使用,比如 UART3_DMA_RX_IRQHandler 这个宏对应哪个中断入口函数呢,我们在文件中查找一下:

在文件中可以找出uart3对应的是这个函数,所以我们可以把下面的函数名定义成宏,大家可以把所有的串口在STM32CubMx中打开,并打开所有的DMA接收,这样所有的中断函数就出现在文件中了,这是一个比较快捷的方式
rt-thread添加uart驱动 - stm32f091RCTx_第8张图片
接下来还有一个比较重要的地方需要注意,要不然串口的接收中断将不能使用

stm32fo91RCTx这个芯片 3~8 串口使用的是同一个串口中断入口:USART3_8_IRQHandler,所有在rt-thread的 drv_uart.c 驱动文件中我们要做相应的修改,修改如下:
我们要添加这么一个函数

void USART3_8_IRQHandler(void)
{
     
	/* enter interrupt */
    rt_interrupt_enter();
	
#if defined(BSP_USING_UART3)
	struct stm32_uart *uart3 = NULL;
	struct rt_serial_device *serial3 = &(uart_obj[UART3_INDEX].serial);
	uart3 = rt_container_of(serial3, struct stm32_uart, serial);

	if (uart3->handle.Instance == USART3)
	{
     
		uart_isr(&(uart_obj[UART3_INDEX].serial));
	}
#endif //BSP_USING_UART3
	
	/* leave interrupt */
    rt_interrupt_leave();
}

5. 注意事项

在用STM32CubMx重新生成工程后,有一个原本关闭的宏被打开了,这块我们手动关闭即可
rt-thread添加uart驱动 - stm32f091RCTx_第9张图片

6. 下载调试

我们把console改成uart3,下载到板子上,开机log也打印出来了,并且敲命令也可以接收执行,我们的串口移植就成功了

rt-thread添加uart驱动 - stm32f091RCTx_第10张图片

你可能感兴趣的:(嵌入式,stm32,rthread,uart,stm32f091RCTX)