Gweithredu Golau Anadlu LED Gan ddefnyddio'r 51 Microreolydd

Jun 11, 2026 Gadewch neges

[Cyflwyniad]


Mae technoleg microcontroller yn dechnoleg brif ffrwd anhepgor mewn awtomeiddio diwydiannol modern, electroneg, peirianneg drydanol, a Rhyngrwyd Pethau (IoT). Wrth i'n bywydau ddod yn fwyfwy craff, mae technoleg microreolwyr wedi treiddio i bron bob agwedd ar ein bywydau bob dydd, megis mewn poptai reis smart, siaradwyr craff, a mwy.


Gyda hyn mewn golwg, nod y gyfres o erthyglau "Ail-ddysgu'r 51 Microcontroller" yw helpu dechreuwyr i ddechrau gyda thechnoleg microreolydd. Byddwn yn dechrau gyda'r dasg symlaf-troi un LED ymlaen-ac yn symud ymlaen yn raddol i weithredu modiwlau megis rheolyddion botwm, yr arddangosfa LCD1602, synwyryddion tymheredd DS18B20 a DS1302, a chyfathrebu rhwng dau ficroreolydd. Byddwn hefyd yn ymdrin â phrotocolau cyfathrebu caledwedd fel UART, I²C, a SPI. Trwy gyfuno'r cysyniadau hyn â thechnegau rhaglennu C, byddwn yn defnyddio prosiectau peirianneg byd go iawn i ddangos dulliau rhaglennu, gan eich galluogi i gymhwyso awgrymiadau a strwythurau C yn hyblyg i gyflawni rhaglennu modiwlaidd.


Nawr, gadewch i ni fynd yn ôl at y prif bwnc: defnyddio microreolydd 51 i reoli LED a chreu effaith golau anadlu.

 

[Sut mae Goleuadau Anadlu yn Gweithio]


Yn gyntaf, gadewch i ni edrych ar sut mae effaith golau anadlu yn gweithio.
Mae golau anadlu yn goleuo'n raddol ac yna'n pylu'n raddol, gan ailadrodd y cylch hwn mewn modd sy'n debyg i anadlu. Fodd bynnag, gan mai dim ond naill ai 1 (ymlaen) neu 0 (i ffwrdd) y gall pinnau microreolwr allbynnu, sut y gellir cyflawni effaith trawsnewid graddol?
Mae hyn oherwydd dyfalbarhad gweledigaeth yn ein llygaid. Pan edrychwn ar rywbeth, mae'r ddelwedd a ffurfiwyd gan ein llygaid yn parhau am 0.04 eiliad (darganfuwyd y ffigur hwn ar-lein).
Os byddwn yn cyfrifo yn seiliedig ar 0.04 eiliad, mae hynny'n hafal i 40 ms. Felly, pan fydd y LED ymlaen ac i ffwrdd am 20 ms yr un, mae'n ymddangos i'r llygad dynol fel pe bai'n cael ei oleuo'n gyson.

图片

A yw effaith fflachio LED ymlaen am 20 ms ac i ffwrdd am 20 ms yr un peth â chael iddo aros ymlaen drwy'r amser?

 

Haha, mae'n bendant yn wahanol. Pan fydd y golau yn troi ymlaen ac i ffwrdd bob 20 milieiliad, mae'r effaith a welwn yn pylu na phan fydd yn aros ymlaen yn barhaus. Os tybiwn mai 100% yw disgleirdeb golau sy'n cael ei oleuo'n barhaus, yna mae disgleirdeb golau sy'n newid bob yn ail rhwng bob 20 milieiliad yn 50%. Yn seiliedig ar hyn, gallwn addasu disgleirdeb y LED.

图片

 

Ar y pwynt hwn, gallwn addasu disgleirdeb y LED (trwy osod hyd y lefel uchel o fewn y cylch 40ms). Dyma'r egwyddor y tu ôl i'r dull PWM (Modiwleiddio Lled Pwls) adnabyddus o reoli disgleirdeb, ac mae gosod hyd y lefel uchel yn cyfateb i addasu'r cylch dyletswydd (hy, hyd y lefel uchel wedi'i rannu â chyfanswm y cylch: 20/40=50%).


