• 使用定时器消除抖动


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

    具体怎么实现

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

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

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

    中断 向量表.s文件

            DCD     SysTick_Handler            ; SysTick Handler

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

    1. void SysTick_Handler(void)
    2. {
    3. HAL_IncTick();//增加计数值,
    4. extern void check_timer(void);
    5. check_timer();
    6. }

    stm32f1xxx_hal.c 

    1. __weak void HAL_IncTick(void)
    2. {
    3. uwTick += uwTickFreq;
    4. }
    5. __weak uint32_t HAL_GetTick(void)
    6. {
    7. return uwTick;
    8. }

    main.c

    指针的时间和时钟的时间

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

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

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

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

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

    1. struct soft_timer {
    2. uint32_t timeout;
    3. void * args;
    4. void (*func)(void *);
    5. };
    6. int g_key_cnt = 0;
    7. void key_timeout_func(void *args);
    8. struct soft_timer key_timer = {~0, NULL, key_timeout_func};
    9. void key_timeout_func(void *args)
    10. {
    11. g_key_cnt++;
    12. key_timer.timeout = ~0;
    13. }
    14. void mod_timer(struct soft_timer *pTimer, uint32_t timeout)
    15. {
    16. pTimer->timeout = HAL_GetTick() + timeout;
    17. }
    18. void check_timer(void)
    19. {
    20. if (key_timer.timeout <= HAL_GetTick())
    21. {
    22. key_timer.func(key_timer.args);
    23. }
    24. }
    25. 、、数据处理的源头,发生中断
    26. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
    27. {
    28. if (GPIO_Pin == GPIO_PIN_14)
    29. {
    30. mod_timer(&key_timer, 10);
    31. }
    32. }
    1. int main(){
    2. OLED_Init();
    3. OLED_Clear();
    4. OLED_PrintString(0, 4, "Key ISR cnt = ");
    5. while (1)
    6. {
    7. OLED_PrintSignedVal(0, 6, g_key_cnt);
    8. }
    9. }

    stm32f1xx_it.c

              DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10

    1. void EXTI15_10_IRQHandler(void)
    2. {
    3. /* USER CODE BEGIN EXTI15_10_IRQn 0 */
    4. /* USER CODE END EXTI15_10_IRQn 0 */
    5. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_14);
    6. /* USER CODE BEGIN EXTI15_10_IRQn 1 */
    7. /* USER CODE END EXTI15_10_IRQn 1 */
    8. }

     stm32f1xxx_hal_gpio.c  

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

    1. void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
    2. {
    3. /* EXTI line interrupt detected */
    4. if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
    5. {
    6. __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
    7. HAL_GPIO_EXTI_Callback(GPIO_Pin);
    8. }
    9. }

  • 相关阅读:
    程序员团队如何做好项目管理?十年管理经验,真实案例分享
    Spring Security登录流程分析
    Linux高级---ingress
    【前端实例代码】Html5+css3+JavaScript实现新拟态新拟物风格(Neumorphism)气泡图标泡泡网页效果!手把手教学!新手必会!超简单 ~
    C# 将一种类型的数组转换为另一种类型的数组
    WEB前端工具推荐丨分享6个热门颜色选择器组件
    服务器购买后的五个小技巧
    详解FreeRTOS:FreeRTOS任务调度器开启过程源码分析(进阶篇—5)
    [Linux] 下载工具 aria2 的使用
    淹没虚函数地址过GS保护(关闭DEP保护)
  • 原文地址:https://blog.csdn.net/m0_47239466/article/details/140306144