目录
0. STM32F446产品概要
1. 实验任务
2. 硬件原理
3. 利用STM32CubeMX创建MDK工程
3.1 STM32CubeMX工程创建
3.2 配置GPIO
3.3 配置时钟电路
3.3.1 使用片内时钟
3.3.2 使用外部时钟
3.4 项目配置
3.5 代码生成设置
4.在MDK中编辑工程
4.1 代码编辑说明
4.2 修改代码
4.3 关于找不到V5编译器报错的解决方法
5. 在开发板上下载验证
6. HAL库函数学习
6.1 HAL_GPIO_WritePin函数介绍
6.2 HAL_Delay函数介绍
6.3 HAL_GPIO_TogglePin函数
6.4 HAL_GPIO_ReadPin函数介绍
6.5 HAL_GPIO_Ini和HAL_GPIO_DeInit函数
6.6 HAL_GPIO_LockPin函数介绍
6.7 HAL_GPIO_EXTI_IRQHandler函数介绍
6.8 HAL_GPIO_EXTI_Callback函数介绍
7. 总结
STM32F446产品系列是高度集成的节能产品,具有高性能和丰富的连接性,Flash最小为256KB。
它利用ST的专有ART Accelerator™、智能架构、先进的Flash技术及其嵌入式ARM Cortex-M4内核,实现了225 DMIPS和608 CoreMark® 的领先性能(180MHz频率下从嵌入式Flash执行)。
通过多个接口进行高效并发通信,使工业、科技、医疗以及物联网(Internet-of-Things,IoT)应用更加智能并具有更多交互,同时先进的处理技术和动态电压调节、广泛的时钟门控以及灵活的睡眠模式实现了有效的节能。
STM32F446系列产品在小至3.85 x 3.728 mm的封装内提供了256~512KB Flash、128KB SRAM和64~144个引脚。
STM32 Nucleo-64板为用户提供了一种可负担的灵活方法,通过选择STM32微控制器提供的各种性能和功耗特性组合来尝试新概念并构建原型。对于兼容板,外部SMPS可显著降低运行模式下的功耗。
实验采用STM32F446RE MCU的STM32 Nucleo-64(NUCLEO-F446RE)开发板,利用STM32CubeMX,创建MDK工程,实现流水灯。
核心板原理图:
扩展板原理图:
选择File下的New Project:
利用开发板创建工程(NUCLEO-F446RE),选择下边的item,然后Start Project:
以NUCLEO-F446RE开发板为模版创建的工程如下:
结合开发版的硬件电路,进行GPIO设置
选择GPIO,依次将PC4、PB13、PB14设置为GPIO_Output:
结合开发版的硬件电路,选择Clock Configuration,时钟配置有两种方式:
使用STM32F4芯片的片内时钟时,做如下配置:
Nucleo开发板没有焊接外部时钟,需要用户自行焊接X3、C33、C34、R35、R37。原理图见本文第二部分,实物见下图。
使用外部时钟时,上图中开发板需焊接的X3(8MHz)、C33、C34(20PF)、R36、R37),焊接后 的实物在本文末尾。在STM32CubeMX中,做如下配置:
在Project Manager下的Project中设置工程名称和工程路径,并选择编译软件。取消勾选Use lastest available version,选择其他版本:
在Code Generate中选择第二个,然后Generate Code,即生成代码:
可以打开MDK工程编辑了。
点击上图中的Open Folder,可以看到STM32CubeMX自动建立了与工程名同名的文件夹,并将工程存在该文件夹下。生成的MDK工程及源文件也至于该文件夹内。
文件夹MDK-ARM内是项目工程及编译文件
由STM32CubeMX生成的代码,为用户预留了用户代码区,所有自己编写的代码,请放在:
/* USER CODE BEGIN XXX */
和
/* USER CODE END XXX */之间。
这样我们修改工程的时候你自己写的代码就不会被删除。
打开Keil文件后点击Application,在 main.c 文件里的 while(1) 循环内的
/* USER CODE BEGIN 3 */
和
/* USER CODE END 3 */
之间添加以下代码:
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_RESET); // LED亮
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET); // LED灭
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET); // LED灭
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_SET); // LED灭
HAL_Delay(500); // 延时 500ms
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_SET); // LED亮
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET); // LED灭
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET); // LED灭
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_RESET); // LED灭
HAL_Delay(500); // 延时 500ms
见下图:
编译代码:
由于自MDK5.37开始,AC5(ARMCC)编译器不再默认安装,需要独立安装。没安装AC5编译器的同学,会出现如下报错:
请将编译器设置为Version 6,方法如下图:
如果你需要AC5编译器,请参考如下博文安装设置:
Keil MDK5.37以上版本自行添加AC5(ARMCC)编译器的方法_armcc下载 :
Keil MDK5.37以上版本自行添加AC5(ARMCC)编译器的方法_armcc下载_笑春风oO的博客-CSDN博客
编译程序,确定产生0个错误,就可以进入调试或下载了。可通过下载器将程序下载到开发板中验证或进行在线调试。下载方法很多,可以使用ISP方式,如果你需要在线调试,则必须仿真器,如Ulink、ST-Link等。
点击上图中的Settings:
后续的内容中会将在线调试,点击下载按钮,将程序下载到STM32:
下载后,在开发板上观察流水灯效果。
【STM32F446,NUCLEO-F446RE板】流水灯
HAL库中提供一个操作GPIO电平的函数:HAL_GPIO_WritePin函数
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
函数名 |
HAL_GPIO_WritePin |
函数作用 |
使得对应的引脚输出高电平或者低电平 |
返回值 |
Void |
参数1:GPIOx |
对应GPIO总线,其中x可以是A…I。 例如PH10,则输入GPIOH |
参数2:GPIO_Pin |
对应引脚数。可以是0-15。例如PH10,则输入GPIO_PIN_10 |
参数3:PinState |
GPIO_PIN_RESET:输出低电平;GPIO_PIN_SET:输出高电平 |
HAL库提供了用于毫秒级延迟的函数,HAL_Delay函数(使用_weak修饰符说明该函数是可以用户重定义的)。
__weak void HAL_Delay(uint32_t Delay);
函数名 |
HAL_Delay |
函数作用 |
使系统延迟对应的毫秒级时间 |
返回值 |
Void |
参数:Delay |
对应的延迟毫秒数,比如延迟1秒就为1000 |
HAL库中提供一个反转GPIO电平的函数。
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
函数名 |
HAL_GPIO_TogglePin |
函数作用 |
翻转对应引脚的电平 |
返回值 |
Void |
参数1:GPIOx |
对应GPIO总线,其中x可以是A…I。 例如PH10,则输入GPIOH |
参数2:GPIO_Pin |
对应引脚数。可以是0-15。例如PH10,则输入GPIO_PIN_10 |
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
功能:读取引脚的电平状态、函数返回值为0或1
实例:pin_State = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_9);
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
功能: GPIO初始化
实例:HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);
功能:在函数初始化之后的引脚恢复成默认的状态,即各个寄存器复位时的值
实例:HAL_GPIO_Init(GPIOC, GPIO_PIN_4);
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
功能:锁住引脚电平,比如说一个管脚的当前状态是1,当这个管脚电平变化时保持锁定时的值。
实例:HAL_StatusTypeDef hal_State;
hal_State = HAL_GPIO_LockPin(GPIOF, GPIO_PIN_9);
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
功能: 外部中断服务函数,清除中断标志位。函数实体里面有两个功能,1是清除中断标记位,2是调用下面要介绍的回调函数。实际调用的是下边的中断回调函数
实例:HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
功能: 中断回调函数,可以理解为中断函数具体要响应的动作。
实例:HAL_GPIO_EXTI_Callback(GPIO_PIN_4);