硬件消抖按键模块采用硬件消除按键的抖动,在学习测试新型号单片机时是非常好的工具。本文选用源地的CH32V103C8T6的最小核心板进行了测试。
消抖按键模块
源地CH32V103C8T6核心板
刚开始的按键测试程序,如下:
u8 inputFlag;
while(1)
{
inputFlag=GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
if(inputFlag==0)
{
printf("Input is Active\r\n");
}
}
运行后通过串口助手发现,当按键按下,串口就接收到大量数据,可以想见是程序导致的,因为按键一直为低(虽然只有几十毫秒),所以单片机一直发送信息。
改进1
u8 inputFlag;
while(1)
{
inputFlag=GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
if(inputFlag==0)
{
printf("Input is Active\r\n");
Delay_Ms(100);//增加的延时,超过按键按下的时间
}
}
效果可以,但感觉使用太占用CPU.
改进2
u8 inputFlag;
u8 inputFlagOld;//增加的记录按键过去状态
while(1)
{
inputFlag=GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
if(inputFlag!=inputFlagOld)//如果新旧状态不一致,则认为按键已经按下
{
printf("Input is Active\r\n");
}
inputFlagOld=inputFlag;
}
}
取消了延时,也消除了大量串口输出,但按键抬起时也会触发一次串口输出。
改进3
u8 inputFlag;
u8 inputFlagOld;//增加的记录按键过去状态
while(1)
{
inputFlag=GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
if((inputFlag!=inputFlagOld)&&(inputFlag==0))//如果新旧状态不一致,则认为按键已经按下
{ //且只有按键按下才发送数据
printf("Input is Active\r\n");
}
inputFlagOld=inputFlag;
}
}
效果很好!按键按下只触发一次串口输出。
完整代码
/********************************** (C) COPYRIGHT *******************************
* File Name : main.c
* Author : armxu
* Version : V1.0.0
* Date : 2020/04/30
* Description : 演示硬件消抖按键的单次触发串口输出。基于MounRiver Studio
*******************************************************************************/
#include "debug.h"
/* Global typedef */
/* Global define */
u8 inputFlag,inputFlagOld;
/* Global Variable */
void GPIO_INPUT_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/*******************************************************************************
* Function Name : main
* Description : Main program.
* Input : None
* Return : None
*******************************************************************************/
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
Delay_Init();
GPIO_INPUT_INIT();
USART_Printf_Init(115200);
printf("SystemClk:%d\r\n",SystemCoreClock);
printf("This is printf example\r\n");
while(1)
{
inputFlag=GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
if((inputFlag!=inputFlagOld)&&(inputFlag==0))
{
printf("Input is Active\r\n");
}
inputFlagOld=inputFlag;
}
}