蓝桥杯嵌入式组 学习笔记(HAL库学习)__ 四、按键(定时器中断)

基本每届必考(长按、短按、双击)

 原理:    1、判断引脚高低电平,按下接GND,引脚为0,反之。

                2、使用定时器中断,每隔一段时间扫描引脚电平,做判断。

一、cubemx

配置gpio

PB0/1/2和PA0->GPIO_inout

gpio->gpio pull-up(上拉)

配置定时器(通用可选tim2\3\4)

tim3->clock source->internal clock(内部时钟 前文80mhz)

prescaler(预分频)->80-1     (80000000/80=1000000(决定工作频率))

counter period /arr(重装载值)->10000-1  (1000000/10000=100hz(10ms中断一次->扫描一次按键))

nvic settings->enabled√(使能nvic)

二、keil

创建新文件interrupt.c/.h

//interrupt.c
#include "interrupt.h"                  // Device header

struct keys key[4]={0,0,0};
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
//该中断回调函数可在函数库xxxxhal_tim.h 复制
{
	if(htim->Instance==TIM3)
	{
			  key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
			  key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
			  key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
			  key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
			  
			  for(int i=0;i<4;i++)
			  {
				  switch(key[i].judge_sta)
				  {
					  case 0:
					  {
						  if(key[i].key_sta==0) 
						  {
							  key[i].judge_sta=1;
						  }
					  }
					  break;
					  case 1://消抖
					  {
						  if(key[i].key_sta==0)
						  {
							  key[i].judge_sta=2;
							  key[i].single_flag=1;
						  }
                          else
                          {
                              key[i].judge_sta=0;
                          }
					  }
					  break;
					  case 2://松手
					  {
						    if(key[i].key_sta==1)
						  {
							  key[i].judge_sta=0;
						  }
					  }
					  break;
				  }
			  } 
	}
} 
//interrupt.h
#ifndef __INTERRUPT_H_
#define __INTERRUPT_H_

#include "main.h"                
#include "stdbool.h" 

struct keys
{
	uchar judge_sta;   //判断进行到哪一步
	bool key_sta;      //01两种状态,是否被按下,按下为0
	bool single_flag;  //按下转为1
};

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);

#endif

回到main.c  添加

#include "interrupt.h"

/* Private typedef ----*/
/* USER CODE BEGIN PTD */

extern struct keys key[];

/* USER CODE END PTD */


HAL_TIM_Base_Start_IT(&htim3); (打开tim3)

while(1)
{  
	  if(key[0].single_flag==1)
	  {
		  sprintf(text," key0 down      ");
	      LCD_DisplayStringLine(Line8, (unsigned char *)text);
		  key[0].single_flag=0;
	  }
	  	  if(key[1].single_flag==1)
	  {
		  sprintf(text," key1 down      ");
	      LCD_DisplayStringLine(Line8, (unsigned char *)text);
		  key[1].single_flag=0;
	  }
}

参考手册p76

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值