stm32f1按键检测使用外部中断以及定时器延时方式去抖

发布者:shmilyde最新更新时间:2018-12-27 来源: eefocus关键字:stm32f1  按键检测  外部中断  定时器  延时方式 手机看文章 扫描二维码
随时随地手机看文章

本来一个按键检测是很简单的功能,在大学的时候做的51单片机矩阵键盘更要复杂,但是如果要在操作系统中使用按键并且很好的去除抖动,不影响整个rtos系统的运行,保证中断不会长时间占用CPU,达到快进快出的目的。就需要另外启动一个定时器来完成计时功能(比如去抖20ms)后,产生定时器中断后再次检测按键电平。


    一般51或stm32按键检测流程:


#define key1 GPIOC_11

 

void delay(uint32_t n )

{

while(n--);

}

 

void key_detected()

{

    if (key1 == 0)

    {

        delay(20);

  if (ke1 == 0)

            printf("key1 be pressed!!!\r\n");

        else

      return ;

    }

}

 

while(1)

{

    key_detected();

}

    这样的delay()可以达到去抖的目的,但是实现方式太过暴力,在延时的时候一直占用cpu的资源,如果在延时的时候,有其他外部中断或者抢占事件,系统完全没有响应的。所以我们CPU需要一个独立的定时装置,来完成这个计时工作,而且需要在计时时间到达时再检测一次按键的电平值。


    我的r8t6资源有限,所以使用TIM1和它的定时溢出(update)中断。


    首先初始化管脚,打开管脚的外部中断:


/*Configure GPIO pins : KEY_1_Pin KEY_2_Pin */

GPIO_InitStruct.Pin = KEY_1_Pin|KEY_2_Pin;

GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;

GPIO_InitStruct.Pull = GPIO_NOPULL;

HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);


/* EXTI interrupt init*/

HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0);

HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

    初始化TIM1,打开其update中断:


static void MX_TIM1_Init(void)

{

htim1.Instance = TIM1;

htim1.Init.Prescaler = 7200 - 1;                // 72000000 / 7200 = 10000 hz  0.01ms

htim1.Init.CounterMode = TIM_COUNTERMODE_UP;

htim1.Init.Period = 200 - 1;                    // 200 * 0.01 = 20ms

htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

htim1.Init.RepetitionCounter = 0;

htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;


if (HAL_TIM_Base_Init(&htim1) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}


}

这个在stm32f1xx_hal_msp.c中

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base){ if(htim_base->Instance==TIM1) {/* Peripheral clock enable */ __HAL_RCC_TIM1_CLK_ENABLE();/* USER CODE BEGIN TIM1_MspInit 1 */HAL_NVIC_SetPriority(TIM1_UP_IRQn,1,3); HAL_NVIC_EnableIRQ(TIM1_UP_IRQn); }}

在stm32f1xx_hal_it.c中去注册中断回调函数(关键的步骤,需要在按键中断处理函数中打开定时器,开始计时):


void EXTI15_10_IRQHandler(void)            // 按键的中断处理函数

{

 

HAL_TIM_Base_Start_IT(&htim1);    //  开启定时器1,开始计时

 

printf("key down\r\n");

 

__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_11);

__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_12);

}

定时器的中断处理函数:


void TIM1_UP_IRQHandler(void)

{


HAL_TIM_IRQHandler(&htim1);   //这个是所有定时器处理回调的入口,在这个函数里对应定时器多种中断情况的中断回调,需要找到update的回调函数

printf("TIM IRQ\r\n");

 

}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)        // 定时器update中断处理回调函数

{

/* USER CODE BEGIN Callback 0 */

 

/* USER CODE END Callback 0 */

if (htim->Instance == TIM2) {

   HAL_IncTick();

}

 

if (htim->Instance == TIM1) {            // 在这里选择tim1 

 

printf("TIM1 updata\r\n");

 

HAL_TIM_Base_Stop_IT(&htim1);       //    关闭tim1 及清除中断

 

if (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_11) )    //再次判断管脚的电平

{

printf("KEY1 be pressed!!!\r\n");

}


if (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_12) )//再次判断管脚的电平

{

printf("KEY2 be pressed!!!\r\n");

}

}

/* USER CODE BEGIN Callback 1 */

 

/* USER CODE END Callback 1 */

}


总结一下,实现用定时器中断来完成按键延时去抖的关键步骤:


1. 初始化GPIO管脚,初始化TIM ,算好时间,填入分频值。


2. 打开GPIO中断,在中断处理函数中打开定时器,让其计数。


3. 定时器溢出中断函数中,再次判断按键电平值。关闭定时器,清除pending。



关键字:stm32f1  按键检测  外部中断  定时器  延时方式 引用地址:stm32f1按键检测使用外部中断以及定时器延时方式去抖

上一篇:Stm32定时器中断触发AD采样
下一篇:stm32pwm简单程序

推荐阅读最新更新时间:2024-03-16 16:21

