LED kvėpuojančios šviesos įdiegimas naudojant 51 mikrovaldiklį

Jun 11, 2026 Palik žinutę

[Įvadas]


Mikrovaldiklių technologija yra nepakeičiama pagrindinė šiuolaikinės pramonės automatikos, elektronikos, elektros inžinerijos ir daiktų interneto (IoT) technologija. Kadangi mūsų gyvenimas tampa vis išmanesnis, mikrovaldiklių technologija persmelkė beveik visus mūsų kasdienio gyvenimo aspektus, pavyzdžiui, išmaniosiose ryžių viryklėse, išmaniuosiuose garsiakalbiuose ir kt.


Turint tai omenyje, straipsnių serija „Iš naujo išmokti 51 mikrovaldiklį“ siekiama padėti pradedantiesiems pradėti naudotis mikrovaldiklio technologija. Pradėsime nuo paprasčiausios užduoties-įjungti vieną šviesos diodą-ir palaipsniui diegsime tokius modulius kaip mygtukų valdikliai, LCD1602 ekranas, DS18B20 ir DS1302 temperatūros jutikliai ir ryšys tarp dviejų mikrovaldiklių. Taip pat apimsime aparatinės įrangos ryšio protokolus, tokius kaip UART, I²C ir SPI. Derindami šias sąvokas su C programavimo technikomis, programavimo metodams iliustruoti naudosime realius{10}}pasaulio inžinerinius projektus, kad galėtumėte lanksčiai taikyti C rodykles ir struktūras, kad sukurtumėte modulinį programavimą.


Dabar grįžkime prie pagrindinės temos: 51 mikrovaldiklio naudojimas šviesos diodui valdyti ir kvėpuojančios šviesos efektui sukurti.

 

[Kaip veikia kvėpuojančios šviesos]


Pirmiausia pažiūrėkime, kaip veikia kvėpuojantis šviesos efektas.
Kvėpuojanti šviesa palaipsniui ryškėja, o po to palaipsniui pritemsta, kartodama šį ciklą panašiai kaip kvėpavimas. Tačiau, kadangi mikrovaldiklio kontaktai gali išvesti tik 1 (įjungta) arba 0 (išjungta), kaip galima pasiekti laipsniško perėjimo efektą?
Taip yra dėl nuolatinio regėjimo mūsų akyse. Kai žiūrime į ką nors, mūsų akių suformuotas vaizdas išlieka 0,04 sekundės (šis skaičius buvo rastas internete).
Jei skaičiuosime pagal 0,04 sekundės, tai yra 40 ms. Todėl kai šviesos diodas įsijungia ir išjungiamas po 20 ms, žmogaus akiai atrodo, kad jis nuolat dega.

图片

Ar šviesos diodo, įjungto 20 ms ir išjungus 20 ms, efektas yra toks pat, kaip ir nuolatinis mirksėjimas?

 

Haha, tikrai kitaip. Kai šviesa pakaitomis įjungiama ir išjungiama kas 20 milisekundžių, matomas efektas yra silpnesnis nei nuolat degant. Jei darysime prielaidą, kad nuolat šviečiančios šviesos ryškumas yra 100%, tai kas 20 milisekundžių pakaitomis įsijungiančios ir išjungiančios šviesos ryškumas yra 50%. Remdamiesi tuo, galime reguliuoti šviesos diodo ryškumą.

图片

 

Šiuo metu galime reguliuoti šviesos diodo ryškumą (nustatydami aukšto lygio trukmę per 40 ms ciklą). Tai yra gerai žinomo -PWM (impulso pločio moduliavimo) ryškumo valdymo metodo principas, o aukšto lygio trukmės nustatymas prilygsta darbo ciklo koregavimui (ty aukšto lygio trukmė, padalyta iš viso ciklo: 20/40=50%).


Čia svarbiausias veiksnys yra darbo ciklas. Pavyzdžiui, jei laikotarpis yra 20 ms, o šviesos diodas kinta tarp 10 ms įjungtų ir 10 ms išjungtų, suvokiamas ryškumas vis tiek yra 50 % (ty darbo ciklas yra 10/20=50 %).

Toliau pažiūrėkime, kaip tai įgyvendinama programoje.

 

[Programos įgyvendinimas]


LED įjungimas
Pirmiausia pradėkime nuo šviesos diodo įjungimo, o tada palaipsniui įgyvendinsime kvėpuojančios šviesos efektą. Aparatinė įranga, kurią naudosime, yra tokia:

Vystymosi taryba „ZeroOne“ mikrovaldiklių mokymo kūrimo taryba
Mikrovaldiklio modelis STC89C52
LED sąsaja Smeigtukas P4^4
图片

 

Iš schemos matome, kad šviesos diodas yra prijungtas prie mikrovaldiklio kaiščio P4^4. Kai mikrovaldiklis išveda 1, įsijungia šviesos diodas; kai išveda 0, šviesos diodas išsijungia. Todėl programa LED įjungti yra gana paprasta, kaip parodyta žemiau:

info-299-230

 

 

Šviesos diodo įjungimo programa yra gana paprasta; Esu tikras, kad visi žino, kaip tai padaryti.
 

LED ryškumo reguliavimas


Toliau įdiegsime funkciją, leidžiančią reguliuoti ryškumą (ty reguliuoti darbo ciklą), kaip nurodyta toliau:

info-400-538


 

Apibrėžkite statinį kintamąjį „darbo_ciklas“, kad išsaugotumėte darbo ciklą. Kai „vėliava“ yra 1, darbo ciklas palaipsniui didėja iki 255, tada nustatykite „žymą“ į 0, o „darbo ciklas“ palaipsniui mažėja nuo 255 iki 0. Pakartokite šį ciklą.
Haha, šiuo metu galite pamanyti, kad kvėpavimo lemputė jau veikia, bet taip nėra. Jei netikite manimi, išbandykite aukščiau pateiktą kodą patys.

