STM32在CubeMX使用HAL库实现按键控制流水灯亮灭

一、在CubeMX创建项目

已配置好java环境和CubeMX。
CubeMX官网下载传送门:CubeMX - 工具与软件

1.第一步
在这里插入图片描述
2.第二步
在这里插入图片描述
3.第三步
在这里插入图片描述
将CubeMX中的"DEBUG"栏目设置为"Serial Wire"
意味着你选择了Serial Wire Debug(SWD)接口作为调试接口。
SWD是一种调试接口协议,通常用于与ARM Cortex-M微控制器进行调试和编程交互。

当你选择SWD接口时,它将作为与目标芯片之间的调试通信通道。SWD接口使用两根线进行通信:SWDIO(Serial Wire Debug I/O)和SWCLK(Serial Wire Debug Clock)。SWDIO用于数据传输和调试信息的收发,而SWCLK用于时钟同步。

通过使用SWD接口进行调试,你可以实现以下功能:

  • 单步执行(Single Step):逐条指令地执行代码,方便调试程序的运行过程。
  • 断点(Breakpoint):在特定代码行设置断点,使程序执行到断点处停止,以便进行逐步调试。
  • 寄存器查看与修改:查看和修改目标芯片的寄存器值,以便分析和调试程序状态。
  • 调试信息输出:通过SWD接口将调试信息输出到开发环境,如调试器或仿真器。

总之,选择将CubeMX中的"DEBUG"栏目设置为"Serial Wire"意味着你选择了SWD接口作为调试接口,以便进行嵌入式软件的调试和开发。

4.第四步
在STM32F103C8T6微控制器中,GPIO口是通过APB2总线进行控制和访问的。
在这里插入图片描述
在STM32F103C8T6微控制器中,HSE(High-Speed External)LSE(Low-Speed External)分别用于控制不同的外部时钟源。

  1. HSE(高速外部时钟):

    • 主时钟(SYSCLK):HSE可以作为主时钟源,提供较高的时钟频率。通过适当的配置和分频系数,可以将HSE的频率作为系统时钟(SYSCLK)。
    • PLL(锁相环)输入:HSE可以作为PLL的输入时钟源,用于生成更高的时钟频率。通过配置PLL参数,可以将HSE的频率倍增并输出为SYSCLK。
  2. LSE(低速外部时钟):

    • RTC(实时时钟):LSE被用作STM32F103C8T6的RTC模块的时钟源。RTC模块用于提供实时时钟和日历功能,可以用于时间戳记录、定时器和闹钟功能等。

注意:STM32F103C8T6微控制器还可以使用内部时钟源(HSILSI)作为主时钟和RTC时钟源。HSI是内部高速时钟,而LSI是内部低速时钟。选择使用HSELSE作为时钟源是根据具体需求和应用场景来决定的。

在STM32F103C8T6微控制器中,APB2总线的时钟并不直接由HSE(高速外部时钟)控制。APB2总线的时钟源可以选择来自系统时钟(SYSCLK)或者从PLL(锁相环)输出的时钟。

在STM32F103C8T6中,HSE可以作为主时钟(SYSCLK)的输入源之一,通过PLL倍频后输出。主时钟(SYSCLK)可以进一步分频得到APB2总线的时钟。

具体来说,时钟源的配置如下:
1. 如果HSE被配置为主时钟(SYSCLK)的输入源,那么APB2总线的时钟也将来自HSE通过PLL的输出。
2. 如果HSE没有被配置为主时钟(SYSCLK)的输入源,而是使用内部时钟源(如HSI),那么APB2总线的时钟将与主时钟(SYSCLK)相同,来自HSI或者通过PLL倍频后输出的HSI。

因此,APB2总线的时钟源是与主时钟(SYSCLK)相关的,并不直接由HSE控制。配置主时钟(SYSCLK)的时钟源,间接地影响了APB2总线的时钟频率。

所以,为了通过APB2控制GPIO口,这里选择将将HSE设置为Crystal/Ceramic Resonator

5.第五步
在这里插入图片描述
根据需要配置相应的管脚,点击并选择管脚模式即可。这里选择GPIO_Output,输出模式。
在这里插入图片描述
我在A8的地方加了一个按键,准备用来做中断控制的实验,选的是GPIO_EXTI8

6.第六步
由上面提供的资料,如果HSE被配置为主时钟(SYSCLK)的输入源,那么APB2总线的时钟也将来自HSE通过PLL的输出。
在这里插入图片描述
所以在时钟架构这个页面选择PLLCLK。

7.第七步

生成代码
在这里插入图片描述

在这里插入图片描述

