Implementace LED dýchacího světla pomocí mikrokontroléru 51

Jun 11, 2026 Zanechat vzkaz

[Zavedení]


Technologie mikrokontrolérů je nepostradatelnou mainstreamovou technologií v moderní průmyslové automatizaci, elektronice, elektrotechnice a internetu věcí (IoT). Jak se naše životy stávají stále chytřejšími, technologie mikrokontrolérů pronikla prakticky do všech aspektů našeho každodenního života, jako jsou chytré rýžovary, chytré reproduktory a další.


S ohledem na tuto skutečnost je cílem série článků „Relearning the 51 Microcontroller“ pomoci začátečníkům začít s technologií mikrokontrolérů. Začneme nejjednodušším úkolem-zapnutím jedné LED-a postupně pokročíme k implementaci modulů, jako jsou tlačítka, displej LCD1602, teplotní senzory DS18B20 a DS1302 a komunikace mezi dvěma mikrokontroléry. Budeme také pokrývat hardwarové komunikační protokoly, jako je UART, I²C a SPI. Kombinací těchto konceptů s technikami programování v jazyce C použijeme skutečné{10} inženýrské projekty k ilustraci přístupů k programování, které vám umožní flexibilně používat ukazatele a struktury v jazyce C k dosažení modulárního programování.


Nyní se vraťme k hlavnímu tématu: použití mikrokontroléru 51 k ovládání LED a vytvoření efektu dýchacího světla.

 

[Jak fungují dýchací světla]


Pojďme se nejprve podívat na to, jak funguje světelný efekt dýchání.
Dýchací světlo se postupně rozjasňuje a pak postupně tlumí, přičemž se tento cyklus opakuje způsobem, který připomíná dýchání. Protože však kolíky mikrokontroléru mohou vydávat pouze 1 (zapnuto) nebo 0 (vypnuto), jak lze dosáhnout efektu postupného přechodu?
To je způsobeno přetrvávajícím viděním v našich očích. Když se na něco díváme, obraz vytvořený našimi očima přetrvává po dobu 0,04 sekundy (tento údaj byl nalezen online).
Pokud počítáme na základě 0,04 sekundy, rovná se to 40 ms. Když se tedy LED dioda rozsvítí a zhasne po dobu 20 ms, zdá se lidskému oku, jako by neustále svítila.

图片

Je účinek blikání LED na 20 ms a zhasnutí na 20 ms stejný, jako když svítí stále?

 

Haha, určitě je to jinak. Když se světlo střídavě zapíná a vypíná každých 20 milisekund, efekt, který vidíme, je slabší, než když svítí nepřetržitě. Pokud předpokládáme, že jas trvale svítícího světla je 100 %, pak jas světla, které se každých 20 milisekund střídavě rozsvěcuje a zhasíná, je 50 %. Na základě toho můžeme upravit jas LED.

图片

 

V tomto okamžiku můžeme upravit jas LED (nastavením doby trvání vysoké úrovně v rámci 40ms cyklu). Toto je princip-známé metody PWM (Pulse Width Modulation) ovládání jasu a nastavení doby trvání vysoké úrovně je ekvivalentní úpravě pracovního cyklu (tj. trvání vysoké úrovně dělené celkovým cyklem: 20/40=50%).


Zde je nejdůležitějším faktorem tento pracovní cyklus. Pokud je například perioda 20 ms a LED střídavě svítí mezi 10 ms a 10 ms nesvítí, vnímaný jas je stále 50 % (tj. pracovní cyklus je 10/20=50 %).

Dále se podívejme, jak je to implementováno v programu.

 

[Implementace programu]


Zapnutí LED
Nejprve začneme rozsvícením LED a poté postupně implementujeme efekt dýchacího světla. Hardware, který budeme používat, je následující:

rozvojová rada ZeroOne Microcontroller Training Development Board
Model mikrokontroléru STC89C52
Rozhraní LED Pin P4^4
图片

 

Ze schématu vidíme, že LED je připojena na pin P4^4 mikrokontroléru. Když mikrokontrolér vydá 1, LED se rozsvítí; když je na výstupu 0, LED zhasne. Proto je program pro zapnutí LED poměrně jednoduchý, jak je znázorněno níže:

info-299-230

 

 

Program pro zapnutí LED je poměrně jednoduchý; Určitě každý ví, jak na to.
 

Nastavení jasu LED


Dále implementujeme funkci, která nám umožňuje upravit jas (tj. upravit pracovní cyklus), a to následovně:

info-400-538


 

Definujte statickou proměnnou `duty_cycle` pro uložení pracovního cyklu. Když je „příznak“ 1, pracovní cyklus se postupně zvýší na 255, poté nastavte „příznak“ na 0 a „duty_cycle“ postupně klesá z 255 na 0. Tento cyklus opakujte.
Haha, v tuto chvíli si možná myslíte, že dýchací světlo již funguje, ale není. Pokud mi nevěříte, vyzkoušejte kód výše.

Kde je tedy přesně problém?


