目录
6.5 HAL_GPIO_Ini和HAL_GPIO_DeInit函数
6.7 HAL_GPIO_EXTI_IRQHandler函数介绍
6.8 HAL_GPIO_EXTI_Callback函数介绍
1. 实验任务
利用STM32CubeMX,创建MDK工程,实现流水灯。
2. 硬件原理
3. 利用STM32CubeMX创建MDK工程
选择File下的New Project:
选择芯片类型(本文为stm32f103RBt6),选择下边的item,然后Start Project:
点击左侧的System Core下的SYS,将Debug设置为Serial Wire:
配置时钟:将RCC下的HSE设置为Crystal/Ceramic Resonator
结合开发版的硬件电路,进行GPIO设置
选择GPIO,依次将PA8、PD2设置为GPIO_Output:
结合开发版的硬件电路,选择Clock Configuration,做如下配置:
项目配置:
在Project Manager下的Project中设置工程名称和工程路径,并选择编译软件。取消勾选Use lastest available version,选择其他版本:
代码生成设置:
在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(GPIOA,GPIO_PIN_8,GPIO_PIN_RESET);
//LED0 对应引脚 PA8 拉低,亮
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
//LED1 对应引脚 PD2 拉高,灭
HAL_Delay(500); //延时 500ms
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_SET);
//LED0 对应引脚 PA8 拉高,灭
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
//LED1 对应引脚 PD2 拉低,亮
HAL_Delay(500); //延时 500ms
见下图:
编译代码:
4.3 关于找不到V5编译器报错的解决方法
由于自MDK5.37开始,AC5(ARMCC)编译器不再默认安装,需要独立安装。没安装AC5编译器的同学,会出现如下报错:
请将编译器设置为Version 6,方法如下图:
如果你需要AC5编译器,请参考如下博文安装设置:
Keil MDK5.37以上版本自行添加AC5(ARMCC)编译器的方法_armcc下载 :
https://blog.youkuaiyun.com/qcmyqcmy/article/details/125814461
5. 调试
5.1 虚拟仿真
使用KEIL的软件仿真的逻辑分析仪功能观察GPIO的波形,可以较为方便地定位到程序中的问题。
(1)点击上方菜单栏中的options for target设置
(2)虚拟仿真设置
在Debug界面中,勾选Use Simulator,在Run to main()选项上打勾,将Dialog.DLL修改为DARMSTM.DLL,Parameter是跟你使用的单片机的型号有关的,此处为-pSTM32F103RB,设置后点击OK,完成设置。
注意:
在Debug设置里,须对下面两项内容进行更改:
Dialog DLL栏更改为DARMSTM.DLL
Parameter栏更改为-pSTM32F103RB
Options for target的Debug选项卡中的参数说明:
SARMCM3.DLL是一个动态链接库,名称SARMCM3表示是ARM Cortex-M3架构
DCM.DLL、TCM.DLL同理,表示Cortex-M系列。
参数-pCM3表示Cortex-M3系列的参数。
由于Cortex-M3只是个大框架,具体的厂商实现细节不一样,实际仿真时,建议修改得具体点。
DARMSTM.DLL、TARMSTM.DLL(参考下方5.3节的设置图片)指明了是STMicroelectronics(意法半导体)的ARM架构的产品。
(3)点击Debug,进入调试
完成上述设置后,点击编译,Debug按钮:
5.2 虚拟仿真中的逻辑分析仪使用
设置完成后,开启调试模式,打开逻辑分析仪:
逻辑分析仪界面如下:
给逻辑分析仪中添加要观察的IO口,添加方法很多,此处介绍直接输入管脚的方法:
直接以 PORTX >> X 的形式输入,内容取决于代码中定义的管脚
本实例中,用到了PA8和PD2口,在逻辑分析仪中点击setup:
如下图:依次输入:PORTA >> 8 和 PORTD >> 2 。将Display Type 设置为 Bit 。然后点击 Close。
注意:务必将上图中管脚的 Display Type 设置为 Bit !
设置好之后,逻辑分析仪左侧会出现刚才设置的两个IO口,点击调试工具栏中的全速运行,执行一段时间后,点击停止按钮即可。
点击逻辑分析仪中的Zoom All,查看全图,得到的波形图如下:
如果波形有问题,可借助逻辑分析仪中的工具,对波形详细分析:
5.3 在开发板上下载验证
编译程序,确定产生0个错误,就可以进入调试或下载了。
程序编译后,可通过下载器将程序下载到开发板中验证或进行在线调试。下载方法很多,可以使用ISP方式,如果你需要在线调试,则必须仿真器,如Ulink、ST-Link等。
点击上图中的Settings:
后续的内容中会将在线调试,点击下载按钮,将程序下载到STM32:
下载后,在开发板上观察流水灯效果。
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. 总结