【正点原子STM32】STM32CubeMX入门(搭建Java运行环境、STM32CubeMX安装、新建STM32CubeMX工程步骤、STM32CubeMX用户使用手册)

一、STM32CubeMX简介
二、STM32CubeMX安装

三、新建STM32CubeMX工程步骤
四、总结

一、STM32CubeMX简介

STM32CubeMX(CubeMX)是STMicroelectronics开发的一款图形化配置工具,用于帮助开发者轻松配置和初始化STM32微控制器。它提供了一个直观的图形用户界面,让用户通过简单的操作完成对STM32微控制器的配置,包括引脚分配、时钟配置、外设初始化等。

STM32CubeMX的主要功能和特点包括:

  1. 图形界面配置: CubeMX通过图形用户界面让用户配置STM32芯片的各种参数,避免了手动修改寄存器配置的繁琐步骤。

  2. 引脚配置: 用户可以通过简单的拖拽和连接来配置芯片的引脚分配,方便地设置GPIO、外部中断、定时器等功能。

  3. 时钟配置: CubeMX支持用户配置系统时钟、外设时钟和总线时钟等,通过可视化工具帮助用户优化时钟树。

  4. 外设初始化: CubeMX能够自动生成外设的初始化代码,简化了用户对外设的配置和初始化过程。

  5. 代码生成: CubeMX生成的配置信息可以直接用于STM32CubeIDE或其他支持Cube配置的开发环境,也可以导出为各种主流开发环境(如Keil、IAR等)的工程文件。

  6. Firmware Package集成: CubeMX可以与STM32Cube固件包(Firmware Package)集成,支持不同系列的STM32芯片。

使用STM32CubeMX能够提高开发效率,降低初期配置的复杂性,同时保证了配置的正确性。它是STM32系列微控制器开发工程中的一个强大工具,特别适用于初学者和需要迅速进行原型设计的开发者。
在这里插入图片描述
STM32CubeMX 具有如下特性:
① 直观的选择 MCU 型号,可指定系列、封装、外设数量等条件;
② 微控制器图形化配置;
③ 自动处理引脚冲突;
④ 动态设置时钟树,生成系统时钟配置代码;
⑤ 可以动态设置外围和中间件模式和初始化;
⑥ 功耗预测;
⑦ C 代码工程生成器覆盖了 STM32 微控制器初始化编译软件,如 IAR,KEIL,GCC;
⑧ 可以独立使用或者作为 Eclipse 插件使用;
⑨ 可作为 ST 的固件包、芯片手册等的下载引擎;
对于 STM32CubeMX 和 STM32Cube 的关系这里我们还需要特别说明一下,STM32Cube 包含 STM32CubeMX 图形工具和 STM32Cube 库两个部分,使用 STM32CubeMX 配置生成的代码,是基于 STM32Cube 库的。也就是说,我们使用 STM32CubeMX 配置出来的初始化代码,和 STM32Cube 库兼容,例如硬件抽象层代码就是使用的 STM32 的 HAL 库。不同的 STM32 系列芯片,会有不同的 STM32Cube 库支持,而 STM32CubeMX 图形工具只有一种。所以我们配置不同的 STM32 系列芯片,选择不同的 STM32Cube 库即可。

二、STM32CubeMX安装

首先是 Java 运行环境安装,其次是STM32CubeMX 软件安装

路径:战舰 V4→资料→6,软件资料→1,软件→ 3,STM32CubeMX
在这里插入图片描述

2.1、STM32CubeMX软件获取

  1. 获取Java软件
    Java 官网 www.java.com 下载最新的 Java 软件
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  2. 获取STM32CubeMX软件
    ST官方下载,下载地址为:https://www.st.com/en/development-tools/stm32cubemx.html
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

2.2、搭建Java运行环境

在这里插入图片描述
在这里插入图片描述
安装完 Java 运行环境之后,为了检测是否正常安装,我们可以打开 Windows 的命令输入框,输入:java –version 命令,如果显示 Java 版本信息,则安装成功。
提示信息如下图
在这里插入图片描述

2.3、安装STM32CubeMX软件

