Reklama

Základy ovládání mikrokontroléru ATmega(16/32) 5.díl – Ošetření zákmitů na vstupním pinu mikrokontroléru

Úvod

Pokud vaše aplikace bude obsahovat nějaký spínací prvek jako např. tlačítko, klávesnici nebo spínač, budete muset řešit jak docílit toho, aby byl zaznamenán mikrokontrolérem vždy pouze jeden stisk. Uvidíte, že bez ošetření těchto stavů to není vždy zaručené. Na vině je fakt, že se jedná o mechanický kontakt, který než se trvale spojí, dojde k několika spojení a odpojení. Stejná situace nastane i při odpojování. Tento jev se nazývá zákmity a je nutné ho dostatečně ošetřit.

První způsob jak se zbavit zákmitů, je vytvoření bezzákmitového tlačítka. To lze vytvořit pomocí běžného tlačítka, dolní propustí RC článkem a Schmittovým klopným obvodem. Zapojení bezzákmitového tlačítka ukazuje Obr. 1.
Obr. 1: Bezzákmitové tlačítko, převzato z [1]

Obr. 1: Bezzákmitové tlačítko

Výpočet hodnot odporu a kondenzátoru závisí na mezním kmitočtu vytvořené dolní propusti. Obvykle se volí hodnota mezi 50 – 100 Hz. Hodnoty lze určit dle následujícího vztahu:

 

fmez = 1 / (2π•R•C) [Hz]

Jednu hodnotu si musíte zvolit a druhou dle vztahu dopočítat.

 

Druhou možností ošetření zákmitů, kterou se tady budeme zabývat, je pomocí vhodně napsaného programu. K detekci stisknutí je dále přidána časová prodleva a také zjištění z jakého logického stavu změna nastává. V normálním stavu (tlačítko nestisknuto) je na pinu vysoká logická úroveň. Při stisku dojde ke změně na nízkou logickou úroveň. Z toho plyne, že chceme detekovat první změnu z log. 1 na log. 0 při stisknutí tlačítka. Při spuštění tlačítka také hledáme přechod, a to z log. 0 na log. 1. Délka časové prodlevy může být různorodá.
 
V demonstračním zdrojovém kódě je na pinu PC0 umístěno proti zemi tlačítko, které při stisknutí a při spuštění generuje změnu stavu na pinech PA4 – PA7. Pokud na PORTA jsou zapojeny LED diody s předřadnými odpory na Vcc, tak dojde při stisknutí tlačítka ke zhasnutí čtyř LED diod. Níže lze vidět okomentovaný zdrojový kód. Pro zjednodušení byly použity globální proměnné “button_state” a “prev_button_state” a funkce “scan_button” neočekává žádná vstupní data. Programátorsky čistější řešení by ovšem bylo, nepoužívat proměnné jako globální a tyto proměnné předat funkci “scan_button” pomocí ukazatelů.

 

Okomentovaný zdrojový kód
 

001: #define F_CPU 16000000UL// definice hodinového signál, nutné pro delay
002: #include <util/delay.h>// hlavičkový soubor pro zpoždění
003: #include <avr/io.h>// knihovna AVR pro Input/output
004: #include <stdint.h>// knihovna pro standardní typy
005:
006: void scan_button(void);// prototyp funkce
007:
008: int button_state;// stav tlačítka
009: int prev_button_state;// předchozí stav tlačítka
010:
011: int main(void)
012: {
013: DDRA = 0xFF;// nastavení PORTU A jako výstup
014: PORTA = 0x00;// rozsvícení LED diod
015: DDRC = 0x00;// nastavení PORTU C jako vstup
016: PORTC = 0xFF;// nastavení PULL–UP rezistorů
017:
018: button_state = 1;// tlačítko není stisknuté
019:
020: while(1)
021: {
022: scan_button();// funkce pro testování stisknutého tlačítka
023: }
024: return 0;
025: }
026:
027: void scan_button(void)
028: {
029: // uložení předchozího stavu
030: prev_button_state = button_state;
031: button_state = PINC;// uložení stavu portu C
032: // maskování spodního bitu, kde se nachází tlačítko
033: button_state &= 0b00000001;
034:
035: if ((button_state == 0))// současný stav log. 0
036: {
037: if (prev_button_state == 1)// stisknutí tlačítka z log. 1 -> log. 0
038: {
039: PORTA = 0b11110000;// zhasnutí čtyř LED
040: _delay_ms(150);// prodleva – můžete měnit dle potřeby
041: }
042: }
043: else// současný stav log 1.
044: {
045: if (prev_button_state == 0)// puštění tlačítka z log. 0 -> log. 1
046: {
047: PORTA = 0b00000000;// rozsvícení LED diod
048: _delay_ms(150);// prodleva – můžete měnit dle potřeby
049: }
050: }
051: }

