一:什么是开关抖动?
二:电路及波形
通过示波器抓取信号的波形如下:
三:硬件去抖动
硬件电路去抖
R-C 去抖
开关去抖IC
四:软件消抖
软件延时
sbit KEY = P1^3;
///按键读取函数
uint8_t GetKey(void)
{
if(KEY == 1)
{
DelayMs(20); //延时消抖
if(KEY == 1)
{
return 1;
}
else
{
return 0;
}
}
else
{
return 0;
}
}
中断消抖
/*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);
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__);
}
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);
}
}
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 */
}
End
欢迎关注我的公众号,回复【加群】限时免费进入技术交流群
(扫码进 技术开发交流群)