在这里插入图片描述

  1. 启动安装
    在这里插入图片描述
  2. 接受本许可协议
    在这里插入图片描述
  3. 勾选第一项即可
    在这里插入图片描述
  4. 指定安装路径
    在这里插入图片描述
  5. 创建快捷方式
    在这里插入图片描述
  6. 安装进度提示
    在这里插入图片描述
  7. 完成安装
    在这里插入图片描述

2.4、下载和关联STM32cube固件包

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

关联STM32Cube固件包的方法

在这里插入图片描述
获取相关STM32Cube 官方固件包(F1/F4/F7/H7)的方法:
STM32Cube官网

路径:战舰 V4资料:资料→8,STM32 参考资料→1,STM32CubeXX固件包

  新建工程前,我们需要先安装关联与 STM32 主芯片对应的 STM32Cube 固件包,点击
Help->Manage embedded software packages,如图所示。
在这里插入图片描述
  在弹出的软件包管理界面中,我们可以选择安装驱动包的方式,有以下两种方法:
  方式一:从网络下载安装,按照如图的步骤,在该窗口找到 STM32F1 列表选项,因
为我们的教程源码使用的固件包是 1.8.3 版本的,所以我们勾选 1.8.3 版本,等待安装完成即可。
在这里插入图片描述
在这里插入图片描述
  方法二:不通过网络,直接点击从本地导入。由于直接使用上面的安装包管理器的“From Local”选项导入压缩包有时候会直接报错,比如可以直接导入“stm32cube_fw_f1_v180.zip”固件包,但直接导入“stm32cube_fw_f1_v183.zip”的安装包时 CubeMX 软件会报错,所以我们采用以下方法来处理:
  我们这里要使用的是 CubeF1 固件的 1.8.3 版本。由于 CubeF1 的 1.8.3 版本是 1.8.0 版本的补充包,所以需要把“stm32cube_fw_f1_v180.zip”和“stm32cube_fw_f1_v183.zip”两个固件包都复制到对应的路径下。复制后目录 CubeMX 的仓库目录的状况如图所示。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、新建STM32CubeMX工程步骤

官方STM32CubeMX用户使用手册下载
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
建立STM32CubeMX工程通常涉及以下步骤:

  1. 新建工程,选择芯片型号:

    • 打开STM32CubeMX软件,点击"New Project"。
    • 在弹出的对话框中,选择目标芯片型号。这通常是你所使用的具体STM32微控制器型号。
  2. 时钟模块配置:

    • 进入"Clock Configuration"选项卡。
    • 配置外部晶振(HSE)和/或外部低速晶振(LSE),具体设置与硬件设计有关。
    • 配置主时钟输出(MCO),如果需要。
  3. 时钟系统配置:

    • 在"Configuration"选项卡中,配置PLL(锁相环)和系统时钟。
    • 设置主系统时钟(SYSCLK)频率,通常由PLL提供。
    • 配置AHB、APB1、APB2等时钟分频系数,以确定总线和外设时钟。
  4. GPIO引脚配置:

    • 进入"Pinout & Configuration"选项卡。
    • 在这里,你可以配置各个引脚的功能,例如输入、输出、模拟、复用等。
    • 以连接在LED灯的IO为例,选择相应的引脚并配置为输出。
  5. Cortex内核配置:

    • 进入"Configuration"选项卡的"System"子选项。
    • 在这里,你可以配置与Cortex内核相关的参数。
    • 配置SYS(DEBUG)参数,包括如何处理调试信息。
    • 配置NVIC(Nested Vector Interrupt Controller),设置中断优先级分组等。
  6. 生成工程源码:

    • 在左下角点击"Project"选项卡。
    • 配置生成工程的相关设置,包括选择开发环境(如MDK)和生成路径等。
    • 点击"Project", 然后点击"Generate Code",生成初始化的工程代码。
  7. 编写用户程序:

    • 打开生成的工程,在main.c文件的适当位置编写你的用户程序。
    • 添加初始化代码和主循环,以配置外设并执行你的应用程序。

以上步骤可能会因芯片型号和具体的硬件设计而略有差异,因此确保仔细查阅相关芯片手册和参考资料,以确保正确的配置。

1、工程初步建立

  方法一:依次点击“File->New Project”即可建新工程。如果之前打开过的话,左侧最近打开的过程一列会有打开的工程列表,直接点击这些工程也可以打开。
  方法二:直接点击 ACCESS TO MCU SELECTOR。具体操作如图所示。