STM32的几种输入模式以及外部中断的配置
  要求:将连接按键的IO口配置为上拉输入,按键一端接IO口,一端接地,即当按键按下后,该IO口会产生一个下降沿,触发下降沿中断。   问题:将相应的IO口配置好后,测了引脚的的电压,并不是3.3V左右,而是0.1V左右。于是猜想:   1. 外围电路对IO口产生了影响。   2. STM32内部上拉能力较弱,一次只能上拉一个IO口。   于是开始从这两个想法着手解决。首先第一个,很容易就排除了。将外围电路撤掉,我用的是杜邦线,直接拔掉测量引脚上的电压,依然是0.1V左右,于是第1个猜想排除。   第二个,查看万能的参考手册,发现每一个IO口都是有独立的驱动电路,这样第2个也排除了。   最后各种纠结,然后发现:在主函数的开头部分
[单片机]
Tiny4412中断控制器(GIC)之外部中断
#include regs.h void enable_mmu(unsigned long ttb); void init_ttb(unsigned long *ttb_base); void mmap(unsigned long *ttb_base, unsigned long va, unsigned long pa); void memset(char *buf, char ch, int size); void memcpy(char *dst, char *src, int size); void do_irq(unsigned long regs ); void (*printf)(char *, ...) = 0x
[单片机]
51定时器外部中断
#include reg52.h #define uint unsigned int #define uchar unsigned char sbit p2_0=P2^0; sbit p2_2=P2^1; sbit p2_4=P2^2; uchar num=11; uchar tt=0; uchar bai,shi,ge,bai1,num1; uchar code table = {~0x3f,~0x06,~0x5b,~0x4f, ~0x66,~0x6d,~0x7d,~0x07, ~0x7f,~0x6f,~0x77,~0x7c, ~0x39,~0x5e,~0x79,~0x71}; void delay(uint z)
[单片机]
STM32--外部中断
这是我经过几天,的努力最终把外部中断解决了,这篇日志我将终结几下问题 一:外部中断的配置步骤     二:配置的技巧以及如何快速配置   三:自己出现的问题  一:外部中断的配置步骤 1. 加入必要的头文件,且platform_config.h需手动复制到工程文件夹下; 2 void RCC_Configuration(void); 全局时钟的配置相映的时钟,这更STM32处理器总线结构有关 3 void GPIO_Configuration(void); GPIO的初始化设置输入输出, 注意别忘
[单片机]
定时器3-计时示例
_ :16位定时器自动重装,60ms定时周期,LED闪烁 _ :连接方式:将任意一个LED的引脚和P1.2相连 _ :实验现象:LED以60ms为周期闪烁。 1 /*----------------------------------------------- 2 名称:定时器2 3 论坛:www.doflye.net 4 编写:shifang 5 内容:通过定时让LED灯闪烁 6 ------------------------------------------------*/ 7 #include reg52.h //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 8 9 sbit L
[单片机]
C51编程15-中断篇(定时器中断2)
使用定时器/计数器中断,需要将满足以下的条件。 1)中断总允许打开 EA = 1; 2)中断源允许打开 ET0 = 1或者 ET1= 1; 3)设置定时器计/计数器的工作方式(设置TMOD) 4)装载定时器,设置计数器的初始计算值。 5)开启定时器(TCON中的TR0 = 1或者TR1 = 1) 6)中断服务函数 在满足上面的条件后,就使用定时器了,但为了对定时器的4种方式更深入的了解,下面从逻辑图上讲解4种方式。 方式0: 逻辑结构图 从上面的逻辑结构图中,逻辑结构主要分为三个部分; 1)计数源:计数源可以选择振荡器12分频(机器周期);计数源也可以选择T0(P3.4)引脚。当C/
[单片机]
C51编程15-中断篇(<font color='red'>定时器</font>中断2)
labview中的的几种定时器
LABVIEW提供了几种定时器(包括DELAY),如下图所示 首先看看Tick Count 节点的帮助说明: 返回毫秒定时器的值. 基准参考时间(0 毫秒)未定义,也就是说,不能把返回的毫秒数直接转换成现实世界的时间和日期.必须注意当你使用这个函数进行比较的时候,毫秒定时器达到2^32-1后反转成0. 基准参考时间未定义,说法比较模糊,难道会是个随机数,那显然不可能,如果是随机数,那两次调用 TI CK COUNT取得差值就不可能表示经过的毫秒数.无论如何,必须有个时间的起点. API函数中也有一个类似的函数:GetTickCount,该函数返回计算机启动以来经过的毫秒数.在9X中,它读取的是BIOS中保存的系统时钟
[测试测量]
labview中的的几种<font color='red'>定时器</font>
具有四个输出并基于微处理器的双定时器
基于Freescale半导体公司MCC908QY型8位闪存微型计算机的图1所示电路,可提供一个低成本通用双定时器,该定时器可代替单触发电路。您可以通过修改汇编语言软件来满足特定应用要求。该电路采用微处理器 IC1的内部12.8MHz 时钟振荡器。内部时钟除以4即获得3.2 MHz时钟频率,此频率进一步除以定时器预定比例 64即获得50 kHz时钟。将定时器模数计数器除以 50000,可获得可产生1次/秒实时中断与主定时间隔 的1Hz 时基。   每组4个的两组开关(S3至S6及S7至S10),分别以1"16秒的递量设置时间间隔 t1和 t2。尽管该图只给出了单独的DIP 开关,但您也可采用十六进制编码的旋钮式开关来设置时
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved