STM32基于HAL库流水灯实验
一.搭建STM32的开发环境
(一)安装jdk
由于STM32CubeMX是Java实现的,需要安装jdk环境。
jdk官网下载链接:
https://www.oracle.com/java/technologies/javase-downloads.html
(二)安装STM32CubeMX
1.下载地址:
https://www.st.com/en/development-tools/stm32cubemx.html
安装的过程就不一一赘述了,网上教程很多。
二.HEL库GPIO端口3只LED红绿灯的周期闪烁
(一)新建cubeMX工程
1.新建File->Project
2.进入以下界面,我们搜索我们所用的芯片型号,我用的是STM32103C8T6芯片,所以我们在这里搜索STM32F103C8T6,选择芯片
3.进入以下界面,我们开始配置我们需要用到的管教和时钟,这里我们点流水灯的话选择PA4,PB9和系统板自带的PC13管脚,将它们配置为OUTPUT推挽输出模式。
我们先配置sys和rcc
这里sys选择sw模式
rcc这样选择
4.选择端口输出设置,选择需要的端口,点击设置GPIO_OUTPUT,我选择的是PC13,PA4,PB9
5.Clock Configuration设置
6.Project Manager设置
7.创建完成并用keil打开
2.流水灯代码
进入KEIL软件以下编程页面,在main.c中找到main函数,在while循环中添加以下代码
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // 灯1亮
HAL_Delay(1000); // 延时1s
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); // 灯1灭
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET); // 灯2亮
HAL_Delay(1000); // 延时1s
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET); // 灯2灭
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); // 灯3亮
HAL_Delay(1000); // 延时1s
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); // 灯3灭
编译烧录即可完成我们的流水灯的程序。
三.外部中断模式控制灯亮灭
(一)外部中断
STM32的中断是由硬件引起的,用于处理特定事件。当这些事件发生时,处理器会暂停当前的程序执行,转而处理这些中断。处理完成后,程序会从暂停处继续执行。
STM32的中断系统包括多个中断源,例如:
GPIO中断:当GPIO引脚的电平发生变化时,会产生GPIO中断。
定时器中断:STM32的定时器可以生成定时中断。
UART、I2C或SPI通信中断:当这些通信接口有数据接收或发送时,会产生中断。
ADC、DAC或RTC中断:这些组件在完成一次转换或达到预设的时间点时,会产生中断。
DMA中断:当DMA(Direct Memory Access)传输完成时,会产生中断。
Cortex-M3核心的中断:包括系统、调试和存储器保护等中断。
在编程时,你需要配置并启用这些中断源。你可以使用STM32的HAL库或者直接使用Cortex-M的中断处理API进行编程。在STM32CubeMX工具中,你也可以使用图形界面来配置并启用中断。
以下是启用和处理中断的基本步骤:
1.配置中断源:在对应的初始化函数中,你需要开启你想要的中断源。例如,如果你想要使用定时器中断,你需要在定时器的初始化函数中开启定时器中断。
2.设置中断优先级:你可以使用NVIC(Nested Vectored Interrupt Controller)设置每个中断的优先级。STM32CubeMX工具可以帮助你设置这些优先级。
3.编写中断服务函数:你需要为每个中断源编写一个中断服务函数(Interrupt Service Routine, ISR)。这个函数会在对应的中断发生时被调用。这个函数需要尽可能快地执行,避免阻塞其他的中断。
4.开启中断:在主程序中,你需要开启你配置的所有中断。你可以使用HAL_NVIC_EnableIRQ函数来开启一个特定的中断。
5.在ISR中处理中断:当一个中断发生时,处理器会跳转到对应的ISR中执行。在这个函数中,你可以处理这个中断。例如,如果你在等待一个外部事件,当这个事件发生时(例如,一个GPIO引脚的电平发生变化),你可以在ISR中读取这个引脚的状态,并处理这个事件。
6.退出ISR:在ISR的末尾,你应该使用__NOPUSH宏来确保你不会将当前堆栈帧压入堆栈。这可以避免在退出ISR后,程序跳转回ISR中间的代码。
在主程序中处理中断:当一个中断发生时,主程序会暂停执行,跳转到对应的ISR中执行。当ISR执行完成后,主程序会从暂停的地方继续执行。
(二)STMCube配置项目
这里我们使用的是GPIO中断,在管脚PB1电平发生高低变化时,触发我们的GPIO中断,程序中断,处理中断事件,完成之后继续执行主程序
所以在进行编程之前,我们需要先去STM32CubeMX中配置我们的管脚
进入以下界面,选择PB5管脚当我们的按键开关管脚
选择模式为GPIO_EXIT,即GPIO中断,然后我们配置NVIC,点击GPIO,进入以下界面
点击NVIC ,我们使能中断并设置优先级
之后我们在GPIO配置触发模式,设置为下降沿触发
配置完成之后,即可完成项目创建,生成代码
在生成的代码中我们可以看到,在stm32f1xx_it.c中可以找到我们的中断服务程序,点击跳转
往下找到HAL_GPIO_EXTI_Callback这个函数
该函数是给用户自己重写的,可以在这里根据不同的中断来执行不同的处理。在这里我们需要根据B5的不同中断来实现A4的亮灭。
函数代码
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
if(GPIO_Pin == SWITCH_Pin){
//获取B5的电位
GPIO_PinState pinState = HAL_GPIO_ReadPin(SWITCH_GPIO_Port,SWITCH_Pin);
//低电位
if(pinState==GPIO_PIN_RESET)
HAL_GPIO_WritePin(LED_A4_GPIO_Port,LED_A4_Pin,GPIO_PIN_RESET);//把A4变为低电位
//高电位
else
HAL_GPIO_WritePin(LED_A4_GPIO_Port,LED_A4_Pin,GPIO_PIN_SET);//把A4变为高电位
}
}
之后我们编译烧录即可完成使用按键中断控制led流水灯的熄灭
四.总结
本次流水灯实验,理清了流水灯的原理,首先是包括GPIO配置、设置 GPIOx 某个引脚的默认电平,配置 GPIOx 引脚号、输入/输出方式、输出速度/输入类型。实现流水效果(main 函数),需要一个 while 循环,保持程序一直运行,调用延时函数 HAL_Delay(1000),延时1000s,实现流水效果。使用STM32 HAL库可以简化GPIO操作,实现方便、快速、稳定的LED控制。通过初始化GPIO端口,设置引脚模式为输出模式,可以使用HAL_GPIO_WritePin函数控制LED灯的点亮和熄灭。在中断模式下,通过配置中断线,关联中断处理函数,可以在按键按下时实时改变LED灯的状态。实验表明,STM32 HAL库为开发者提供了高效、稳定的硬件操作解决方案。