Обмен технологиями

Используйте таймеры для устранения джиттера

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Вопрос: К какому режиму работы относятся прерывания по таймеру и прерывания по клавишам, они опрашиваются?

Как это реализовать конкретно

Прерывание таймера (решение) Прерывание клавиши параметра времени (модификация)

.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. }

основной.c

Время стрелки и время часов

Структура pTimerФункция, содержащая значения времени и количества процессов

в системефункция обработки часовДобавьте функцию проверки часов, и оператор if в check_timer ограничит время указателя меньшим или равным времени часов.

Если прервано, пропуститеФункция обратного вызова прерыванияДобавьте 10 мс ко времени вашего указателя,Если в этот период произойдет еще одно прерывание, время указателя будет увеличено на 10.

Когда прерывание не происходит или прерывание происходит в течение (n*10) мс, условия для ввода тела функции if в check_timer не выполняются;

Введите тело функции 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 ; Линия ЭКСТИ 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. }