二、代码编写实现流水灯

1.编写代码并实现

因为重新构建了好几次这个工程,为了方便起见我把管脚改成了这样的设置,别的不变。
在这里插入图片描述
用下面这段代码替换主函数中的while(1){}。

  while (1)
  {		
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);//PA4亮灯
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);//PB9熄灯
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_SET);//PC15熄灯
		HAL_Delay(1000);//延时1s
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);//PA4熄灯
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);//PB9亮灯
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_SET);//PC15熄灯
		HAL_Delay(1000);//延时1s		
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);//PA4熄灯
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);//PB9熄灯
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_RESET);//PC15亮灯
		HAL_Delay(1000);//延时1s
	}

HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);语句的解释:
是GPIO输出的HAL库函数,可以设定或改变当前引脚电平值

HAL_GPIO_WritePin(GPIO_TypeDef* GPIOX,Uint16_t GPIO_Pin,GPIO_PinState pinstate);

GPIOX代表目标引脚的端口号,如GPIOA
GPIO_Pin代表目标引脚的引脚号
pinstate代表当前引脚的高低电平,高电平(GPIO_PIN_SET)、低电平(GPIO_PIN_RESET)。

运行结果如下
在这里插入图片描述

2.观察GPIO端口的输出波形
  1. 在keil中点击魔法棒,进入Target界面,设置晶振为8MHz在这里插入图片描述

  2. 进入Debug界面进行如下设置,最后点击OK在这里插入图片描述

  3. 点击Debug进入调试,打开逻辑分析仪(Logic Analyzer),选择要观察的引脚在这里插入图片描述

  4. 观察波形
    在这里插入图片描述
    动态图如下(图片上传有大小限制所以加了点倍速):
    在这里插入图片描述
    可以观察到引脚为低电平的灯亮,高电平的灯不亮,高低电平转换周期(LED闪烁周期)为1s左右。

三、代码编写实现按键控制流水灯亮灭

1.新建工程

(1)配置中断函数

在这里插入图片描述
在CubeMX中将GPIO模式(GPIO mode)设置为"上升和下降都可触发"(Rising and Falling Edge Triggered)意味着你配置了GPIO引脚的输入触发方式,使其能够在引脚电平上升沿和下降沿发生变化时触发中断或事件。

当你将GPIO模式设置为"上升和下降都可触发"时,GPIO引脚会监测其输入电平的变化,并在引脚电平从低电平(0)变为高电平(1)或从高电平(1)变为低电平(0)时触发相应的中断或事件。

这种触发方式常用于需要对输入信号的变化做出实时响应的应用场景。例如,当一个按钮或开关被按下或释放时,你可以配置相应的GPIO引脚为"上升和下降都可触发"模式,从而使得微控制器能够在按钮按下或释放时立即检测到并执行相应的中断服务程序或处理逻辑。

通过CubeMX配置GPIO模式为"上升和下降都可触发",它将生成相应的初始化代码,以使你能够轻松地设置和使用这种触发方式,并在中断或事件回调函数中处理GPIO引脚的变化。

在GPIO引脚上选择Pull-up或Pull-down电阻的目的是为了确保在引脚未连接到外部设备或信号时,引脚的电平保持在已定义的状态(高电平或低电平),从而避免电平浮动或不确定性。

当GPIO引脚未连接到外部设备时,引脚可能会处于高阻抗状态,这可能导致电平不确定或受到干扰。通过选择Pull-up或Pull-down电阻,可以将引脚拉向预定义的电平,以确保引脚在未连接时有一个已知的状态。
选择Pull-up电阻意味着将引脚连接到Vcc(电源正电压)或逻辑高电平,而选择Pull-down电阻意味着将引脚连接到GND(地)或逻辑低电平。具体选择哪种电阻取决于你的应用需求和电路设计。

一些常见的应用情况包括:

  • 输入引脚:当GPIO引脚用作输入时,选择Pull-up或Pull-down电阻可以确保在未连接外部信号时,引脚保持在已定义的状态,避免电平浮动。例如,当一个开关未被按下时,可以选择Pull-up电阻,使引脚保持高电平;当开关被按下时,引脚会被接地,变为低电平。
  • 输出引脚:选择Pull-up或Pull-down电阻可以帮助确保输出引脚在未连接到其他设备时,保持在预期的电平状态。例如,当你需要将一个引脚作为开关控制信号时,你可以选择Pull-down电阻,使引脚在未连接到其他设备时保持低电平,以确保开关关闭。

