赵工的个人空间


专业技术部分转网页计算转业余爱好部分


 单片机与嵌入式

首页 > 专业技术 > 单片机与嵌入式 > 使用STM32CubeMX开发STM32单片机
使用STM32CubeMX开发STM32单片机

STM32是ST公司开发的基于ARM Cortex-M系列的32位单片机,在市场上很流行。但Cortex-M系列是32位单片机,内部资源很多,配置使用比较复杂,特别是项目配置很繁琐,要配置成功有比较大的难度也很耗时,而且在不同的开发平台也有差别。为了方便使用,ST公司推出了一套STM32CubeMX软件,用于通过设置一些基本功能,自动形成项目配置,并产生适应对应开发平台的一部分框架代码,开发者在此基础上再填入需要的程序代码就比较方便了。

1.STM32CubeMX的下载和安装:

STM32CubeMX软件的下载网址为:http://www.st.com/en/development-tools/stm32cubemx.html
网页下方有Get Software按钮,点击并接收相应协议后就可以下载。ST对新用户可能会要求提供一个邮件地址用于推广。

STM32CubeMX

在其上方,还有对应不同系列的软件包,可以根据常用的系列进行下载,软件使用时需要安装这些软件包。

STM32CubeMX

下载完成后解压,里面有个SetupSTM32CubeMX-*.exe安装文件,点击后就可以根据提示进行安装。安装完成后就会在系统菜单及桌面上产生对应的图标,点击后就可以运行。

2.STM32CubeMX的基本配置:

运行STM32CubeMX后,会显示下面的界面:

stm32

点击New Project,就会打开一个界面,用于新项目的配置:

STM32CubeMX

在界面左侧可以选择需要的芯片型号,也可以根据需要的资源由软件来推荐相应的型号列表。

STM32CubeMX

软件根据用户的选择,把对应的型号列表显示在下面的列表中,其中列出封装、价格、Flash容量、RAM容量、IO口数量等主要参数。点选后就可以使能上面的按钮,在其中可以查看点选芯片的特性、框图、Datasheet、相关文件及资源等。

STM32CubeMX

最右一个按钮是Start Project,点击后会打开项目配置页面:

STM32CubeMX

项目配置中有几个按钮,最左侧为Pinout,用于配置项目中需要使用的内部资源及相应管脚,其中SYS中的SysTick是默认配置的,一般情况下需要使用外部晶振,需要在RCC中进行配置,这里使用的是High Speed Clock(HSE),然后右侧主界面中相应的芯片引脚变绿,表示使用的管脚。
一定要注意,SYS中的Debug选项一般一定要配置,用于生成代码后烧入程序。如果忘记配置,烧入一次程序后可能无法再次用swd写入,需要通过将boot0置高才能修改,很麻烦。建议首先设置此选项。

STM32CubeMX

然后是Clock Configuration,用于配置芯片内部资源的时钟。因为前面已经配置了HSE,所以这个界面中HSE就已经变蓝,表示可用,在其中可以改变频率值,这里使用常用的8MHz晶振。因为使用外部晶振,在System Clock Mux中选择HSE源,用于SYSCLK及AHB、APB总线的时钟。

STM32CubeMX

然后是Configuration按钮,如果设置使用相关资源,这里可以进行进一步的配置。如果前面的一些功能配置中有冲突或时钟配置有问题,软件可以进行自动检查,并进行提示,甚至可以选择适当的时钟设置。

最后还有一个Power Consumption Calculator按钮,用于计算各种状态下的功耗,包括Run、Sleep、Stop、Standby等。

STM32CubeMX

点击界面中的绿色的+按钮,可以打开设置界面,选择一种电源模式,设置对应模式使用的外设Peripherals资源,下面就能自动计算出所消耗的电流。

STM32CubeMX

如果选择使用电池,还会出现一个选择电池的界面,其中有多种常用电池的参数,可以作为选用电池的参考。一般常用的备用电池是Li-MnO2,但这种电池有时不能支持运行状态,只能用于保存数据。

STM32CubeMX

加入多种状态的功耗项后,会出现一个图表,这对预估系统的耗电情况非常有用,特别是电池供电情况下。

STM32CubeMX

3.STM32CubeMX的菜单:

STM32CubeMX界面中只有简单的几个菜单。首先是File菜单,基本都是与项目有关,包括创建、打开、存储、关闭等,比较简单。

STM32CubeMX

而Help菜单中有一个重要的菜单项,就是Install New Libraries,可以用于安装ST网站中下载的各系列的软件包,这样更方便使用。

STM32CubeMX

点击这个菜单后,会打开一个New Libraries Manager界面。

STM32CubeMX

左下角有一个From Local按钮,点击后出现Select文件包的界面,找到下载的各系列软件包的存放位置,安装需要的软件包。

STM32CubeMX

安装软件包需要一段时间,会出现进度条提示:

STM32CubeMX

安装完成后,回到库管理界面,相应的固件包列表前面的方框变绿,表示已经安装成功。

STM32CubeMX

还有一个Pinout菜单,在其中可以设置或清除一些引脚的输入/输出功能,但一般是在程序中用代码设置。

STM32CubeMX