新建工程
在这里插入图片描述
  点击新建工程后,可能会弹出如图的窗口,提示需要联网下载一些文件,可能等待时间比较长,可以直接选择取消即可。我们可以通过关闭自动更新设置来禁止弹出这个窗口。
启动时联网更新检测
在这里插入图片描述
  之后都可以进入芯片选型界面,如图所示。
芯片选型界面
在这里插入图片描述
  选择具体的芯片型号,如图所示。
选择具体的芯片型号
在这里插入图片描述
  鼠标双击选择的芯片型号后,弹出主设计界面,如图所示。
主设计界面
在这里插入图片描述

2、HSE 和 LSE 时钟源设置

  进入工程主设计界面后,首先设置时钟源 HSE 和 LSE。如图所示。
设置时钟源 HSE 和 LSE
在这里插入图片描述
  标号④和⑤,我们都选择了 Crystal/Ceramic Resonator,表示外部晶振作为它们的时钟源。我们开发板的外部高速晶振和外部低速晶振分别是:8MHZ 和 32.768KHZ,所以 HSE 时钟频率就是 8MHZ,LSE 时钟频率就是 32.768KHZ。
  选项 Master Clock Output 1 用来选择是否使能 MCO1 引脚时钟输出。

3、时钟系统(时钟树)配置

在这里插入图片描述
  点击 Clock Configuration 选项卡即可进入时钟系统配置栏,如下图所示:
时钟系统配置栏
在这里插入图片描述
  进入 Clock Configuration 配置栏之后可以看到,界面展现一个完整的 STM32F1 时钟系统框图。从这个时钟树配置图可以看出,配置的主要是外部晶振大小,分频系数,倍频系数以及选择器。在我们配置的工程中,时钟值会动态更新,如果某个时钟值在配置过程中超过允许值,那么相应的选项框会红色提示。
  这里,我们将配置一个以 HSE 为时钟源,配置 PLL 相关参数,然后系统时钟选择 PLLCLK为时钟源,最终配置系统时钟为 72MHz 的过程。同时,还配置了 AHB,APB1,APB 和 Systick的相关分频系数。由于图片比较大,我们把主要的配置部分分两部分来讲解,第一部分是配置系统时钟,第二部分是配置 SYSTICK、AHB、APB1 和 APB2 的分频系数。首先我们来看看第一部分配置如下图所示:
系统时钟配置图
在这里插入图片描述
我们把系统时钟配置分为七个步骤,分别用标号 1~5 表示,详细过程为:
  ① 时钟源参数设置:我们选择 HSE 为时钟源,所以我们要根据硬件实际的高速晶振频率(这里我们是 8MHZ)填写。
  ② 时钟源选择:我们配置选择器选择 HSE 即可。
  ③ PLL 倍频系数 PLLMUL 配置。倍频系数 PLLMUL 我们设置为 9。
  ④ 系统时钟时钟源选择:PLL,HSI 还是 HSE。我们选择 PLL,选择器选择 PLLCLK 即可。
  ⑤ 经过上面配置以后此时 SYSCLK=72MHz。
经过上面的 5 个步骤,就配置好 STM32F1 的系统时钟为 72MHz。接下来我们还需要配置AHB、APB1、APB2 和 Systick 的分频系数,为 STM32 的片上外设或 M3 内核设置对应的工作时钟,为后续使用这些硬件功能做好准备。配置如下图所示:
AHB、APB1、APB2、APB3 和 APB4 总线时钟配置
在这里插入图片描述
  AHB、APB1 和 APB2 总线时钟以及 Systick 时钟的来源于系统时钟 SYSCLK。其中 AHB总线时钟 HCLK 由 SYSCLK 经过 AHB 预分频器之后得到,如果我们要设置 HCLK 为 72MHz(最大为 72Mhz),那么我们只需要配置图中标号⑥的地方为 1 即可。得到 HCLK 之后,接下来我们将在图标号⑦~⑨处同样的方法依次配置 Systick、APB1 和 APB 分频系数分别为 1、2 和 1。
  注意!systick固定为72MHz,配置完成之后,那么HCLK=72MHZ,Systic=72MHz,PCLK1=36MHz,PCLK2=72MHz,这和之前例程配置的时钟是主频一样的。
  以上方法是手动计算的方法,是为了帮助我们更好地去认识 STM32 时钟的配置方法,当然CubeMX 也提供了更简单的方法:在上图的“HCLK(MHz)”位置,实际上是可以编辑的。我们直接输入我们要的主频,这里是 72Mzh,按回车键,CubeMX 会帮我们提供一种设置主频和其它时钟的建议,选择是后会由软件自动配置好,当然只有启用外部的晶振后才能配置到72Mhz 的时钟,这里大家自己尝试一下就清楚了,我们不展开讲述了。

4、GPIO 功能引脚配置

在这里插入图片描述
在这里插入图片描述
  使用 STM32CubeMX 工具配置 STM32F1 的 GPIO 口。STM32F103 战舰开发板的 PB5 和 PE5 引脚各连接一个 LED 灯,我们来学习配置这两个 IO 口的相关参数。这里我们回到 STM32CubeMX 的 Pinout&Configuration 选项,在搜索栏输入 PB5 后回车,可以在引脚图中显示位置,如下图所示:
搜索引脚位置
在这里插入图片描述
  接下来,我们在下图引脚图中点击 PB5,在弹出的下拉菜单中,选择 IO 口的功能为 GPIO_Output。操作方法如下图所示:
配置 GPIO 模式
在这里插入图片描述
  同样的方法,我们配置 PE5 选择功能为 GPIO_Oput 即可。设置好即可看到引脚从灰色变成绿色,标识该管脚已经启用。这里我们需要说明一下,如果我们要配置 IO 口为外部中断引脚或者其他复用功能,我们选择相应的选项即可。配置完 IO 口功能之后,还要配置 IO 口的速度,上下拉等参数。这些参数我们通过 System Core 下的 GPIO 选项进行配置,如图所示。
GPIO 选项
在这里插入图片描述
在这里插入图片描述
  我们先配置 PB5,PE5 和 PB5 配置方法一样的。点击图 10.3.3.12 的④号框里面的 PB5,配置如图所示。
配置 GPIO 口详细参数
在这里插入图片描述
在这里插入图片描述
  GPIO output level 是 IO 的初始值,由于 LED 一端接 VCC,另一端接 GPIO,故要点亮 LED灯时,使 GPIO 输出低电平即可。为了一开始让 LED 灯熄灭,我们设置初始值输出高电平。
  GPIO mode 我们已经在视图中配置为推挽输出了,这里不需要修改。
  GPIO Pull-up/Pull-down 默认是无上下拉,我们这里用默认配置。
  Maximum output speed 输出速度配置,默认是低速,我们设置为高速。
  User Label 用户符号,我们可以给 PB5 起一个别的名字 LED0。
  PE5 也是按照这样的方法配置即可。
在这里插入图片描述

5、配置 Debug 选项

  由于 CubeMX 默认把 Debug 选项关闭了,这样会给我们带来麻烦:用 CubeMX 生成的工程编译下载一次后,后续再次下载就会提示错误,因此我们要把 Debug 选项打开。这里有多种选择,我们设置成图所示的情况即可。
打开 Debug 选项
在这里插入图片描述
  如果已经不小心关闭了 Debug 选项,那么下次下载的时候按住复位键,等到工程提示的时候松开复位键即可,因为 STM32 的芯片默认复位上电时的 Debug 引脚功能是开启的。
在这里插入图片描述

配置 NVIC中断

在这里插入图片描述

6、生成工程源码

  接下来我们学习怎么设置生成一个工程,如图 10.3.3.15 所示。选择 Project Manager-> Project选项用来配置工程的选项,我们了解一下里面的信息。
  Project Name:工程名称,填入工程名称(半角,不能有中文字符)
  Project Location:工程保存路径,点击 Browse 选择保存的位置(半角,不能有中文字符)
  Toolchain Folder Location:工具链文件夹位置,默认即可。
  Application Structure:应用的结构,选择 Basic(基础),不勾选 Do not generate the main(),因为我们要其生成 main 函数。
  Toolchain/IDE:工具链/集成开发环境,我们使用 Keil,因此选择 MDK-ARM,Min Version 选择 V5.27,这里根据 CubeMX 的版本可能会有差异,我们默认使用 V5 以上的版本即可。
  Linker Settings 链接器设置:
  Minimum Heap Size 最小堆大小,默认(大工程需按需调整)。
  Minimum Stack Size 最小栈大小,默认(大工程需按需调整)。
  MCU and Firmware Package 是 MCU 及固件包设置:
  MCU Reference:目标 MCU 系列名称。
  Firmware Package Name and Version:固件包名称及版本。
  勾选 Use Default Firmware Location,文本框里面的路径就是固件包的存储地址,我们使用默认地址即可。(这里因为我有两个版本的固件包,所以它默认使用最新的,这个关系不大,就用新的)。这样工程生成的设置就设置好了,如图所示。
工程配置
代码生成器设置
在这里插入图片描述
在这里插入图片描述
  打开 Project Manager-> Code Generator 选项,Generated files 生成文件选项,勾选 Generate peripheral initialization as a pair of ‘.c/.h’files per peripheral,勾选这个选项的话将会将每个外设单独分开成一组.c、.h 文件,使得代码结构更加的清晰,如图所示。
代码生成器设置
在这里插入图片描述
在这里插入图片描述
  由于 CubeMX 默认勾选了复制所有的库,即工程中不使用到的代码也会复制进来,为了节省 CubeMX 生成工程的空间,我们勾选生成工程时只复制用到的库(这一步是可选操作,大家根据自己的实际选择),如图所示:
设置只复制与工程相关的库驱动以减小工程大小
在这里插入图片描述
保存工程
在这里插入图片描述
  至此工程最基础配置就已经完成,点击蓝色按钮(SENERATE CODE)就可以生成工程。
生成工程
在这里插入图片描述
  如果我们的 CubeMX 工程放置配置路径中没有中文。生成代码后会弹出类似下图的提示窗口,点击 Open Project 就打开 MDK 工程(如果是中文路径则会报错,这里暂时不用管,我们先往下继续操作)。
打开工程
在这里插入图片描述
  完整的 STM32F1 工程就已经生成完成。生成后的工程目录结构如下图所示:
STM32CubeMX 生成的工程目录结构
在这里插入图片描述
在这里插入图片描述
Drivers 文件夹存放的是 HAL 库文件和 CMSIS 相关文件。
Inc 文件夹存放的是工程必须的部分头文件。
MDK-ARM 下面存放的是 MDK 工程文件。
Src 文件夹下面存放的是工程必须的部分源文件。
Template.ioc 是 STM32CubeMX 工程文件,双击该文件就会在 STM32CubeMX 中打开。
在这里插入图片描述

7、用户程序

  在编写用户程序之前,首先我们打开生成的工程模板进行编译,因为我们在之前步骤生成的 CubeMX工程为LED_TEST.ioc,故生成的 MDK 工程位置是.\MDK-ARM\LED_TEST.uvprojx,如果大家配置的 CubeMX 的工程名和路径名不含中文或中文字符,按上述步骤生成的工程就可以直接编译通过了。
STM32CubeMX 生成的 MDK 工程编译通过
在这里插入图片描述

  接下来我们中生成的工程模板的 main.c 文件中找到 main 函数,这里我们删掉了源码注释,关键源码如下:

int main(void)
{
	HAL_Init();
	SystemClock_config();
	MX_GPIO_Init();
	/* USER CODE BEGIN WHILE */
	while (1)
	{
	 /* USER CODE END WHILE */
	}
}

  大家需要注意,STM32CubeMX 生成的 main.c 文件中,有很多地方有“/* USER CODE BEGIN X /”和“/ USER CODE END X */”格式的注释,我们在这些注释的 BEGIN 和 END之间编写代码,那么重新生成工程之后,这些代码会保留而不会被覆盖。
  我们编写一个跑马灯的用户程序,程序具体如下:

/**
 * @brief The application entry point.
 * @retval int
 */
