STM32——HAL库开发笔记14(按键控制LED灯实验)(参考来源:b站铁头山羊)

本实验使用一枚按钮来切换板载LED的亮/灭状态,每按一次,亮/灭切换一次。

一、电路图

连接图

二、编程思路

当我们按下按钮时,LED状态不变,当我们松开按钮时,LED的状态才会发生变化。因此,我们需要捕捉按钮状态变化的瞬间。那么我们如何捕捉呢?我们可以申明两个变量 pre 和 cur。其中pre保存按钮上一次的值,cur保存按钮当前值,按键抬起为1,按键按下为0。我们不断更新pre和cur的值。当pre = cur 时,按键状态未发生变化,当 pre ≠ cur时,我们就可以捕捉到按键变化的瞬间。

当pre = 1 , cur = 0时,按键按下;当pre = 0 , cur = 1时,按键抬起。

三、CubeMX配置

最后生成代码,打开工程。

四、代码

我们在工程的main.c文件中进行代码编写,找到main.c文件的while循环处。

代码编写在上图的begin和end之间。

	uint8_t pre = 1,cur = 1;// 申明两个变量并且赋值1,代表当前按键处于松开状态
    uint8_t ledstate = 0;   //用来保存当前LED的状态  0 ——熄灭 ;1 ——点亮。
  
  while (1)
  {
     pre = cur ; //更新pre的值
     if( HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_SET)//读取PA0上的电压,如果是高电压
      { 
         cur = 1; //给cur赋值为1
      }
     else {        //读到低电压
         cur = 0;
          } 
     if (pre != cur)   //捕捉到了按动动作
        {
          if (cur = 0)    //按键按下的动作
             {
        
             }
           else   //按键抬升的动作
             {
               if(ledstate == 0)       //如果当前LED熄灭
                 {
                   HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);    //点亮LED
                   ledstate = 1;  //更新ledstate状态
                 }
               else   //当前LED点亮
                 {
                   HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);    //熄灭LED
                   ledstate = 0;  //更新ledstate状态
                 }
             }
        }
		
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

我们编译下载到单片机里面会发现有时候按键失灵,这是由于按键抖动引起的,我们再对其进行消抖。

按键的抖动时间一般不会超过10ms ,所以我们检测到按动动作之后延迟10ms就可以解决。

加入消抖代码。

	uint8_t pre = 1,cur = 1;// 申明两个变量并且赋值1,代表当前按键处于松开状态
    uint8_t ledstate = 0;   //用来保存当前LED的状态  0 ——熄灭 ;1 ——点亮。
  
  while (1)
  {
     pre = cur ; //更新pre的值
     if( HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_SET)//读取PA0上的电压,如果是高电压
      { 
         cur = 1; //给cur赋值为1
      }
     else {        //读到低电压
         cur = 0;
          } 
     if (pre != cur)   //捕捉到了按动动作
        {
          HAL_Delay(10);     //按键消抖
          if (cur = 0)    //按键按下的动作
             {
        
             }
           else   //按键抬升的动作
             {
               if(ledstate == 0)       //如果当前LED熄灭
                 {
                   HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);    //点亮LED
                   ledstate = 1;  //更新ledstate状态
                 }
               else   //当前LED点亮
                 {
                   HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);    //熄灭LED
                   ledstate = 0;  //更新ledstate状态
                 }
             }
        }

最终,我们就可以实现自由切换LED的亮灭状态。

### 铁头山羊 STM32 HAL 示例代码 #### 使用HAL初始化I2C通信并操作OLED屏幕 为了实现通过I2C接口与OLED屏交互的功能,下面展示一段基于STM32 HAL的示例代码。这段代码展示了如何配置I2C外设以及执行简单的读写命令。 ```c #include "stm32f1xx_hal.h" // 定义I2C句柄结构体变量 I2C_HandleTypeDef hi2c1; void I2C_Init(void){ __HAL_RCC_I2C1_CLK_ENABLE(); // 启用I2C时钟 hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 100000; // 设置SCL频率为100kHz hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK){ Error_Handler(); } } uint8_t WriteToSlave(uint8_t slaveAddr, uint8_t reg, uint8_t *pData, uint16_t size){ if(HAL_I2C_Mem_Write(&hi2c1, slaveAddr << 1, reg, I2C_MEMADD_SIZE_8BIT, pData, size, 100)!= HAL_OK){ return 1; }else{ return 0; } } uint8_t ReadFromSlave(uint8_t slaveAddr, uint8_t reg, uint8_t *pData, uint16_t size){ if(HAL_I2C_Mem_Read(&hi2c1, slaveAddr << 1, reg, I2C_MEMADD_SIZE_8BIT, pData, size, 100)!= HAL_OK){ return 1; }else{ return 0; } } ``` 上述代码实现了基本的I2C初始化过程,并提供了`WriteToSlave()`用于向指定地址的从设备寄存器写入数据;而`ReadFromSlave()`则负责从特定位置读取所需长度的数据[^1]。 对于具体的OLED显示控制部分,则需参照具体型号的数据手册编写相应的指令集来完成画面刷新等工作。通常情况下,会有一个专门针对某种品牌或类型的显示屏驱动程序可供调用。 当涉及到实际应用中的硬件连接时,请务必确认所使用的开发板上已经正确安装了对应的外围电路元件,并且连线无误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值