Yma, y ​​ffactor pwysicaf yw'r cylch dyletswydd hwn. Er enghraifft, os yw'r cyfnod yn 20 ms, gyda'r LED bob yn ail rhwng 10 ms ymlaen a 10 ms i ffwrdd, mae'r disgleirdeb canfyddedig yn dal i fod yn 50% (hy, y cylch dyletswydd yw 10/20=50%).

Nesaf, gadewch i ni weld sut mae hyn yn cael ei weithredu yn y rhaglen.

 

[Gweithredu Rhaglen]


Troi LED ymlaen
Yn gyntaf, gadewch i ni ddechrau trwy droi LED ymlaen, ac yna byddwn yn gweithredu effaith golau anadlu yn raddol. Mae'r caledwedd y byddwn yn ei ddefnyddio fel a ganlyn:

Bwrdd Datblygu Bwrdd Datblygu Hyfforddiant Microreolwyr ZeroOne
Model microreolydd STC89C52
Rhyngwyneb LED Pin P4^4
图片

 

O'r sgematig, gallwn weld bod y LED wedi'i gysylltu â phin P4 ^ 4 y microreolydd. Pan fydd y microreolydd yn allbynnu 1, mae'r LED yn troi ymlaen; pan fydd yn allbynnu 0, mae'r LED yn diffodd. Felly, mae'r rhaglen i droi LED ymlaen yn eithaf syml, fel y dangosir isod:

info-299-230

 

 

Mae'r rhaglen i droi LED ymlaen yn eithaf syml; Rwy'n siŵr bod pawb yn gwybod sut i wneud hynny.
 

Addasu disgleirdeb LED


