STM32
直播中

yuhonglong

12年用户 690经验值
私信 关注
[问答]

如何对基于STM32CubeMX的UART进行配置呢

如何基于STM32CubeMX、Kiel和STM32 HAL来配置生成一个可用的开发环境呢?
如何对基于STM32CubeMX的UART进行配置呢?

回帖(1)

刘静

2021-11-26 15:32:55
开发步骤

配置环境

工欲善其事,必先利其器。首先第一步就是安装STM32CubeMX环境,关于STM32CubeMX环境的安装。

在这里说一句,STM32CubeMX提供所有STM32家族的MCU芯片的初始配置抽象,并提供了HAL,封装、抽象了关于底层硬件的配置、使用过程,这是一把双刃剑,有利有弊:利是它增强了STM32不同MCU之间的兼容性,大大加快了初始开发进度,其提供的HAL为开发者提供了统一的开发接口,这样节省了宝贵开发时间。同时,基于其提供的配套的中间件(RTOS、TCP/IP、FS等),开发者可以快速的完成更高级需求的环境定制,这对于开发者来说是不小的福音;弊是,STM32 MCU毕竟是比较低级的硬件开发平台,其开发过程中涉及到大量的底层硬件操作,如果我们想彻底理解这些基础的硬件操作原理的话,可能还是需要从最为原始的硬件寄存器配置开始。
不过,个人感觉STM32CubeMX利大于弊,就像通用操作系统,其屏蔽了所有的硬件相关的操作,为开发者抽象出了进程、内存管理、文件系统、网络等等,易于开发、理解的开发接口,也是正是操作系统的逐步成熟,才最终促使了后来的计算机一次又一次的革命。我想,对于MCU来说,其过程是类似的。如今,已经进入了物联网时代,各种各样的的硬件开发平台层出不穷,各种层次的开发者都涌入到了这一开发领域。试想对于一个原来从事于Web开发的人员来说,其不可能从头去理解底层的硬件知识,其需要的就是一个快速、高效的配置工具,完成原始开发环境的搭建。这时,STM32CubeMX就可以提供很大的帮助。
相信,STM32CubeMX未来肯定会发展的更为智能,任何一个有志于基于该平台开发的开发者,都会被其强度的功能所折服的,零基础的开发人员也能够快速上手该平台。我想,这可能也是STM32CubeMX未来的目标吧。
最后说明一下,本文所使用的STM32CubeMX的版本是:5.5.0。温馨提示,不同版本的操作步骤也能不太一样,所以建议使用相同的版本进行配置。
开始配置

首先,我们需要确定我们所使用的STM32的MCU具体型号,然后,打开STM32CubeMX,创建一个新的工程。





我们选择第一个“ACCESSTO MCU SELECTOR”,开始创建一个工程。我们选择的MCU是STM32L010K8,安装如下图的步骤创建工程。







  • 选择MCU型号
  • 查看MCU型号信息
  • 创建项目

然后,选择Project Manager项目,配置本项目的一些信息。





接下来,我们进行Pinout & Configuration配置,这里面会涉及到MCU提供的所有外围硬件的相关配置。本文主要关注的是UART的配置过程,STM32L010K8提供一个UART2和LPUART,我们选择的配置项为UART2。
UART2的基本配置步骤如下,






  • 选择UART2配置项。
  • 选择UART2的工作模式,这里选择的是Asynchronous。
  • 配置UART2的参数,参数分为Basic Parameters、Advanced Paramters、Advanced Features几类。



    • 基本参数配置就是波特率、字长、校验方式、停止位;
    • 高级参数配置就是数据传输方向、采集相关的配置;
    • 高级特性配置:就是UART2提供的一些比较高级的功能,比如,自适应波特率、Overrun等。


我们选择UART2的中断方式处理数据的传输模式,所以,需要进一步配置NVIC。配置步骤如下:







  • 点击System Core中的NVIC配置。
  • 使能USART2中断,并配置中断抢占优先级为0。

还有就是需要确定UART2使用GPIO引脚,配置方式如下:





这里使用的是PA2和PA3。
最后,配置SysClock,我们最终选择的系统主时钟频率为16MHz。





完成上述配置之后,点击GENERATE CODE完成项目代码的生成。





HAL

项目代码生成之后,我们使用Kiel打开,如下图:





下面是main中的芯片初始化代码:

int main(void)
{
  /* USER CODE BEGIN 1 */


  /* USER CODE END 1 */
  


  /* MCU Configuration--------------------------------------------------------*/


  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();


  /* USER CODE BEGIN Init */


  /* USER CODE END Init */


  /* Configure the system clock */
  SystemClock_Config();


  /* USER CODE BEGIN SysInit */


  /* USER CODE END SysInit */


  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */


  /* USER CODE END 2 */




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


    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
我们看到,STM32CubeMX自动生成了关于HAL、系统时钟、UART2的初始化代码。下面看一下UART2的初始化代码:


static void MX_USART2_UART_Init(void)
{


  /* USER CODE BEGIN USART2_Init 0 */


  /* USER CODE END USART2_Init 0 */


  /* USER CODE BEGIN USART2_Init 1 */


  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */


  /* USER CODE END USART2_Init 2 */
}
stm32l0xx_it.c中定义了UART2的中断处理函数,代码如下:


void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */


  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */


  /* USER CODE END USART2_IRQn 1 */
}
该中断处理函数用来处理所有与UART2相关的中断事件。那如何才能开启UART2的数据发送和接收呢?这就需要HAL中关于UART2数据发送接收的接口函数:


HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
当我们需要已中断的方式接收数据时,就调用HAL_UART_Receive_IT函数,其中第一个参数是UART的描述符,pData保存数据的缓存区,Size是缓存区的大小。注意,调用完该接口之后,UART2开始已中断的方式接收数据,数据的大小为Size,当接收了Size个字节的数据之后,UART2就不会再接收数据。若想再次接收数据,需要再一次调用HAL_UART_Receive_IT函数。一个比较好的实现就是,在重新覆盖实现下面的函数,


`__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)`


该函数会在数据接收完之后被调用,然后我们在函数中,可以将数据拷贝走,然后再次调用HAL_UART_Receive_IT。


对于数据的发送,处理过程与接收类似,所不同的就是发送的接口函数为:HAL_UART_Transmit_IT,该发送完成之后的回调函数是:


__weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)


好了,至此我们基本完成了基于STM32CubeMX的UART的配置过程,可以看到基于此种方式,我们基本上不会触碰到硬件寄存器的配置过程,所要做的就是基于HAL框架提供的接口完成APP的开发。这也许就是STM32CubeMX的魅力所在吧,简单,高效,可移植性强。
UART_TxCpltCallback(UART_HandleTypeDef *huart)
举报

更多回帖

发帖
×
20
完善资料,
赚取积分