基于STM32F103C8T6(HAL库)和CubeMX使用定时器TIM中断扫描按键,避免delay造成的程序堵塞,实现按键控制LED灯

在按键的使用过程中,很多人使用delay延时函数进行按键的消抖,delay函数可能会堵塞程序的运行,而使用定时器TIM进行按键的使用能够有效的避免程序堵塞的问题,下面就是有关于使用TIM实现按键的使用

1.硬件连接

按键的一端PB0
按键的另一端GND
LED长脚(+)PA1
LED短脚(-)GND

2.TIM、按键以及LED的cubemx配置

定时器TIM

开启Internal Clock以及中断使能TIM3

配置TIM中断时间为T=10ms,PSC=72-1,ARR=10000-1

TIM的中断时间T计算

T=1/F

F=时钟源频率/(预分频系数+1)/(自动重装载值+1)=72 000 000/(PSC+1)/(ARR+1)

时钟源频率:stm32f103c8t6一般默认为72KHz,我们配置的时钟树是多少就是多少(如下图)

预分频系数PSC:

降低计数频率:将定时器的输入时钟源分频,得到更低的计数频率

扩展定时范围:   通过降低计数频率,定时器计数器(Counter)的每个“步进”时间变长,从而允许在有限的计数器位数(如16位)下实现更长的定时周期。

自动重装载值ARR:

定义计数周期:定时器从 0 开始计数,当达到 ARR 值时触发中断或更新事件,随后自动重置为 0。

控制中断频率:ARR 直接决定了定时器中断的间隔时间。较小的 ARR 值会频繁触发中断,较大的 ARR 值则减少中断频率。

按键

按键PB0设置为上拉输入,在stm32f103c8t6系统板上一部分IO内部自带上、下拉电阻。

LED灯

LED灯PA1设置为推挽输出,初始电平为Low

3.LED和KEY的封装函数以及main.c

LED的封装函数void led_p(uint8_t mode)

void led_p(uint8_t mode)//LED封装函数 mode=0灯灭 mode=1灯亮
{
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);//将PA1输出低电平,灯熄灭
    if(mode)
    {
       HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);//将PA1输出高电平,灯点亮
    }
    else
    {
       HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);//将PA1输出低电平,灯熄灭
    }
}

KEY的封装函数调用TIM的中断回调函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

volatile uint8_t  j = 0;//变量j和key_number声明为volatile,防止可能主循环中读取错误的值
volatile uint8_t  key_number = 0;

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
    if (htim->Instance == TIM3) {
        uint8_t k = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0);
        switch (j) {
            case 0:
                if (k == 0) j = 1;  // 首次检测到按下
                break;
            case 1:
                if (k == 0) j = 2;  // 二次确认,去抖
                else j = 0;
                break;
            case 2:
                if (k == 1) {       // 释放时触发
                    key_number = 1;
                    j = 0;         // 立即复位
                }
                break;
        }
    }
}

中断回调函数:当中断触发时,系统调用预先注册的回调函数来处理中断逻辑。

主函数main.c

HAL_TIM_Base_Start_IT(&htim3);

开启定时器中断,一定不要忘记

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      if(key_number==1)//按键按下之后LED灯点亮1S
      {
         led_p(1);
         HAL_Delay(1000);
         led_p(0);
         key_number=0;
      }
  }

烧录代码即可实现相应内容:按键按下之后LED灯点亮1S

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值