Nesaf, byddwn yn gweithredu swyddogaeth sy'n ein galluogi i addasu'r disgleirdeb (hy, addasu'r cylch dyletswydd), fel a ganlyn:

info-400-538


 

Diffiniwch 'gylchred_dyletswydd' newidyn statig i storio'r cylch dyletswydd. Pan fydd `baner` yn 1, mae'r cylch dyletswydd yn cynyddu'n raddol i 255, yna gosodwch `faner` i 0, ac mae`r cylch dyletswydd yn gostwng yn raddol o 255 i 0. Ailadroddwch y cylch hwn.
Haha, ar y pwynt hwn, efallai y byddwch chi'n meddwl bod y golau anadlu eisoes yn gweithio, ond nid yw. Os nad ydych yn fy nghredu, rhowch gynnig ar y cod uchod eich hun.

Felly ble yn union mae'r broblem?


Mae'r broblem yn gorwedd yn ein galwad uniongyrchol i'r swyddogaeth gosod disgleirdeb -set_led_luminance()`. Mae'r ffwythiant hwn yn cymryd 40 ms i gwblhau un cylchred, sy'n golygu na ellir newid y gylchred ddyletswydd yn ystod y 40 ms hynny; fel arall, ni fydd yr addasiad disgleirdeb yn gweithio. Gadewch i ni edrych eto ar y swyddogaeth `anadl_led`. Ar ôl pob galwad i `set_led_luminance()` i osod y cylch dyletswydd, mae'n newid gwerth y cylch dyletswydd ar unwaith heb aros am 40 ms.


Ar y pwynt hwn, mae angen i ni ychwanegu amserydd meddalwedd i ddiweddaru'r gwerth `duty_cycle` ar ôl i 40 ms ddod i ben. Mae'r rhaglen wedi'i haddasu fel a ganlyn:

info-495-656

 

 

Nodyn: Mae angen i hyd yr amserydd fod yn fwy na 40 ms (sy'n golygu bod yn rhaid i werth `s_breathCounter` fod yn fwy na 255), ond mae'n well ei osod i luosrif y gylchred. Er enghraifft, os yw ein cylchred yn 255 (hy, 256 o werthoedd o 0 i 255), gallwn ei osod i ddwywaith y gwerth hwnnw: 256 * 2 - 1=511 (hy, 512 o werthoedd o 0 i 511).
A dyna chi-mae ein golau anadlu wedi'i gwblhau! Onid yw hynny'n syml? (* ̄︶ ̄)

 

Nesaf i fyny yw'r adran bonws heddiw.

Er ein bod wedi cyflawni'r effaith golau anadlu, nid yw'r cod yn ddigon cryno nac yn ddigon cain-mae'n defnyddio llawer o ddatganiadau os ac arall. Gawn ni weld a allwn ni ei symleiddio ymhellach.

Yn gyntaf, gadewch i ni symleiddio'r adran hon o'r swyddogaeth set_led_luminance(), fel y dangosir yn y ffigur isod.
 

图片

 

Cyn i ni symleiddio hyn, gadewch i ni gwmpasu awgrym cyflym am C: y bitwise AND gweithrediad.

info-600-117

 

O hyn, rydyn ni'n gwybod, p'un a yw'n 1 neu'n 0, bod perfformio ychydig yn ddoeth AC â 0 yn arwain at 0.

P'un a yw'n 1 neu'n 0, mae perfformio ychydig yn ddoeth AC gydag 1 yn arwain at y gwerth gwreiddiol.

Er hwylustod, rydym yn defnyddio nodiant hecsadegol (wedi'i rhagddodi â "0x"); er enghraifft, mae 0xff yn cyfateb i 255 mewn degol. Felly,

 

Pan fydd rhif sy'n llai na neu'n hafal i 0xff yn cael ei ANDed gyda 0xff, y canlyniad yw'r rhif ei hun, fel y dangosir isod

info-534-63

 

 

Beth sy'n digwydd os byddwch yn perfformio ychydig yn ddoeth AC rhwng rhif sy'n fwy na 0xff a 0xff?

info-551-63

Y canlyniad yw'r gweddill pan rennir y rhif hwn â (0xff + 1) (hy, mae'r canlyniad yn dal i fod rhwng 0 a 0xff).
Gyda'r gweithrediad bitwise AND hwn, gellir symleiddio'r cod uchod i

info-550-64

 

 

Fel hyn, bydd gwerth s_Counter bob amser o fewn yr ystod o 0x00 i 0xff.
Yn yr un modd, gellir hefyd symleiddio'r amserydd meddalwedd yn y swyddogaeth breath_led uchod fel a ganlyn:

info-389-353

Yn llinell 3, 0x1ff yw 511 mewn degol. Mae'r amod yn wir pan fydd gwerth s_breathCounter yn (0x1ff+1), neu 512, oherwydd 512 & 0x1ff=0. Mae'r ebychnod cyn iddo yn dynodi gweithrediad bitwise NOT (i fod yn fanwl gywir, mae'r amod yn cael ei fodloni pan fydd gwerth `s_breathCounter` yn lluosrif o 512 mae angen i hwn ddileu'r anadl. esboniad yn glir-meddyliwch drwyddo). Os bodlonir yr amod, mae'r cylch dyletswydd yn dechrau cynyddu neu leihau.


Ond onid 0 i 255 yw'r ystod cylch dyletswydd? Pam mae llinell 5 hefyd yn dod yn 0x1ff (511)? Peidiwch â phoeni-edrychwch ar linell 8. Rydyn ni'n tynnu 0xff eto, felly mae'r ystod cylchred dyletswydd yn aros rhwng 0 a 255.


Mae llinellau 7–10 yn golygu: Pan fydd `cylch_dyletswydd > (0xff)`, hy, 256–511, mae tynnu 0xff yn cyfateb i gynyddu o 1 i 255, felly mae'r disgleirdeb yn cynyddu'n raddol.


Pan ddyletswydd_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, oeddech chi'n meddwl bod ein symleiddio drosodd?

 

Na, na, na

Mewn gwirionedd, gellid symleiddio llinellau 7 i 10 hyd yn oed ymhellach. Dyma lle mae'r swyddogaeth gwerth absoliwt yn dod yn ddefnyddiol.

Beth? Pam defnyddio'r swyddogaeth gwerth absoliwt?

 

Edrychwch ar linell 10: 0xff Mae - duty_cycle yn cyfateb i duty_cycle - 0xff ac yna cymryd y gwerth absoliwt. Iawn, dyma'r cod symlach:

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

 

 

Mae'r swyddogaeth macro ar gyfer cymryd y gwerth absoliwt fel a ganlyn

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

 

Yn olaf, rwyf wedi cynnwys y cod symlach cyfan isod

 

info-562-684

Beth yw eich barn chi? Onid yw'n syml? (* ̄︶ ̄)

Anfon ymchwiliad

whatsapp

Dros y ffôn

E-bost

Ymchwiliad