П`ятниця, 29.03.2024, 03:07
Приветствую Вас Гість | RSS

Radiomanoff+

Меню сайта
Форма входа
Календарь
«  Червень 2016  »
ПнВтСрЧтПтСбНд
  12345
6789101112
13141516171819
20212223242526
27282930

Блог

Главная » 2016 » Червень » 20 » STM32 - button debounce.HAL&CubeMX.Боремось із дрижанням кнопки.
22:12
STM32 - button debounce.HAL&CubeMX.Боремось із дрижанням кнопки.

 

Cьогодні я розповім, як я боровся із дрижанням кнопки, в розрізі мікроконтролера STM32 ( в данному випадку STM32F042F6P6 ) та бібліотеки HAL  & CubeMX. Будемо використовувати зовнішні переривання.

Як відомо при натисканні на кнопку, зазвичай відбувається багаторазове замикання і розмикання її контактів. Схематично це може бути представлене в такий спосіб:

Я не буду розповідати по всі свої експерименти в боротьбі із цим "нехорошим" явищем, тому зупинюсь лише на кінцевому варіанті, який мене влаштував.

Підключення кнопок. Після різних варіантів підключення, я зупинився на "фірмовому" варіанті від STMicroelectronics, який застосований в платах Discovery:

Таку схему я зібрав для 4-ох кнопок, с такимиж номіналами резисторів та конденсаторів.

Як  я вже писав ми використовуємо зовнішні переривання. Як відомо  зовнішні переривання активізуються при зміни логічного рівня на нозі контролера. У STM32 за зовнішні переривання відповідає EXTI контролер.

Стартуємо. Будемо створювати прошивку для нашого МК при допомозі програми CubeMX. Цей інструмент, хоча і з'явився вже давно, був мною незаслужено обділений увагою. Щож я думаю ми заповнимо цю прогалину...

Відкриваємо програму, створюємо новий проект

Ми будемо  використовувати відлагоджувальну плату для STM32F0xxFx описану раніше, та в якості пограматора плату STM32F4 Discovery. 

Вибираємо наш МК, в даному випадку у мене STM32F042F6P6.

Далі налаштовуємо наші піни. Спочатку ввімкнемо інтерфейс SWD, звісно якщо ми будемо прошивати МК через програматор ST-Link. Це ноги РА13,РА14. Якщо цього не зробити, то потрібно буде завжди при прошивці контролера натискати кнопку RESET, що не дуже зручно.

Забіжу наперед, ми маємо підключити крім кнопок ще дисплей - потрібно 5 ніжок, нехай це будуть РА0,РА1,РА2,РА3,РА4. Також три піна виділимо для світлодіодів,  нехай це будуть РВ1,РF0,РF1. Всі ці ножки налаштовуються як GPIO_Output:

Налаштовуємо ножки під кнопки. Використовуємо піни PA5,PA6,PA7, вмикаємо на них контролер зовнішніх переривань EXTI:

Тепер ще один момент. Як ми вже писали для реагування на натискання кнопки використовуємо контролер зовнішніх переривань EXTI. Обробник переривання спільний для цих тьох пінів - EXTI4_15_IRQHandler . Тобто з 4 по 15 пін має одне зовнішнє переривання. Оскільки ми не плануємо обробляти два натискання одночасно, то в принципі це все нас влаштовує.

Забігаючи на перед опишу, як же ми будемо боротись саме с дрижанням кнопки. Для цього скористаємось затримкою на час перехідних процесів в кнопці, і щоб її організувати так щоб не зашкодити виконанню основної програми, застосуємо іще таймер , наприклад TIM14. Вмикаємо його:

Далі заходимо на вкладку Clock Configuration і виставляємо частоту на якій буде працювати ядро та переферія контролера. в даному випадку я встановив максимально можливу для STM32F0xx - 48 MHz. Також все буде тактуватись від внутрішнього генератора HSI . Хоча STM32F042 має  більш стабільний HSI48 , призначений для апаратного USB, всеж використовуємо звичайний HSI, оскільки планується перенос проекта на STM32F030.

Наступна вкладка Configuration . Розпочнем із того що ввімкнемо наші обробники переривань для EXTI та TIM14.

Далі налаштуємо наші піни, які використовуються для кнопок. Підтяжки не вмикаємо, оскільки вони в нас вже є (див. вище схему підключення кнопки). Також зовнішнє переривання налаштовуємо по обох фронтах Rising & Filling, саме так сама досяглась сама стабільна робота...

Далі налаштовуємо таймер TIM14. Прескалер виставляємо 47999, щоб таймер "тікав" з частотою 1 раз в мілісекунду. А період поставимо 100, в нашому випадку це буде 100 мс. Чому вибране це число? Приблизно такий час зазвичай складає дрижання кнопки.

Ну ось тепер можна генерувати наш проект.

Я люблю Keil, тому саме цей компілятор я вибрав в налаштування CubeMX. 5-ту версію. "Пустий" проект "заважив" - Program Size: Code=3564 RO-data=240 RW-data=8 ZI-data=1088  

Починаємо наповнювати проект.

Дисплей. Для більшої інформативності прикріпив до проекта дисплей під назвою NOKIA 5110 на контролері PCD8544:

Бібліотека для нього перша яка "нагуглилась" з "ногодригом" - http://vg.ucoz.ru/forum/9-100-1 Ми її трішки адаптували під себе та бібліотеку HAL.

// Управление линией LCD_CS
#define LCD_CS1   HAL_GPIO_WritePin(LCD_PORT, SCE, GPIO_PIN_SET)
#define LCD_CS0   HAL_GPIO_WritePin(LCD_PORT, SCE, GPIO_PIN_RESET)

// Управление линией LCD_RST
#define LCD_RST1  HAL_GPIO_WritePin(LCD_PORT, RST, GPIO_PIN_SET)
#define LCD_RST0  HAL_GPIO_WritePin(LCD_PORT, RST, GPIO_PIN_RESET)

// Управление линией LCD_DC
#define LCD_DC1   HAL_GPIO_WritePin(LCD_PORT, DC, GPIO_PIN_SET)
#define LCD_DC0   HAL_GPIO_WritePin(LCD_PORT, DC, GPIO_PIN_RESET)

// Управление линией LCD_SCK
#define LCD_SCK1   HAL_GPIO_WritePin(LCD_PORT, SCLK, GPIO_PIN_SET)
#define LCD_SCK0   HAL_GPIO_WritePin(LCD_PORT, SCLK, GPIO_PIN_RESET)

// Управление линией LCD_MOSI
#define LCD_MOSI1   HAL_GPIO_WritePin(LCD_PORT, MOSI, GPIO_PIN_SET)
#define LCD_MOSI0   HAL_GPIO_WritePin(LCD_PORT, MOSI, GPIO_PIN_RESET)

Підключення пінів прописане в файлі pcd8544.h :

#define SCLK   GPIO_PIN_0
#define MOSI   GPIO_PIN_1
#define DC     GPIO_PIN_2
#define RST    GPIO_PIN_3
#define SCE    GPIO_PIN_4

#define LCD_PORT GPIOA

На початку головного цикла вставимо "заставочку". А так будемо на екрані відслідковувати стан світлодіодів LED-ON та LED-OFF . Саміж світлодіоди будуть вмикатись кнопками. Поїхали...

Реалізація. Алгоритм такий 

- спрацьовує зовнішнє переривання від кнопки;

-в обробнику переривання EXTI4_15_IRQHandler вимикаємо зовнішнє переривання ЕХТІ та вмикаємо таймер ТІМ14;

-таймер відпрацьовує 100 мс і в обробнику TIM14_IRQHandler провіряє. яка кнопка підтянута до "+";

залежності від натисненої кнопки засвічується свій світлодіод та виводиться відповідний напис на екрані дисплея;

Нас цікавить файл stm32f0xx_it.с , тут прописується що ми будемо робити в перериванні.

Перша функція обробник переривання EXTI4_15_IRQHandler  , робимо те про, що ми писали вище:

  HAL_NVIC_DisableIRQ(EXTI4_15_IRQn);   // вимикаємо  ЕХТІ 
  HAL_TIM_Base_Start_IT(&htim14);  // вмикаємо ТІМ14

 Наступна функція оброник перериваня TIM14_IRQHandler 

  HAL_TIM_Base_Stop_IT(&htim14);   // вимикаємо ТІМ14

  // ===== тут наш код обробки=========
    
    HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
 // вмикаємо ЕХТІ 

От і все. Компілюємо проект , прошиваємо МК . Все працює бездоганно.

Сам проект в Keil 5 http://radiomanoff.at.ua/load/stm32f0xx_button/1-1-0-39

Та невеличке відео, за створення якого дуже дякую моєму сину Ярославу....

Просмотров: 2994 | Добавил: rastamanoff | Рейтинг: 0.0/0
Всего комментариев: 0
Ім`я *:
Email *:
Код *:
Статистика

Онлайн всього: 1
Гостей: 1
Користувачів: 0