历史上的今天
返回首页

历史上的今天

今天是:2024年12月27日(星期五)

正在发生

2018年12月27日 | stm32f1按键检测使用外部中断以及定时器延时方式去抖

2018-12-27 来源:eefocus

本来一个按键检测是很简单的功能,在大学的时候做的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。



推荐阅读

史海拾趣

诚芯微(CXW)公司的发展小趣事

在2017年,诚芯微被认定为国家高新技术企业,这是对公司技术实力和创新能力的高度肯定。获得这一荣誉后,诚芯微进一步加大了研发投入,加强了与高校和科研机构的合作,推动了公司技术的持续创新。同时,公司还扩大了产能,优化了供应链管理,提升了市场竞争力。

DURABLE公司的发展小趣事

在竞争激烈的电子行业中,DURABLE公司深知单打独斗难以取得长远发展。因此,公司积极寻求与其他行业的跨界合作机会。通过与汽车制造商、医疗设备制造商等行业的合作,DURABLE成功将自身的技术优势应用于更多领域的产品中。这种跨界合作模式不仅拓宽了公司的业务领域和收入来源,还为公司带来了更多的创新灵感和市场机遇。通过与其他行业的合作,DURABLE实现了资源共享和优势互补,实现了共赢发展。

Franz Binder GmbH & Co公司的发展小趣事

在电子材料领域取得初步成功后,DURABLE公司意识到市场拓展的重要性。公司开始积极拓展海外市场,与全球知名电子产品制造商建立合作关系。通过深入了解不同地区的市场需求和消费者偏好,DURABLE不断调整产品策略,推出符合当地市场需求的产品。同时,公司还加强了与渠道合作伙伴的合作,通过完善的销售网络和售后服务体系,提升了产品的市场占有率和客户满意度。

3L Electronic Corporation公司的发展小趣事

随着国内市场的饱和,3L Electronic Corporation开始将目光投向国际市场。公司积极参与国际展览和贸易活动,与全球知名企业建立合作关系。同时,公司还在海外设立分支机构和研发中心,进一步拓展国际业务。这些举措不仅提升了公司的知名度,也为公司的长期发展注入了新的活力。

Global Mixed-Mode Technology Inc公司的发展小趣事
三相缺相报警灯电路的工作原理基于三相电的平衡性。当三相电中的任意一相缺失时,会导致电路不平衡,从而触发报警机制。通常,该电路会使用中间继电器或专门的缺相检测芯片来监测三相电的电压情况。一旦检测到缺相,就会通过继电器或芯片的控制,使报警灯亮起或发出声音警报,以提醒用户及时处理。
BusBoard Prototype Systems公司的发展小趣事

在发展过程中,BusBoard Prototype Systems深知单打独斗难以取得长远的发展。因此,公司积极寻求与上下游企业的合作,共同推动电子行业的发展。通过与芯片制造商、软件开发商等建立紧密的合作伙伴关系,BusBoard不仅能够获得更优质的资源支持,还能够为客户提供更加全面的解决方案。

问答坊 | AI 解惑

超级单片机开发工具!! 很实用哦!

!!!超级单片机开发工具!!!   单片机开发过程中用到的多功能工具,包括热敏电阻RT值--HEX数据转换;3种LED编码;色环电阻计算器;HEX/BIN 文件互相转换;eeprom数据到C/ASM源码转换;CRC校验生成;串口调试,带简单而实用的数据分 ...…

查看全部问答>

基于AT89C52单片机的SD卡的读写设计

长期以来,以Flash Memory为存储体的SD卡因具备体积小、功耗低、可擦写以及非易失性等特点而被广泛应用于消费类电子产品中。特别是近年来,随着价格不断下降且存储容量不断提高,它的应用范围日益增广。当数据采集系统需要长时间地采集、记录海量数 ...…

查看全部问答>

到底应该选择哪种无线技术?

底应该选择哪种无线技术?---- 各种无线技术简介及其选择 摘要:本文将简要介绍各种无线技术,包括:红外线、蓝牙技术、Zigbee技术、自组织网络、Wi-Fi技术、射频识别技术(RFID)、实时定位服务(RTLS)、微波存取全球互通技术(WiMax)、大功 ...…

查看全部问答>

辩题讨论-硬件工程师好还是软件工程师好?

我想每个学电子的,都会为自己的发展方向而忧愁过。在选择从事方向时不知道就行选择哪一个?   究竟是做硬件好还是做软件好,还是全部都做?   希望网友能说是你的看法,给为选择的人们一定指引。。。…

查看全部问答>

ucos中的OSUnMapTbl原理在硬件中的应用?

ucos中的OSUnMapTbl是一个很大的静态数组,提高查找速度 以前看过一个网页说 这中设计思想在硬件设计中也有应用,固化在芯片中什么的, 烦请请高手指点一下。…

查看全部问答>

大家一般怎么采购电子元器件?

我一般是在华强电子网上搜,华强上面的商家一般是深圳广州的,然后逐个打电话去问,网上显示有货也不一定有货。不知道大家一般怎么买元器件。…

查看全部问答>

【MSP430共享】基于智能检测技术的室内照明系统

以MSP430单片机为核心,采用检测单元阵列进行人体检测,并结合自然光检测,实现照明系统的只能控制,解决了传统节能照明控制系统存在的检测不准确、可靠性不高的问题,达到了节能目的。实际应用验证了方案的可行性,具有良好的实用价值。 [ 本帖最 ...…

查看全部问答>

求帮助设计一个关于电梯运行的控制电路

一个四层楼的建筑,两个电梯:电梯1和电梯2要求:1,当处于某层的一个人按动“呼叫”命令时,距离他较近的电梯到来;           2,如果两个电梯和这个人距离一样,则“电梯1”到来        &nbs ...…

查看全部问答>

How to deliver employee's welfare?

The high welfare of valley song on the other hand can keep a talented person, can deliver the information of \"the valley song has good business enterprise quality\" to the north face denali external world on the other hand.As lon ...…

查看全部问答>

430F169AD采样工作有间断期

#include #define   Num_of_Results   8 uint ADC_BUF0[Num_of_Results]; uint ADC_BUF1[Num_of_Results]; uint sumI;            //定义电流采样均值 uint sumV;    ...…

查看全部问答>