int main(void)
{
	HAL_Init();
	SystemClock_Config();
	MX_GPIO_Init();
	/* USER CODE BEGIN WHILE */
	while (1)
	{
	HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
	HAL_Delay(500);
	HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
	HAL_Delay(500);
	/* USER CODE END WHILE */
	}
}

  编写好程序后,编译没有任何警告和错误。可以直接下载程序到开发板中,使用 DAP 下载,请注意设置 MDK 的下载选项,如果不清楚设置的读者可以回看本书第四章的相关知识点。下载后,可以看到 LED0 和 LED1 同时按 500ms 的频率亮灭,效果与其它版本的新建工程相同。
  使用 STM32CubeMX 新建的工程模板在我们光盘目录:“4,程序源码\2,标准例程-HAL 库版本\实验 0 基础入门实验\实验 0-4,新建工程实验-CubeMX 版本”中有存放,大家在编写用户代码过程中可以参考该工程的 main.c 文件。

main.c文件

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * 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 "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* 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 -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
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 */
    HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_SET);  /*LED0 PB5置1*/ 
    HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);/*LED1 PE5置0*/ 
    HAL_Delay(500);
    HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_RESET);/*LED0 PB5置1*/
    HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);  /*LED1 PE5置0*/
    HAL_Delay(500);
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

/* 用户代码开始 头文件 */
/**
  ******************************************************************************
  * @文件           : main.c
  * @概要           : 主程序体
  ******************************************************************************
  * @注释
  *
  * <h2><center>&copy; 版权所有 2022 意法半导体.
  * 保留所有权利.</center></h2>
  *
  * 本软件组件由ST根据BSD 3-Clause许可证许可,
  * "许可证"; 除非符合许可证,否则您不能使用此文件。
  * 您可以在以下网址获取许可证的副本:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* 用户代码结束 头文件 */
/*  头文件  ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"

/*  用户私有头文件  ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* 用户私有的类型定义 --------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* 用户私有的宏定义 ----------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* 用户私有的宏  -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* 用户私有的变量声明 --------------------------------------------------------*/
/* USER CODE BEGIN PV */

/* USER CODE END PV */

/*   用户私有的函数原型声明    -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/*  用户私有的代码   ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @概要     应用程序入口点。
  * @返回值 整型
  */
int main(void)
{
  /* 用户代码开始 1 */

  /* 用户代码结束 1 */

  /* MCU配置--------------------------------------------------------*/

  /* 复位所有外设,初始化Flash接口和SysTick。 */
  HAL_Init();

  /* 用户代码开始 初始化 */

  /* 用户代码结束 初始化 */

  /* 配置系统时钟 */
  SystemClock_Config();
  /* 用户代码开始 系统初始化 */

  /* 用户代码结束 系统初始化 */
  
  /* 用户代码开始 初始化所有配置的外设 */
  MX_GPIO_Init();
  /* 用户代码开始 2 */

  /* 用户代码结束 2 */

  /* 无限循环 */
  /* 用户代码开始 主循环任务 */ 
  while (1)
  {
   /* 用户代码开始 3 */
    HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_SET);  /* 将LED0 PB5置1 */ 
    HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);/* 将LED1 PE5置0 */ 
    HAL_Delay(500);
    HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_RESET);/* 将LED0 PB5置0 */
    HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);  /* 将LED1 PE5置1 */
    HAL_Delay(500);
   /* 用户代码结束 3 */
  }
   /* 用户代码结束 主循环任务 */  
}

/**
  * @概要    系统时钟设置
  * @返回值 None*/
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** 根据指定参数初始化 RCC 振荡器
    * 在 RCC_OscInitTypeDef 结构中。
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** 初始化 CPU、AHB 和 APB 总线时钟
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              						 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* 用户代码开始 4 */

/* 用户代码结束 4 */

/**
  * @概要    发生错误时执行此函数.
  * @返回值 None*/
void Error_Handler(void)
{
  /* 用户代码开始 错误处理调试 */
  /* 用户可以添加自己的实现来报告 HAL 错误返回状态 */
  __disable_irq();
  while (1)
  {
  }
  /* 用户代码结束 错误处理调试 */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  报告源文件的名称和源行号
  *              发生assert_param错误的地方。
  * @param  file:  指向源文件名的指针
  * @param  line: assert_param 错误行源编号
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* 用户代码开始 6 */
  /* 用户可以添加自己的实现来报告文件名和行号,
     例如: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* 用户代码结束 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) 版权所有 意法半导体 *****END OF FILE文件结束****/

四、总结

在这里插入图片描述

  • 82
    点赞
  • 222
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咖喱年糕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值