Taigi kur tiksliai yra problema?


Problema slypi mūsų tiesioginiame ryškumo -nustatymo funkcijos „set_led_luminance()“ iškvietime. Šiai funkcijai vienam ciklui atlikti reikia 40 ms, o tai reiškia, kad darbo ciklas negali būti pakeistas per tas 40 ms; kitu atveju ryškumo reguliavimas neveiks. Dar kartą pažvelkime į funkciją „breath_led“. Po kiekvieno iškvietimo į „set_led_luminance()“, kad būtų nustatytas darbo ciklas, jis iš karto pakeičia „darbo_ciklo“ reikšmę, nelaukdamas 40 ms.


Šiuo metu turime pridėti programinės įrangos laikmatį, kad atnaujintume „darbo ciklo“ reikšmę, praėjus 40 ms. Modifikuota programa yra tokia:

info-495-656

 

 

Pastaba: laikmačio trukmė turi būti ilgesnė nei 40 ms (tai reiškia, kad `s_breathCounter' reikšmė turi būti didesnė nei 255), bet geriausia nustatyti jį į ciklo kartotinį. Pavyzdžiui, jei mūsų ciklas yra 255 (ty 256 reikšmės nuo 0 iki 255), galime nustatyti jį dvigubai didesnę reikšmę: 256 * 2 - 1=511 (ty 512 reikšmių nuo 0 iki 511).
Ir štai,{0}}mūsų kvėpavimo lemputė baigta! Argi ne taip paprasta? (* ̄︶ ̄)

 

Kitas yra šios dienos premijų skyrius.

Nors pasiekėme kvėpuojančios šviesos efektą, kodas nėra pakankamai glaustas ar pakankamai elegantiškas,{0}}jame naudojama daugybė if ir else teiginių. Pažiūrėkime, ar galime tai dar labiau supaprastinti.

Pirmiausia supaprastinkime šią funkcijos set_led_luminance() skyrių, kaip parodyta paveikslėlyje žemiau.
 

图片

 

Prieš supaprastindami, pateiksime trumpą patarimą apie C: operaciją bitais IR.

info-600-117

 

Iš to žinome, kad nesvarbu, ar tai yra 1, ar 0, atliekant bitų IR operaciją su 0, gaunama 0.

Nesvarbu, ar tai yra 1, ar 0, atliekant bitų IR operaciją su 1, gaunama pradinė reikšmė.

Patogumui naudojame šešioliktainį žymėjimą (priešdėlis „0x“); pavyzdžiui, 0xff atitinka 255 dešimtainiu tikslumu. Todėl

 

Kai skaičius, mažesnis arba lygus 0xff, yra AND su 0xff, rezultatas yra pats skaičius, kaip parodyta toliau

info-534-63

 

 

Kas atsitiks, jei atliksite bitų IR operaciją tarp skaičiaus, didesnio nei 0xff ir 0xff?

info-551-63

Rezultatas yra liekana, kai šis skaičius yra padalintas iš (0xff + 1) (ty rezultatas vis dar yra tarp 0 ir 0xff).
Naudojant šią bitų IR operaciją, aukščiau pateiktas kodas gali būti supaprastintas iki

info-550-64

 

 

Tokiu būdu s_Counter reikšmė visada bus nuo 0x00 iki 0xff.
Panašiai programinės įrangos laikmatį aukščiau esančioje funkcijoje breath_led taip pat galima supaprastinti taip:

info-389-353

3 eilutėje 0x1ff yra 511 dešimtaine. Sąlyga yra teisinga, kai s_breathCounter reikšmė yra (0x1ff+1) arba 512, nes 512 & 0x1ff=0. Prieš ją esantis šauktukas rodo bitų NOT operaciją (tiksliau, sąlyga įvykdoma, kai `s_breathCounter`51 reikšmė yra poreikio iš naujo nustatyti kartotinis. `s_breathCounter', tikiuosi, kad šis paaiškinimas yra aiškus{18}}pagalvokite. Jei sąlyga įvykdoma, darbo ciklas pradeda didėti arba mažėti.


Bet ar darbo ciklo diapazonas nėra nuo 0 iki 255? Kodėl 5 eilutė taip pat tampa 0x1ff (511)? Nesijaudinkite-pažiūrėkite į 8 eilutę. Vėl atimame 0xff, todėl darbo ciklo diapazonas išlieka nuo 0 iki 255.


7–10 eilutės reiškia: kai „darbo_ciklas > (0xff)“, ty 256–511, 0xff atėmimas prilygsta padidinimui nuo 1 iki 255, todėl ryškumas palaipsniui didėja.


Kai darbo ciklas<= 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, ar manai, kad mūsų supaprastinimas baigėsi?

 

Ne, ne, ne

Tiesą sakant, 7–10 eilutės galėtų būti dar labiau supaprastintos. Čia praverčia absoliučios vertės funkcija.

Ką? Kodėl naudoti absoliučios vertės funkciją?

 

Pažvelkite į 10 eilutę: 0xff - duty_cycle yra lygiavertis duty_cycle - 0xff, tada imama absoliuti vertė. Gerai, čia yra supaprastintas kodas:

set_led_luminance(ABS(darbo_ciklas - (0xff)));

 

 

Makrofunkcija absoliučiai vertei gauti yra tokia

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

 

Galiausiai, toliau įtraukiau visą supaprastintą kodą

 

info-562-684

kaip tu manai? Argi ne paprasta? (* ̄︶ ̄)

Siųsti užklausą

whatsapp

Telefono

El. paštas

Tyrimo