Vzorové zdrojové kódy slouží pouze k jednoduché demonstraci funkce, proto často obsahují globální proměnné, neobsahují většinou ukazatele, dále také neobsahují kontroly proměnných, definování nevyužitých pinů mikrokontroléru a podobné správné programátorské návyky. Proto je nutné tyto kódy brát s patřičnou rezervou.
 

 

Navržené ošetření zákmitu bylo vyzkoušené a měřené pomocí osciloskopu. Na obrázku Obr. 2 lze vidět neošetřený stav výstupu, zatímco na Obr. 3 lze vidět výstup již s aplikovaným ošetřením zákmitů.

Obr. 2: Neošetřený výstup

Obr. 2: Neošetřený výstup

Obr. 3: Ošetřený výstup

Obr. 3: Ošetřený výstup

 

Další možností jak ošetřit zákmity, je použití funkce pro skenování klávesnice vždy např. po 5 – 20 ms. V této funkci je nutné napsat zdrojový kód pro zjištění aktuálního stavu logické úrovně na vstupním pinu a uložením tohoto stavu do nějaké proměnné. Pokud např. minimálně pět po sobě jdoucích stavů mají stejnou logickou úroveň, lze považovat logický stav za stálý.

 

Pokud k obsluze tlačítka používáte externí přerušení reagující na hranu, tak není nutné snímat stav tlačítka, ale přerušení bude vyvoláno automaticky dle nastavení. Aby nedošlo k několikanásobnému vyvolání přerušení, tak na konci obslužné funkce přerušení je vhodné ručně vynulovat příznak pro dané přerušení.

 

Závěr

Z provedeného měření je vidět, že zákmity odezněly po 88 ms. Proto doporučuji, ponechat prodlevu po detekované hraně kolem 100 ms.

 
 
Aktualizace: 2.1.2016
 

Jiné příspěvky v kategorii:

 

Základy ovládání mikrokontroléru ATmega(16/32) 1.díl – První kroky

Základy ovládání mikrokontroléru ATmega(16/32) 2. díl – Kompilace a krokování programu

Základy ovládání mikrokontroléru ATmega(16/32) 3.díl – Nahrání vytvořeného zdrojového kódu do mikrokontroléru

Základy ovládání mikrokontroléru ATmega(16/32) 4.díl – Ovládání vstupně/výstupních portů

Základy ovládání mikrokontroléru ATmega(16/32) 6.díl – Externí přerušení

Základy ovládání mikrokontroléru ATmega(16/32) 7. díl – Jednoduchá elektronická hrací kostka

Základy ovládání mikrokontroléru ATmega(16/32) 8.díl – A/D převodník (1.část)

Základy ovládání mikrokontroléru ATmega(16/32) 9.díl – A/D převodník (2.část)

Základy ovládání mikrokontroléru ATmega(16/32) 10.díl – A/D převodník (3.část)

Základy ovládání mikrokontroléru ATmega(16/32) 11.díl – Čítač / Časovač (1.část – Základní popis)

Základy ovládání mikrokontroléru ATmega(16/32) 12.díl – Čítač / Časovač (2.část – Popis registrů)

Základy ovládání mikrokontroléru ATmega(16/32) 13.díl – Čítač / Časovač (3.část – Praktická ukázka)

Základy ovládání mikrokontroléru ATmega(16/32) 14.díl – Dvouřádkový LCD displej

Základy ovládání mikrokontroléru ATmega(16/32) 15.díl – Popis implementace komunikace I2C a EEPROM paměti 24LC512

Základy ovládání mikrokontroléru ATmega(16/32) 16.díl – Watchdog

Základy ovládání mikrokontroléru ATmega(16/32) 17.díl – Obsluha maticové klávesnice

Základy ovládání mikrokontroléru ATmega(16/32) 18.díl – Jednotka USART (1. část – Popis)

Základy ovládání mikrokontroléru ATmega(16/32) 19.díl – Jednotka USART (2. část – Praktická ukázka)

Základy ovládání mikrokontroléru ATmega(16/32) 20. díl – Generování audio signálu pomocí PWM

Základy ovládání mikrokontroléru ATmega(16/32) 21. díl – Analogový komparátor

Základy ovládání mikrokontroléru ATmega(16/32) 22. díl – Krokování programu v jazyce symbolických adres (JSA)
 
Tajned facebook
 

Za případné chyby v textu, ve zdrojovém kódě, nebo ve schématickém zapojení se omlouváme.
AUTOŘI NEBEROU ŽÁDNOU ODPOVĚDNOST ZA PŘÍPADNÉ ÚJMY NA ZDRAVÍ ČI MAJETKU.