最重要的是Project菜单,其中有Generate Code菜单项:

STM32CubeMX

点击菜单后后出现一个设置界面,需要在其中填入需要产生的项目名,选择路径。要选择一种IDE开发平台,这里使用Keil5,所以选择MDK-ARM V5,。下面有Firmware Package设置项,如果前面安装了相应的软件包,这里就会自动选择了,否则就需要手动选择已解压的软件包存放位置。

STM32CubeMX

这个界面还有几个标签按钮,可以使用默认设置,在Advanced Settings中查看已经设置的资源。这是一个最简单的演示项目,所以只用GPIO和RCC。

STM32CubeMX

点击下面的OK按钮,会出现一个Code Generation提示框。

STM32CubeMX

一般使用Open Project按钮,然后会自动打开电脑中安装的相应开发软件,这里使用的是Keil uVision 5。

stm32

打开刚才使用STM32CubeMX建立的项目,可以看到其中已有4个文件夹,Drivers/CMSIS、Application/MDK-ARM、Drivers/STM32F1xx_HAL_Driver、Application/User,分别放置相应的配置文件。

keil5

在主界面中打开main.c,其中引用了main.h和stm32f1xx_hal.h两个头文件,自动产生的代码中定义了SystemClock_Config()和MX_GPIO_Init()两个函数,在后面有这两个函数的代码。在自动产生的主函数main()的代码中使用了HAL_Init()、SystemClock_Config()和MX_GPIO_Init()函数,并提示了填入相应代码的位置,while (1){}中的代码是空的。最后面还定义了_Error_Handler()和assert_failed()两个错误处理函数,其中也可以填入相应的用户代码。

4.一个简单的示例:

单片机最简单的使用就是用一个引脚控制LED,这里也使用STM32CubeMX实现对STM32F103芯片一个引脚的输出电平控制。STM32单片机在上电时所有外设都是未使能的,以节省能耗。如果要使用某个端口,就需要配置RCC,使能这个端口,一般是用代码实现的。但在STM32CubeMX中,可以使用图形界面对端口引脚进行配置。在Pinout界面中,鼠标点击对应的引脚:

STM32CubeMX

这里要设置的引脚是PA5,鼠标点击后出现一个设置复选列表,选择GPIO_Output点击,即设为输出引脚。

STM32CubeMX

然后PA5变为绿色,表示已经使用。这时再打开Configuration标签按钮,显示设置界面:

STM32CubeMX

界面中点击GPIO,出现已经设置使用的GPIO引脚,这里只有PA5。点击此列项,下方出现设置界面。

stm32

PA5的配置中,输出电平可设为低或高,GPIO模式有推挽Push Pull和开漏Open Drain两种,而最大输出速率有低、中、高三种。设置完成后,使用Project菜单的Generate Code菜单项,产生改变了的代码,其中主函数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();
 /* 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 */
}

上述代码是系统根据用户设置自动产生的,其中只有三行有效代码,分别为HAL_Init()、SystemClock_Config()、MX_GPIO_Init(),并有相应注释,分别为系统初始化、系统时钟配置和GPIO初始化。其他注释部分则标注了用户代码放置的位置,如USER CODE BEGIN x/USER CODE END x,用户编写的代码需要放置在其间,这样使用STM32CubeMX改变配置并重新产生代码时不会被覆盖。我们需要的功能很简单,只需要加入几条语句即可:

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();
 /* USER CODE BEGIN 2 */
 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
  /* USER CODE END WHILE */
  /* USER CODE BEGIN 3 */
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
  HAL_Delay(500);
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
  HAL_Delay(500);

 }
 /* USER CODE END 3 */
}

其中,HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET)将GPIOA端口的PIN5设为1,而HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET)则是将GPIOA端口的PIN5设为0,HAL_Delay(500)则为延时函数。
在后面的代码中,有SystemClock_Config()和MX_GPIO_Init()函数的代码,其中GPIO_Init()函数的代码为:

static void MX_GPIO_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStruct;
 /* GPIO Ports Clock Enable */
 __HAL_RCC_GPIOD_CLK_ENABLE();
 __HAL_RCC_GPIOA_CLK_ENABLE();
 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
 /*Configure GPIO pin : PA5 */
 GPIO_InitStruct.Pin = GPIO_PIN_5;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

代码中,__HAL_RCC_GPIOA_CLK_ENABLE(),用于配置GPIOA的RCC,即使能GPIOA端口;后面用HAL_GPIO_Init()函数配置了GPIO端口的引脚、模式、速率等,这些代码都是按用户设置自动产生的。
可见,通过STM32CubeMX编写STM32程序要简明很多,因为很多配置都是软件按需求自动设好了,用户自己的需求是通过使用系统提供的函数写入代码中的特定位置来实现。通过这样的方式设计应用程序,避开了复杂繁琐的系统配置过程,完成设计更有效率,但一些设置方式及系统提供的函数需要时间熟悉,目前的教材中原来的编程方式比较多,需要转换。

Copyright@dwenzhao.cn All Rights Reserved   备案号:粤ICP备15026949号
联系邮箱:dwenzhao@163.com  QQ:1608288659