我们通过点亮一个LED来深入的了解STM32CubeMX,(点亮LED是我刚接触单片机写的第一个程序,就像刚开始学习编程时打印的“Hello World ”)
一、新建工程
这里我们建立一个新的工程(工程建立参考STM32CubeMX初识),STM32我们选用STM32F407ZG,我们的硬件平台用的是原子的探索者开发板,这个开发版上有两个LED,我们通过STM32CubeMX生成一个MDK-ARM工程,并在这个工程里让LED闪烁。首先我们看看这个开发板的原理,看两个LED接在那两个IO口上,
这里我们可以看到这两个LED接在PF9、PF10上,好我们现在开始操作STM32CubeMX:
我们来选择时钟源,这个开发板上有一个8M的外部晶振,那我们就在RCC这里选择外部高速时钟,(有关32的时钟源,我们单独再来讨论),
我们配置IO口,在要配置的IO口上左键单击,弹出对话框,这里我们要让这个IO口驱动LED那么我们就选GPIO_Output,输出模式(黄色引脚为该功能的GPIO已被用作其他功能,可以忽略。绿色表示管脚已使用)
上图中我们可以自己设定当前IO口的名称,在该IO口右击弹出对话框 选择Enter User Label,进行修改,比如我PF9控制LED1,那我就命名LED1。这个在后面写程序很有用
点击左侧的GPIO可以看你当前在使用的IO口,单击该IO口你可以设置其参数,有IO口 初始状态、工作模式、是否上拉或者下来及速度,我们这个只是简单的驱动一个LED,所以其IO口配置为,初始状态低电平,(从前面图中可以看出,探索者开发板的LED低电平点亮)模式为推完输出,既不上拉也不下拉,IO口速度为低速。(STM32的8种工作模式我们单独在其他地方讨)
我们配置时钟树,
1、我们在上面的时钟源RCC里选择的是外部高速时钟,这里我的开发板上用的是一个8M的晶振,所以我这里填写8,
2、这里锁相环倍频输出,M为分频器,N为倍频器倍频系数 ,P为分频器分频系数 ,
这样的话主PLLCLK是怎么计算的呢:PLL=HSE×N/(M×P),
我这里HSE为外部晶振8M,分频器 M=4,倍频器倍频系数 N=168,分频器分频系数 P=2
这样我们的PLLCLK计算出来为168MHz
3、我们系统时钟频率为168MHz,这里AHB分频器为1,也就是不分频,这里我不需要去考虑STM32的功耗,所以不管是系统时钟频率还是一些外设的时钟频率(4)都是设置为其最大值,这里当PLL锁相环倍频的参数不知道该如何设置时,你可以在HCLK(MHz)这里输入你想要的频率(注意不能超出STM32的频率范围)敲回车键,软件会将自动为你配置PLL锁相环倍频的参数。
有关STM32的配置就完了,我们准备开始生成代码
这里主要是设置项目名称、生成代码存放的地址、和选择IDE
这里主要显示你当前所选的STM32及你所用的HAL库的版本。安装好STM32CubeMX,他会在你的CUsers下生成一个STM32Cube文件夹,HAL库就放在这里,默认没有任何HAL库的,有两种方式获得,一种是如下图
在这里可以直接下,
一种是在网上找资源下,下载好后复制到STM32Cube文件夹的Repository中
这里是对要生成的文件及HAL库的一些设置,一般选择默认,我的话会额外在Generated files框,勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP。这个就是将外设初始化为独立的C文件和头文件。
这里的设置我们暂时用不到默认就行,后期用到我们在讨论,
当一切设置妥当,我们点击右上角的GENERATE CODE 生成代码,生成成功后我们可以直接打开这个工程。
在指定的文件夹下会生成以下文件,第一个文件放一些外设系统配置等文件,第二文件夹是放生成的HAL库,第三个文件夹是IDE(我的时MDK-ARM)工程文件以及编译过程中产生的一些文件,最后一个LED.ioc是STM32CubeMX工程文件。
这是我们刚才生成的工程,大家可以看到启动的文件、HAL库、系统配置文件都自动添加好了,很方便,我们编译了一下没有错误,
我们现在开始编写让LED闪烁的代码
在写代码时有一个地方一定要注意,就是我们自己编写的代码一定要写在这里
/* USER CODE BEGIN 1 */ //开始
/* USER CODE END 1 */ //结束
如果不写在这个里面,那当返回STM32CubeMX去增加一些配置时,再次生成代码时他会将你写的代码清除,在默认的配置设置里有一项保留用户代码,但这个前提代码要写在这里
大家可以看到STM32CubeMX会根据你的配置生成相应的函数,我们进MX_GPIO_Init();看看
```c
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9|GPIO_PIN_10, GPIO_PIN_RESET);
/*Configure GPIO pins : PF9 PF10 */
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
}
大家可以看到这里的配置和我们在STM32CubeMX中设置的一样并且已帮你使能时钟。
我们开始写让LED闪烁的代码,
首先我们到stm32f4xx_hal_gpio.h中找到HAL库就对GPIO操作的函数
我们这里是要改变IO口的状态那就选用函数void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);这个函数里可以看到有三个参数:第一个是那组IO口,第二是IO口标号,第三个是要写入的状态,
大家在找到main.h这个头文件,大家会发现,这里用我们在STM32CubeMX中修改的IO名称进行了宏定义,这样在后续写代码中会让我们很清晰的知道这个IO口用于干什么。
while (1)
{
/* USER CODE END WHILE */
HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET);
HAL_Delay(1000);
HAL_GPIO_WritePin(LED2_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET);
HAL_Delay(1000);
/* USER CODE BEGIN 3 */
}
在main函数中的while循环中写入我们的代码,其中HAL_Delay(1000);是HAL库自带的一个延时函数,单位是ms,那我们这几行代码就是让两个灯以1秒的频率闪烁。
其中GPIO_PIN_SET为1(也就将IO口电平拉高) GPIO_PIN_RESET为0(也就是将IO口的电平拉低)。这个在stm32f4xx_hal_gpio.h中用一个枚举型的数据结构进行了定义`/**
- @brief GPIO Bit SET and Bit RESET enumeration
*/
typedef enum
{
GPIO_PIN_RESET = 0,
GPIO_PIN_SET
}GPIO_PinState;
/**`
编写完程序,进行编译,没有错误,就将程序烧入STM32,我用的下载器是J-LINK,下载方式我选择SWD,JTAG比较占资源,右上角能显示STM的IDCODE说明成功连接到了STM32,然后烧入验证程序,
好了这样我们就用STM32CubeMX完成了我们这样一个小小的点亮LED的功能。
我们通过点亮一个LED来深入的了解STM32CubeMX,(点亮LED是我刚接触单片机写的第一个程序,就像刚开始学习编程时打印的“Hello World ”)
一、新建工程
这里我们建立一个新的工程(工程建立参考STM32CubeMX初识),STM32我们选用STM32F407ZG,我们的硬件平台用的是原子的探索者开发板,这个开发版上有两个LED,我们通过STM32CubeMX生成一个MDK-ARM工程,并在这个工程里让LED闪烁。首先我们看看这个开发板的原理,看两个LED接在那两个IO口上,
这里我们可以看到这两个LED接在PF9、PF10上,好我们现在开始操作STM32CubeMX:
我们来选择时钟源,这个开发板上有一个8M的外部晶振,那我们就在RCC这里选择外部高速时钟,(有关32的时钟源,我们单独再来讨论),
我们配置IO口,在要配置的IO口上左键单击,弹出对话框,这里我们要让这个IO口驱动LED那么我们就选GPIO_Output,输出模式(黄色引脚为该功能的GPIO已被用作其他功能,可以忽略。绿色表示管脚已使用)
上图中我们可以自己设定当前IO口的名称,在该IO口右击弹出对话框 选择Enter User Label,进行修改,比如我PF9控制LED1,那我就命名LED1。这个在后面写程序很有用
点击左侧的GPIO可以看你当前在使用的IO口,单击该IO口你可以设置其参数,有IO口 初始状态、工作模式、是否上拉或者下来及速度,我们这个只是简单的驱动一个LED,所以其IO口配置为,初始状态低电平,(从前面图中可以看出,探索者开发板的LED低电平点亮)模式为推完输出,既不上拉也不下拉,IO口速度为低速。(STM32的8种工作模式我们单独在其他地方讨)
我们配置时钟树,
1、我们在上面的时钟源RCC里选择的是外部高速时钟,这里我的开发板上用的是一个8M的晶振,所以我这里填写8,
2、这里锁相环倍频输出,M为分频器,N为倍频器倍频系数 ,P为分频器分频系数 ,
这样的话主PLLCLK是怎么计算的呢:PLL=HSE×N/(M×P),
我这里HSE为外部晶振8M,分频器 M=4,倍频器倍频系数 N=168,分频器分频系数 P=2
这样我们的PLLCLK计算出来为168MHz
3、我们系统时钟频率为168MHz,这里AHB分频器为1,也就是不分频,这里我不需要去考虑STM32的功耗,所以不管是系统时钟频率还是一些外设的时钟频率(4)都是设置为其最大值,这里当PLL锁相环倍频的参数不知道该如何设置时,你可以在HCLK(MHz)这里输入你想要的频率(注意不能超出STM32的频率范围)敲回车键,软件会将自动为你配置PLL锁相环倍频的参数。
有关STM32的配置就完了,我们准备开始生成代码
这里主要是设置项目名称、生成代码存放的地址、和选择IDE
这里主要显示你当前所选的STM32及你所用的HAL库的版本。安装好STM32CubeMX,他会在你的CUsers下生成一个STM32Cube文件夹,HAL库就放在这里,默认没有任何HAL库的,有两种方式获得,一种是如下图
在这里可以直接下,
一种是在网上找资源下,下载好后复制到STM32Cube文件夹的Repository中
这里是对要生成的文件及HAL库的一些设置,一般选择默认,我的话会额外在Generated files框,勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP。这个就是将外设初始化为独立的C文件和头文件。
这里的设置我们暂时用不到默认就行,后期用到我们在讨论,
当一切设置妥当,我们点击右上角的GENERATE CODE 生成代码,生成成功后我们可以直接打开这个工程。
在指定的文件夹下会生成以下文件,第一个文件放一些外设系统配置等文件,第二文件夹是放生成的HAL库,第三个文件夹是IDE(我的时MDK-ARM)工程文件以及编译过程中产生的一些文件,最后一个LED.ioc是STM32CubeMX工程文件。
这是我们刚才生成的工程,大家可以看到启动的文件、HAL库、系统配置文件都自动添加好了,很方便,我们编译了一下没有错误,
我们现在开始编写让LED闪烁的代码
在写代码时有一个地方一定要注意,就是我们自己编写的代码一定要写在这里
/* USER CODE BEGIN 1 */ //开始
/* USER CODE END 1 */ //结束
如果不写在这个里面,那当返回STM32CubeMX去增加一些配置时,再次生成代码时他会将你写的代码清除,在默认的配置设置里有一项保留用户代码,但这个前提代码要写在这里
大家可以看到STM32CubeMX会根据你的配置生成相应的函数,我们进MX_GPIO_Init();看看
```c
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9|GPIO_PIN_10, GPIO_PIN_RESET);
/*Configure GPIO pins : PF9 PF10 */
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
}
大家可以看到这里的配置和我们在STM32CubeMX中设置的一样并且已帮你使能时钟。
我们开始写让LED闪烁的代码,
首先我们到stm32f4xx_hal_gpio.h中找到HAL库就对GPIO操作的函数
我们这里是要改变IO口的状态那就选用函数void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);这个函数里可以看到有三个参数:第一个是那组IO口,第二是IO口标号,第三个是要写入的状态,
大家在找到main.h这个头文件,大家会发现,这里用我们在STM32CubeMX中修改的IO名称进行了宏定义,这样在后续写代码中会让我们很清晰的知道这个IO口用于干什么。
while (1)
{
/* USER CODE END WHILE */
HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET);
HAL_Delay(1000);
HAL_GPIO_WritePin(LED2_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET);
HAL_Delay(1000);
/* USER CODE BEGIN 3 */
}
在main函数中的while循环中写入我们的代码,其中HAL_Delay(1000);是HAL库自带的一个延时函数,单位是ms,那我们这几行代码就是让两个灯以1秒的频率闪烁。
其中GPIO_PIN_SET为1(也就将IO口电平拉高) GPIO_PIN_RESET为0(也就是将IO口的电平拉低)。这个在stm32f4xx_hal_gpio.h中用一个枚举型的数据结构进行了定义`/**
- @brief GPIO Bit SET and Bit RESET enumeration
*/
typedef enum
{
GPIO_PIN_RESET = 0,
GPIO_PIN_SET
}GPIO_PinState;
/**`
编写完程序,进行编译,没有错误,就将程序烧入STM32,我用的下载器是J-LINK,下载方式我选择SWD,JTAG比较占资源,右上角能显示STM的IDCODE说明成功连接到了STM32,然后烧入验证程序,
好了这样我们就用STM32CubeMX完成了我们这样一个小小的点亮LED的功能。
举报