目录
6.5 HAL_GPIO_Ini和HAL_GPIO_DeInit函数
6.7 HAL_GPIO_EXTI_IRQHandler函数介绍
6.8 HAL_GPIO_EXTI_Callback函数介绍
0. STM32F446产品概要
STM32F446产品系列是高度集成的节能产品,具有高性能和丰富的连接性,Flash最小为256KB。
它利用ST的专有ART Accelerator™、智能架构、先进的Flash技术及其嵌入式ARM Cortex-M4内核,实现了225 DMIPS和608 CoreMark® 的领先性能(180MHz频率下从嵌入式Flash执行)。
通过多个接口进行高效并发通信,使工业、科技、医疗以及物联网(Internet-of-Things,IoT)应用更加智能并具有更多交互,同时先进的处理技术和动态电压调节、广泛的时钟门控以及灵活的睡眠模式实现了有效的节能。
- 性能:在180 MHz频率下,从Flash执行时,STM32F446能够提供225 DMIPS/608 CoreMark性能,并且利用意法半导体的ART加速器实现了FLASH零等待状态。 DSP指令和浮点运算单元扩大了产品的应用范围。
- 功效:该系列产品采用意法半导体90 nm工艺和ART加速器,具有动态功耗调整功能,能够在运行模式下和从Flash存储器执行时实现低至200 µA/MHz的电流消耗(@ 180 MHz)。 停机模式下,功耗为50 µA(典型值)。
- 集成:
- 2个专用音频PLL,SPDIF输入,3路半双工I²S和2路串行音频接口(SAI),支持全双工I²S和时分复用(TDM)模式。
- 多达20个通信接口(包括4个USART、2个速度达11.25 Mbit/s的UART、4个速度达45 Mbit/s的SPI、3个具有新型可选数字滤波器功能的I²C、2个CAN、SDIO、HDMI CEC以及摄像头接口)
- 两个12位DAC、三个速度为2 MSPS或7.2 MSPS(交错模式)的12位ADC定时器多达17个:频率高达180 MHz的16和32位定时器
- 使用灵活的90 MHz存储控制器可以轻松扩展存储范围,带有一个32位的并行接口,能支持Compact Flash、SRAM、PSRAM、NOR、 NAND以及SDRAM存储器
- 由于90MHz Dual quadSPI接口支持内存映射模式,可进行经济实惠的NOR闪存扩展
STM32F446系列产品在小至3.85 x 3.728 mm的封装内提供了256~512KB Flash、128KB SRAM和64~144个引脚。
1. 实验任务
STM32 Nucleo-64板为用户提供了一种可负担的灵活方法,通过选择STM32微控制器提供的各种性能和功耗特性组合来尝试新概念并构建原型。对于兼容板,外部SMPS可显著降低运行模式下的功耗。
实验采用STM32F446RE MCU的STM32 Nucleo-64(NUCLEO-F446RE)开发板,利用STM32CubeMX,创建MDK工程,实现流水灯。
2. 硬件原理
核心板原理图:
扩展板原理图:
3. 利用STM32CubeMX创建MDK工程
3.1 STM32CubeMX工程创建
选择File下的New Project:
利用开发板创建工程(NUCLEO-F446RE),选择下边的item,然后Start Project:
以NUCLEO-F446RE开发板为模版创建的工程如下:
3.2 配置GPIO
结合开发版的硬件电路,进行GPIO设置
选择GPIO,依次将PC4、PB13、PB14设置为GPIO_Output:
3.3 配置时钟电路
结合开发版的硬件电路,选择Clock Configuration,时钟配置有两种方式:
3.3.1 使用片内时钟
使用STM32F4芯片的片内时钟时,做如下配置:
3.3.2 使用外部时钟
Nucleo开发板没有焊接外部时钟,需要用户自行焊接X3、C33、C34、R35、R37。原理图见本文第二部分,实物见下图。
使用外部时钟时,上图中开发板需焊接的X3(8MHz)、C33、C34(20PF)、R36、R37),焊接后 的实物在本文末尾。在STM32CubeMX中,做如下配置:
3.4 项目配置
在Project Manager下的Project中设置工程名称和工程路径,并选择编译软件。取消勾选Use lastest available version,选择其他版本:
3.5 代码生成设置
在Code Generate中选择第二个,然后Generate Code,即生成代码:
可以打开MDK工程编辑了。
点击上图中的Open Folder,可以看到STM32CubeMX自动建立了与工程名同名的文件夹,并将工程存在该文件夹下。生成的MDK工程及源文件也至于该文件夹内。
文件夹MDK-ARM内是项目工程及编译文件
4.在MDK中编辑工程
4.1 代码编辑说明
由STM32CubeMX生成的代码,为用户预留了用户代码区,所有自己编写的代码,请放在:
/* USER CODE BEGIN XXX */
和
/* USER CODE END XXX */之间。
这样我们修改工程的时候你自己写的代码就不会被删除。
4.2 修改代码
打开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
见下图:
编译代码:
4.3 关于找不到V5编译器报错的解决方法
由于自MDK5.37开始,AC5(ARMCC)编译器不再默认安装,需要独立安装。没安装AC5编译器的同学,会出现如下报错:
请将编译器设置为Version 6,方法如下图:
如果你需要AC5编译器,请参考如下博文安装设置:
Keil MDK5.37以上版本自行添加AC5(ARMCC)编译器的方法_armcc下载 :
Keil MDK5.37以上版本自行添加AC5(ARMCC)编译器的方法_armcc下载_笑春风oO的博客-优快云博客
5. 在开发板上下载验证
编译程序,确定产生0个错误,就可以进入调试或下载了。可通过下载器将程序下载到开发板中验证或进行在线调试。下载方法很多,可以使用ISP方式,如果你需要在线调试,则必须仿真器,如Ulink、ST-Link等。
点击上图中的Settings:
后续的内容中会将在线调试,点击下载按钮,将程序下载到STM32:
下载后,在开发板上观察流水灯效果。
【STM32F446,NUCLEO-F446RE板】流水灯
6. HAL库函数学习
6.1 HAL_GPIO_WritePin函数介绍
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:输出高电平 |
6.2 HAL_Delay函数介绍
HAL库提供了用于毫秒级延迟的函数,HAL_Delay函数(使用_weak修饰符说明该函数是可以用户重定义的)。
__weak void HAL_Delay(uint32_t Delay);
函数名 | HAL_Delay |
函数作用 | 使系统延迟对应的毫秒级时间 |
返回值 | Void |
参数:Delay | 对应的延迟毫秒数,比如延迟1秒就为1000 |
6.3 HAL_GPIO_TogglePin函数
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 |
6.4 HAL_GPIO_ReadPin函数介绍
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
功能:读取引脚的电平状态、函数返回值为0或1
实例:pin_State = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_9);
6.5 HAL_GPIO_Ini和HAL_GPIO_DeInit函数
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);
6.6 HAL_GPIO_LockPin函数介绍
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);
6.7 HAL_GPIO_EXTI_IRQHandler函数介绍
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
功能: 外部中断服务函数,清除中断标志位。函数实体里面有两个功能,1是清除中断标记位,2是调用下面要介绍的回调函数。实际调用的是下边的中断回调函数
实例:HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
6.8 HAL_GPIO_EXTI_Callback函数介绍
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
功能: 中断回调函数,可以理解为中断函数具体要响应的动作。
实例:HAL_GPIO_EXTI_Callback(GPIO_PIN_4);
7. 总结