使用定时器消除抖动

问题:定时器中断和按键中断属于什么操作模式,轮询吗?

具体怎么实现

借助HAL_GetTick() 实现与定时器的联动

在中断处理函数处修改,在定时器处定时判断,满足条件时才修改;

定时器中断  (判断)        时间参数           按键中断(修改)

中断 向量表.s文件

        DCD     SysTick_Handler            ; SysTick Handler

中断文件中定时器相关的
stm32f1xx_it.c

void SysTick_Handler(void)
{

  HAL_IncTick();//增加计数值,

  extern void check_timer(void);
  check_timer();

}

stm32f1xxx_hal.c 

__weak void HAL_IncTick(void)
{
  uwTick += uwTickFreq;
}

__weak uint32_t HAL_GetTick(void)
{
  return uwTick;
}

main.c

指针的时间和时钟的时间

pTimer结构体包含时间和处理计数值的函数

在系统的时钟处理函数处加上时钟检查函数,check_timer中的if语句限制  指针时间小于等于时钟时间

如果中断,通过中断回调函数让自己指针的时间加10ms,期间若又发生中断,指针时间再加10,

当未发生中断或者中断(n*10)ms内,都不满足进入check_timer中的if函数体的条件;

直至没有抖动时候进入if函数体中,通过定时器函数和check_timer函数调用结构体中的函数,使计数值增加

struct soft_timer {
	uint32_t timeout;
	void * args;
	void (*func)(void *);
};

int g_key_cnt = 0;

void key_timeout_func(void *args);
struct soft_timer key_timer = {~0, NULL, key_timeout_func};
void key_timeout_func(void *args)
{
	g_key_cnt++;
	key_timer.timeout = ~0;
}

void mod_timer(struct soft_timer *pTimer, uint32_t timeout)
{
	pTimer->timeout = HAL_GetTick() + timeout;
}

void check_timer(void)
{
	if (key_timer.timeout <= HAL_GetTick())
	{
		key_timer.func(key_timer.args);
	}
}

、、数据处理的源头,发生中断
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if (GPIO_Pin == GPIO_PIN_14)
	{		
		mod_timer(&key_timer, 10);
	}
}
int main(){
    OLED_Init();	 
	OLED_Clear();   
  OLED_PrintString(0, 4, "Key ISR cnt = ");
  while (1)
  {
	  OLED_PrintSignedVal(0, 6, g_key_cnt);

  }
 
}

stm32f1xx_it.c

          DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10

void EXTI15_10_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI15_10_IRQn 0 */

  /* USER CODE END EXTI15_10_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_14);
  /* USER CODE BEGIN EXTI15_10_IRQn 1 */

  /* USER CODE END EXTI15_10_IRQn 1 */
}

 stm32f1xxx_hal_gpio.c  

数据处理的源头,发生中断

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
  }
}

STM32微控制器中的定时器常常用于检测外部信号,如GPIO引脚的上升沿或下降沿,但是由于实际信号可能会有短暂的波动,这被称为"抖动"。为了消除这个影响,我们通常会使用软件滤波或者硬件辅助机制。 以下是一个基本的使用STM32 TIM(定时器消除GPIO输入抖动的示例代码(假设我们使用的是TIM1和EXTI中断): ```c #include "stm32f1xx_hal.h" // 定义延时函数,这里用到HAL_Delay void delay(__IO uint32_t time); // 当GPIO边缘检测触发时 void EXTI0_IRQHandler(void) { // 首先清除边沿检测标志 EXTI_ClearITPendingBit(EXTI_Line0); // 确认是否真的发生了边沿变化(避免干扰) if((EXTI_GetITStatus(EXTI_Line0) & EXTI_IT_RISING) != RESET) { // 使用TIMx的Capture功能存储当前时间 HAL_TIM_Capture_Start(&htim1, TIM_CHANNEL_1); // 启动延时,例如50us,等待下一个采样点 delay(50); // 这里需要替换为你设备上合适的延时时间 // 再次检查是否有新的上升沿 if((EXTI_GetITStatus(EXTI_Line0) & EXTI_IT_RISING) != RESET) { // 如果有,计算两次采样之间的间隔,作为抖动判断依据 uint16_t interval = TIM1-> Capture1 - (TIM1-> CapturePreload1 & TIM1-> Capture); // 检查间隔是否超出阈值,如果小于某个预设的最小间隔,认为是抖动并忽略 if(interval < MIN_CAPTURE_INTERVAL) return; // 此时可以确认不是抖动,继续后续处理... } } } void delay(__IO uint32_t time) { while(time--) HAL_Delay(1); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值