Problém spočívá v našem přímém volání funkce nastavení-jasu `set_led_luminance()`. Této funkci trvá dokončení jednoho cyklu 40 ms, což znamená, že během těchto 40 ms nelze pracovní cyklus změnit; jinak nebude nastavení jasu fungovat. Podívejme se znovu na funkci `breath_led`. Po každém volání funkce `set_led_luminance()` k nastavení pracovního cyklu se okamžitě změní hodnota `duty_cycle`, aniž by čekalo 40 ms.


V tomto okamžiku musíme přidat softwarový časovač, který aktualizuje hodnotu `duty_cycle` po uplynutí 40 ms. Upravený program je následující:

info-495-656

 

 

Poznámka: Doba trvání časovače musí být větší než 40 ms (to znamená, že hodnota `s_breathCounter` musí být větší než 255), ale je nejlepší nastavit ji na násobek cyklu. Pokud je například náš cyklus 255 (tj. 256 hodnot od 0 do 255), můžeme jej nastavit na dvojnásobek této hodnoty: 256 * 2 - 1=511 (tj. 512 hodnot od 0 do 511).
A tady to máte-naše dýchací světlo je kompletní! Není to jednoduché? (* ̄︶ ̄)

 

Další na řadě je dnešní bonusová sekce.

Přestože jsme dosáhli efektu dýchajícího světla, kód není dostatečně stručný ani elegantní-používá spoustu příkazů if a else. Uvidíme, zda to dokážeme dále zjednodušit.

Nejprve si zjednodušíme tuto část funkce set_led_luminance(), jak je znázorněno na obrázku níže.
 

图片

 

Než to zjednodušíme, proberme si rychlý tip o C: bitovou operaci AND.

info-600-117

 

Z toho víme, že ať už je to 1 nebo 0, provedení bitové operace AND s 0 má za následek 0.

Ať už je to 1 nebo 0, provedení bitové operace AND s 1 vede k původní hodnotě.

Pro usnadnění používáme hexadecimální zápis (předponou "0x"); například 0xff odpovídá 255 v desítkové soustavě. Proto,

 

Když je číslo menší nebo rovné 0xff spojeno AND s 0xff, výsledkem je samotné číslo, jak je uvedeno níže

info-534-63

 

 

Co se stane, když provedete bitovou operaci AND mezi číslem větším než 0xff a 0xff?

info-551-63

Výsledkem je zbytek, když je toto číslo děleno (0xff + 1) (tj. výsledek je stále mezi 0 a 0xff).
Pomocí této bitové operace AND lze výše uvedený kód zjednodušit

info-550-64

 

 

Tímto způsobem bude hodnota s_Counter vždy v rozsahu 0x00 až 0xff.
Podobně lze softwarový časovač ve výše uvedené funkci breath_led také zjednodušit následovně:

info-389-353

Na řádku 3 je 0x1ff 511 v desítkové soustavě. Podmínka je pravdivá, když je hodnota s_breathCounter (0x1ff+1), nebo 512, protože 512 & 0x1ff=0. Vykřičník před ním označuje bitovou operaci NOT (abych byl přesný, podmínka je splněna, když je hodnota `s_breathCounter` potřeba resetovat `s_Coeliminovat the2;` tento násobek 51;` Doufám, že je toto vysvětlení jasné-prosím, promyslete si to). Pokud je podmínka splněna, pracovní cyklus se začne zvyšovat nebo snižovat.


Ale není rozsah pracovního cyklu 0 až 255? Proč se řádek 5 také změní na 0x1ff (511)? Nebojte se-podívejte se na řádek 8. Znovu odečteme 0xff, takže rozsah pracovního cyklu zůstane 0 až 255.


Řádky 7–10 znamenají: Když `duty_cycle > (0xff)`, tj. 256–511, odečtení 0xff je ekvivalentní zvýšení z 1 na 255, takže jas se postupně zvyšuje.


Když duty_cycle<= 0xff, the duty_cycle increases from 0 to 255, while the set brightness is 255 - duty_cycle. This effectively decreases the brightness from 255 to 0, causing the light to gradually dim. This achieves the breathing light effect.


Haha, mysleli jste, že naše zjednodušení skončilo?

 

Ne, ne, ne

Ve skutečnosti by řádky 7 až 10 mohly být ještě zjednodušeny. Zde se hodí funkce absolutní hodnoty.

Co? Proč používat funkci absolutní hodnoty?

 

Podívejte se na řádek 10: 0xff - duty_cycle je ekvivalentní duty_cycle - 0xff a pak vezmete absolutní hodnotu. Dobře, zde je zjednodušený kód:

set_led_luminance(ABS(pracovní_cyklus - (0xff)));

 

 

Funkce makra pro získání absolutní hodnoty je následující

#define ABS(N) ((N) < 0 ? -(N) : (N))

 

Nakonec jsem níže zahrnul celý zjednodušený kód

 

info-562-684

co myslíš? není to jednoduché? (* ̄︶ ̄)

Odeslat dotaz

whatsapp

Telefon

E-mail

Dotaz