通过选择适当的Pull-up或Pull-down电阻,你可以提高GPIO引脚的可靠性和稳定性,减少电平浮动带来的干扰,并确保在引脚未连接时具有可预测的电平状态。

2.进入NVIC界面设置中断优先级

在这里插入图片描述
在CubeMX中,将EXTI线[9:5]的中断设置为"Enabled"表示启用了EXTI线9到EXTI线5之间的中断功能。

将中断优先级设置为1的目的是确保该中断具有较高的优先级,以优先处理该中断。

中断优先级决定了当多个中断同时发生时,哪个中断具有更高的优先级并首先得到处理。较低的优先级值表示较高的优先级。

将中断优先级设置为1意味着将该中断设置为较高的优先级。这对于需要及时响应和处理的重要中断非常重要。例如,如果你有一个实时任务需要在最短的时间内得到响应和处理,你可以将该任务的中断优先级设置为1,以确保它能够尽快得到处理。

3.配置时钟

在这里插入图片描述

4.生成工程文件

在这里插入图片描述

2.编写代码并实现

  • 首先在stm32f1xx_hal_gpio.c里找到这两个函数。将这个Callback回调函数放到main.c中。
    在这里插入图片描述
    这里我设置的是根据A8的不同中断控制流水灯亮灭
    代码逻辑如下:
    首先,通过调用HAL_GPIO_ReadPin函数来读取引脚GPIOA的状态(GPIO_PIN_8)。
    如果引脚状态为GPIO_PIN_SET,即高电平,则将标志位flag设置为1,表示高电位。
    如果引脚状态为GPIO_PIN_RESET,即低电平,则将标志位flag设置为0,表示低电位。

首先定义一个标志位代表高低电平。

uint16_t flag=0;

根据代码逻辑编写中断回调函数

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	
   if(GPIO_Pin == GPIO_PIN_8){//获取A8的电位
	   
   GPIO_PinState pinState = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_8);//高电位
	   
   if(pinState==GPIO_PIN_SET)//高电位流水灯亮
   {
 	  flag=1;//高电位
   }
   
   else if(pinState==GPIO_PIN_RESET)//低电位流水灯灭
   {
 	  flag=0;//低电位
   }
   } 
}

将流水灯控制代码加入到主函数中

while (1)
  {
    if(flag==1){
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);//PA4亮灯
  	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);//PB9熄灯
  	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_SET);//PC15熄灯
  	HAL_Delay(1000);//延时1s
  	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);//PA4熄灯
  	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);//PB9亮灯
  	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_SET);//PC15熄灯
  	HAL_Delay(1000);//延时1s		
  	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);//PA4熄灯
  	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);//PB9熄灯
  	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_RESET);//PC15亮灯
  	HAL_Delay(1000);//延时1s
    }
    else if(flag==0){
      HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);//PA4熄灯
  	  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);//PB9熄灯
  	  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_SET);//PC15熄灯
  	  HAL_Delay(5000);//延时5s
    }
  }

实现结果:
在这里插入图片描述

  • 24
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
首先,需要在STM32F407上连接一个按键和一个LED。按键连接到一个GPIO输入引脚,LED连接到一个GPIO输出引脚。 然后,需要初始化这些引脚。使用HAL库提供的函数可以很方便地完成初始化。下面是一个示例代码: ``` #include "stm32f4xx_hal.h" GPIO_InitTypeDef GPIO_InitStruct; void GPIO_Init(void) { __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); // Initialize button pin (PA0) GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // Initialize LED pin (PC13) GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } ``` 在初始化完成后,需要设置外部中断。使用HAL库提供的函数可以很方便地完成设置。下面是一个示例代码: ``` void EXTI0_IRQHandler(void) { if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); } HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); } void EXTI_Init(void) { // Enable EXTI0 interrupt HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0); HAL_NVIC_EnableIRQ(EXTI0_IRQn); // Configure EXTI0 line EXTI_HandleTypeDef EXTI_InitStruct; EXTI_InitStruct.Line = EXTI_LINE_0; EXTI_InitStruct.Mode = EXTI_MODE_INTERRUPT; EXTI_InitStruct.Trigger = EXTI_TRIGGER_FALLING; EXTI_InitStruct.GPIOSel = EXTI_GPIOA; EXTI_InitStruct.GPIOPin = GPIO_PIN_0; HAL_EXTI_SetConfigLine(&EXTI_InitStruct); } ``` 在设置外部中断完成后,需要启动中断。下面是一个示例代码: ``` int main(void) { HAL_Init(); GPIO_Init(); EXTI_Init(); while (1) { // Do nothing } } ``` 这个示例代码中,当按键被按下时,LED会切换亮灭状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值