Obsah:
Video: Mikrokontrolér AVR. Přepínejte LED diody pomocí tlačítka. Odskakování tlačítkem: 4 kroky
2025 Autor: John Day | [email protected]. Naposledy změněno: 2025-01-13 06:57
V této části se naučíme, jak vytvořit kód C programu pro ATMega328PU pro přepínání stavu tří LED diod podle vstupu z tlačítkového spínače. Také jsme prozkoumali řešení problému „Switch Bounce“. Jako obvykle sestavíme elektrický obvod na základně AVR ATmega328, abychom zkontrolovali práci programového kódu.
Krok 1: Psaní a vytváření aplikace mikrokontroléru AVR v kódu C pomocí integrované vývojové platformy Atmel Studio 7
Pokud Atmel Studio nemáte, měli byste si jej stáhnout a nainstalovat.
www.microchip.com/mplab/avr-support/atmel-studio-7
Prvních pár řádků, které definuje kompilátor.
F_CPU definuje taktovací frekvenci v Hertzech a je běžný v programech využívajících knihovnu avr-libc. V tomto případě jej rutiny zpoždění používají k určení způsobu výpočtu časových zpoždění.
#ifndef F_CPU
#define F_CPU 16000000UL // sdělující krystalovou frekvenci ovladače (16 MHz AVR ATMega328P) #endif
#include // header umožňující řízení toku dat přes piny. Definuje piny, porty atd.
První soubor zahrnutí je součástí avr-libc a bude použit téměř ve všech projektech AVR, na kterých pracujete. io.h určí CPU, který používáte (což je důvod, proč určujete část při kompilaci) a následně zahrne příslušné záhlaví definice IO pro čip, který používáme. Jednoduše definuje konstanty pro všechny vaše piny, porty, speciální registry atd.
#include // header povolí funkci zpoždění v programu
Knihovna util/delay.h obsahuje některé rutiny pro krátká zpoždění. Funkce, kterou budeme používat, je _delay_ms ().
K deklaraci portů a pinů našich a LED diod používáme definice. Použití takto definovaných příkazů nám umožňuje upravit pouze 3 snadno nalezitelné řádky, pokud přemístíme LED na jiný I/O pin nebo použijeme jiný AVR.
#define BUTTON1 1 // tlačítkový spínač připojený k portu B pin 1
#define LED1 0 // Led1 připojen k portu B pin 0 #define LED2 1 // Led2 připojen k portu C pin 1 #define LED3 2 // Led3 připojen k portu D pin 2
Poslední dva definují časy nastavení příkazů, v milisekundách, aby došlo k odpojení přepínače a času čekání, než povolíte další stisknutí tlačítka. Dobu odskoku je třeba upravit na dobu, po které přepnutí přejde z digitálního maxima na digitální minimum po všech odrazech. Chování při odrazu se bude lišit od přepínače k přepínači, ale 20-30 milisekund je obvykle zcela dostačující.
#define DEBOUNCE_TIME 25 // čas na čekání při tlačítku „odskakování“
#define LOCK_INPUT_TIME 300 // doba čekání po stisknutí tlačítka
neplatné init_ports_mcu ()
{
Tato funkce se nazývá pouze jednou na začátku našeho programu k inicializaci vstupních výstupních pinů, které budeme používat.
U tlačítka budeme pro zápis a čtení používat registry PORT a PIN. U AVR čteme pin pomocí jeho registru PINx a zapisujeme na pin pomocí jeho registru PORTx. Musíme povolit pull-upy do registru tlačítek.
Pro LED potřebujeme k zápisu použít pouze PORT registr, nicméně potřebujeme také datový směrový registr (DDR), protože I/O piny jsou ve výchozím nastavení nastaveny jako vstupy.
Nejprve nastavíme I/O piny LED jako výstup pomocí jeho registru směru dat.
DDRB = 0xFFu; // Nastaví všechny piny PORTB jako výstup.
Dále explicitně nastavte kolík tlačítka jako vstup.
DDRB & = ~ (1 <
Dále jsou kolíky PORTB nastaveny vysoko (+5 voltů), aby se zapnuly. Výstupní piny jsou zpočátku vysoké, a protože naše LED je zapojena aktivní-vysoká, bude zapnuta, pokud ji výslovně nevypneme.
A nakonec povolíme interní pull-up odpor na vstupním pinu, který používáme pro naše tlačítko. To se provádí jednoduše výstupem jednoho do portu. Pokud je nakonfigurován jako vstup, má za následek povolení pull-upů a pokud je nakonfigurován jako výstup, jednoduše by vyvedl vysoké napětí.
PORTB = 0xFF; // Nastavit všechny piny PORTB jako VYSOKÉ. LED svítí, // také je povolen interní Pull Up odpor prvního pinu PORTB. DDRC = 0xFFu; // Nastavit všechny piny PORTC jako výstup. PORTC = 0x00u; // Nastaví všechny piny PORTC low, čímž se vypne. DDRD = 0xFFu; // Nastavit všechny piny PORTD jako výstup. PORTD = 0x00u; // Nastaví všechny piny PORTD nízko, čímž se vypne. }
nepodepsaný znak button_state ()
{
Tato funkce vrací logickou hodnotu udávající, zda bylo tlačítko stisknuto nebo ne. Toto je blok kódu, který se neustále provádí v nekonečné smyčce, a proto dotazuje stav tlačítka. To je také místo, kde jsme zrušili přepínač.
Nyní si pamatujte, že když stiskneme spínač, vstupní výstupní kolík je vytažen k zemi. Proto čekáme, až se špendlík sníží.
/ * tlačítko je stisknuto, když je BUTTON1 bit prázdný */
if (! (PINB & (1 <
Děláme to tak, že zkontrolujeme, zda je bit jasný. Pokud je bit jasný, což znamená, že je tlačítko stisknuto, nejprve zpozdíme dobu definovanou DEBOUNCE_TIME, což je 25 ms, a poté znovu zkontrolujeme stav tlačítka. Pokud je tlačítko stisknuto po 25 ms, pak je přepínač považován za odpojený a připravený ke spuštění události, a tak se vrátíme k naší rutině volání 1. Pokud tlačítko není stisknuto, vrátíme 0 do naší rutiny volání.
_delay_ms (DEBOUNCE_TIME);
if (! (PINB & (1 <
int main (neplatné)
{
Naše hlavní rutina. Hlavní funkce je jedinečná a odlišuje se od všech ostatních funkcí. Každý program C musí mít přesně jednu hlavní () funkci. hlavní je místo, kde AVR začne spouštět váš kód, když se poprvé zapne napájení, takže je to vstupní bod programu.
znak bez znaménka n_led = 1; // původně LED číslo nyní svítí
Volání funkce k inicializaci používaných I/O pinů:
init_ports_mcu ();
nekonečná smyčka, kde běží náš program:
zatímco (1)
{
Když button_state vrátí hodnotu indikující, že tlačítko bylo stisknuto a odpojeno, pak přepíná aktuální stav LED diod postupně podle parametru n_led.
if (button_state ()) // Pokud je tlačítko stisknuto, přepněte stav LED a zpoždění na 300 ms (#define LOCK_INPUT_TIME)
{switch (n_led) {case 1: PORTB ^= (1 << LED1); PORTC ^= (1 << LED2); přestávka;
Tyto příkazy používají bitové operátory C. Tentokrát používá exkluzivního operátora NEBO. Když XOR PORT s bitovou hodnotou bitu, který chcete přepnout, tento jeden bit se změní bez ovlivnění ostatních bitů.
případ 2:
PORTC ^= (1 << LED2); PORTD ^= (1 << LED3); přestávka; případ 3: PORTD ^= (1 << LED3); PORTB ^= (1 << LED1); n_led = 0; // reset LED přerušení čísla; } n_led ++; // další LED svítí _delay_ms (LOCK_INPUT_TIME); }} return (0); }
Takže nyní, když spustíte tento program, měli byste být schopni stisknout tlačítko, aby se LED diody přepínaly. Vzhledem k našemu zpoždění definovanému LOCK_INPUT_TIME můžete stisknout a podržet tlačítko, což způsobí, že se LED diody vypnou a zapnou konzistentní rychlostí (o něco více než každých 275 ms).
Programování je dokončeno.
Dalším krokem je sestavení projektu a programování hexadecimálního souboru do mikrokontroléru pomocí programu avrdude.
Můžete si stáhnout soubor main.c s programem v kódu c:
Krok 2: Přenos souboru HEX programu do flash paměti čipu
Stáhněte a nainstalujte AVRDUDE. Nejnovější dostupná verze je 6.3: Stáhněte si soubor zip
Nejprve zkopírujte hexadecimální soubor programu do adresáře AVRDUDE. V mém případě je to ButtonAVR.hex
Poté do okna výzvy DOS zadejte příkaz: avrdude –c [jméno programátora] –p m328p –u –U flash: w: [název vašeho hexadecimálního souboru].
V mém případě je to: avrdude –c ISPProgv1 –p m328p –u –U flash: w: ButtonAVR.hex
Tento příkaz zapíše hex soubor do paměti mikrokontroléru.
Podívejte se na video s podrobným popisem vypalování flash paměti mikrokontroléru:
Vypalování flash paměti mikrokontroléru…
OK! Mikrokontrolér nyní pracuje v souladu s pokyny našeho programu. Pojďme to zkontrolovat!
Krok 3: Demontáž hardwarového přepínače
Kromě softwarového odblokování softwarového přepínače můžeme použít také techniku odstraňování hardwarových přepínačů. Základní myšlenkou takové techniky je použít kondenzátor k odfiltrování rychlých změn signálu spínače.
Jakou hodnotu kondenzátoru zvolit? To bude nakonec záviset na tom, jak špatně si tlačítko v tomto konkrétním problému vede. Některá tlačítka mohou zobrazovat ohromné chování při odskakování, jiná však budou mít velmi málo. Nízká hodnota kondenzátoru, jako je 1,0 nanofarad, bude reagovat velmi rychle, s malým nebo žádným vlivem na poskakování. Naopak vyšší hodnota kondenzátoru, jako je 220 nanofarád (což je na kondenzátory stále dost malé), zajistí pomalý přechod od počátečního k koncovému napětí (5 voltů na 0 voltů). Přechod pozorovaný s kapacitou 220 nanofarád je stále velmi rychlý ve smyslu skutečného světa, a proto jej lze použít na špatně fungujících tlačítkách.
Krok 4: Elektrický obvod
Připojte komponenty podle schématu.