Cuprins:

Programare simultană Attiny85 sau dovleac cu ochi multicolori: 7 pași
Programare simultană Attiny85 sau dovleac cu ochi multicolori: 7 pași

Video: Programare simultană Attiny85 sau dovleac cu ochi multicolori: 7 pași

Video: Programare simultană Attiny85 sau dovleac cu ochi multicolori: 7 pași
Video: ATtiny85 (introducere) 2024, Noiembrie
Anonim

De jumbleviewJumbleview.info Urmăriți mai multe de la autor:

Țipătul
Țipătul
Țipătul
Țipătul
Înlocuirea bateriei NiCd cu sursă de alimentare externă
Înlocuirea bateriei NiCd cu sursă de alimentare externă
Înlocuirea bateriei NiCd cu sursă de alimentare externă
Înlocuirea bateriei NiCd cu sursă de alimentare externă
Mâner aparat de fotografiat digital
Mâner aparat de fotografiat digital
Mâner aparat de fotografiat digital
Mâner aparat de fotografiat digital

Despre: Lucrez ca inginer software într-una dintre companiile din Bay Area (California). Ori de câte ori am timp îmi place să programez microcontrolere, să construiesc jucării mecanice și să fac câteva proiecte de îmbunătățire a locuințelor. Mai multe despre jumbleview »

Acest proiect arată cum să controlați două LED-uri anodice comune de 10 mm cu trei culori (ochi multicolori de Pumpkin Halloween Glitter) cu cip Attiny85. Scopul proiectului este de a introduce cititorul în arta programării concomitente și în utilizarea bibliotecii de prototipuri Adam Dunkels. Acest proiect presupune că cititorul știe despre controlerele AVR pe 8 biți, poate scrie niște programe C și are o experiență cu Atmel studio.

Codul proiectului publicat pe GitHub:

Provizii

Înainte de programare, trebuie încă să construiți circuitul. Iată componentele:

  • Controler Attiny85 (orice furnizor electronic).
  • Două LED-uri de trei mm de 10 mm cu anod comun. LED-uri Adafruit
  • Rezistoare 100 Ohm, 120 Ohm, 150 Ohm 0,125 sau 0,250 Wt (orice furnizor electronic).
  • Antet cu șase pini pentru interfața ISP AVR. Poate fi realizat din acest antet Adafruit
  • Unele plăci pentru pâine sau șablon tipărit. L-am folosit pe
  • Interfața AVR ISP MKII și Atmel Studio 6.1 (Versiunea ulterioară ar trebui să funcționeze și).

Pasul 1: Circut

Circut
Circut

Designul utilizează cinci pini de cip:

  • Doi pini folosiți pentru controlul anodilor: fiecare anod LED atașat pinului dedicat.
  • Trei pini atașați (prin rezistențe) la catoduri LED (același catod de culoare al fiecărui led atașat la același pin)

S-ar întreba: de ce să nu folosiți toți cei șase pini de intrare / ieșire ai cipului, astfel încât anodii LED vor fi conectați direct la +5 v și fiecare catod va avea pinul dedicat? Acest lucru va face programarea simplă. Din păcate, există problema: pinul PB5 (RESET) este un pin slab capabil să furnizeze doar ~ 2 mA din curent, în timp ce este nevoie să aibă ~ 20 mA.

Desigur, se poate construi un amplificator de tranzistor pentru acest pin slab, dar eu, ori de câte ori este posibil, prefer să rezolv problema prin cod.

Pasul 2: Diagrama de sincronizare

Diagrama de sincronizare
Diagrama de sincronizare

Diagrama de sincronizare ne ajută să înțelegem ce trebuie să programăm.

Primele două rânduri de pe diagramă arată schimbarea tensiunii pe anodii LED. Tensiunea pinilor conectați la anodii LED oscilează cu o frecvență de ~ 250 Hz. Această oscilație de tensiune pentru LED-ul din stânga este opusă oscilației LED-ului din dreapta. Când tensiunea pe anod este ridicată, LED-ul corespunzător poate fi luminos. Când este scăzut, LED-ul corespunzător este întunecat. Asta înseamnă că fiecare LED poate fi luminos în intervalul de 2 milisecunde și este întunecat în alte 2 milisecunde. Deoarece ochiul uman are o oarecare inerție, clipirea de 250 Hz nu este vizibilă de către observator. Să ne uităm la prima coloană diagramă. Afișează cazul când LED-ul stâng este roșu și LED-ul drept în culoare verde. Aici catodii ROȘI rămân scăzuți în timp ce anodul stâng este ridicat, catodul VERDE rămâne scăzut în timp ce anodul drept este ridicat, iar catodul ALBASTRU rămâne scăzut tot timpul. Alte coloane din diagramă arată combinații de tensiune catodică și anodică pentru diferite culori.

După cum putem vedea, există interdependență de starea pinilor. Fără un anumit cadru, nu ar fi ușor de rezolvat. Și aici este utilă biblioteca protothread.

Pasul 3: Programare. Macro și definiții

Programare. Macro și definiții
Programare. Macro și definiții

Exemplul în pașii de programare reprezintă o versiune ușor simplificată. Programul este scurtat, iar unele definiții simbolice înlocuite cu constante explicite.

Să începem de la început. Programul include fișiere care vin cu Atmel Studio, precum și antetul bibliotecii protothread. Apoi, există două macrocomenzi pentru a manipula nivelurile pinilor și câteva definiții pentru a da nume logice semnalelor pin. Până acum nimic special.

Pasul 4: Programare. Bucla principală

Programare. Bucla principală
Programare. Bucla principală

Apoi, să ne uităm la final pentru a vedea ce conține procedura principală.

Funcția principală după inițializare rămâne în buclă permanentă. În acea buclă face pașii următori:

  • Invocă rutina protothread pentru LED-ul din stânga. Schimbă tensiunea unor pini.
  • Faceți o întârziere de două milisecunde. Nu există nicio modificare a tensiunii pinului.
  • Invocă firul prototip pentru LED-ul potrivit. Schimbă o anumită tensiune a pinului.
  • Faceți 2 MS întârziere. Nu există nicio modificare a tensiunii pinului.

Pasul 5: Programare. Funcții auxiliare

Programare. Funcții auxiliare
Programare. Funcții auxiliare

Înainte de a începe să discutăm firele prototree, trebuie să analizăm câteva funcții de ajutor. Mai întâi există funcții pentru a seta o anumită culoare. Sunt simple. Există atât de multe funcții precum numărul de culori acceptate (șapte) și încă o funcție pentru a seta LED-ul întunecat (NoColor).

Și mai există o funcție care va fi invocată direct de rutina protothread. Numele său este DoAndCountdown ().

Din punct de vedere tehnic, utilizarea unei astfel de funcții nu este obligatorie, dar mi s-a părut convenabilă. Are trei argumente:

  • Pointer pentru funcția de setare a culorii LED-ului (cum ar fi RedColor sau GreenColor sau etc.)
  • Valoarea inițială a contorului invers: numărul de câte ori trebuie invocată această funcție la un anumit stadiu de prototire.
  • Pointer pentru inversarea contorului. Se presupune că atunci când există o schimbare a culorii, contorul invers este 0, deci la prima cod de iterație îi va fi atribuit valoarea inițială a contorului. După ce fiecare contor de iterații este decrementat.

Funcția DoAndCountdown () returnează valoarea contorului invers.

Pasul 6: Programare. Rutine Protothread

Programare. Rutine Protothread
Programare. Rutine Protothread

Și aici este nucleul cadru: rutina protothread. Din motive de simplitate, exemplul este limitat doar la trei pași: pentru schimbarea culorii la ROȘU, la VERDE și la ALBASTRU.

Funcția este invocată cu două argumente:

  • Pointer către structura filetului prototip. Această structură a fost inițiată de main înainte de a începe bucla principală.
  • Pointer pentru inversarea contorului. A fost setat la 0 de main înainte de a începe bucla principală.

Funcția setează tensiunile pentru a face LED-ul stâng activ și apoi pornește segmentul filetului prototip. Acest segment este între macro-urile PT_BEGIN și PT_END. În interior există un cod care, în cazul nostru, repetă doar macrocomenzile PT_WAIT_UNTIL. Aceste macrocomenzi efectuează următoarele:

  • Invocarea funcției DoAndCountdown. Aceasta setează tensiunea pe catodii LED pentru a emite o anumită culoare.
  • Rezultatul returnat comparativ cu 0. Dacă condiția este „falsă”, funcția protothread revine imediat și cedează controlul buclei principale.
  • Când protothread este invocat data viitoare, execută din nou cod înainte de PT_BEGIN, apoi sare direct în macrocomenzile PT_WAIT_UNTIL de la care a revenit ultima dată.
  • Astfel de acțiuni repetate până când rezultatul DoAndCountdown este 0. În acest caz nu există nicio returnare, programul rămâne în firul de prototip și execută următoarea linie a codului. În cazul nostru este următorul PT_WAIT_UNTIL dar, în general, ar putea fi aproape orice cod C.
  • La execuția inițială a celui de-al doilea contor invers PT_WAIT_UNTIL este 0, deci procedura DoAndCountdown () îl setează la valoarea inițială. A doua macrocomenzi vor fi executate din nou de 250 de ori până când contorul de inversare ajunge la 0.
  • Starea struct pt este resetată imediat ce controlul atinge macrocomenzile PT_END. Când funcția protothread este invocată data viitoare când segmentul protothread începe, executați linia codului imediat după PT_BEGIN.

Există o rutină similară de prototread pentru LED-ul potrivit. În exemplul nostru, aceasta impune o ordine diferită a culorilor, dar dacă o putem face complet diferit: nu există o cuplare strânsă între rutina LED stângă și dreaptă.

Pasul 7: Internele

Internele
Internele

Programul întreg este mai mic de 200 de linii de cod (cu comentarii și linii goale) și ocupă mai puțin de 20% din memoria de cod Attiny85. Dacă este necesar, este posibil să utilizați aici mai multe rutine de prototire și să le atribuiți o logică mult mai complicată.

Biblioteca Protothreads este cea mai simplă formă de programare simultană a computerului. Programarea concurentă este o abordare care permite împărțirea programului în părți logice: uneori sunt numite coroutine, alteori fire, alteori sarcini. Principiul este că fiecare astfel de sarcină poate împărtăși aceeași putere a procesorului, păstrând în același timp codul mai mult sau mai puțin liniar și independent de alte părți. Sarcinile din punct de vedere logic pot fi executate simultan.

Pentru sisteme avansate de control al acestor sarcini efectuate fie de către nucleul sistemului de operare, fie de limbajul de rulare încorporat în executabil de către compilator. Dar în cazul aplicațiilor protothreads programatorul o controlează manual utilizând biblioteca de macrocomenzi protothreads în rutinele de activități și invocând astfel de rutine (de obicei în afara buclei principale).

Probabil că doriți să știți cum funcționează de fapt protothread? Unde s-a ascuns magia? Protothreads se bazează pe o caracteristică specială a limbajului C: faptul că declarația cu majuscule C poate fi încorporată în if sau în alt bloc (cum ar fi while sau for). Detalii pe care le puteți găsi pe site-ul Adam Dunkels

Internele electronice ale acestui proiect sunt foarte simple. Fotografia de mai sus vă oferă câteva indicii. Sunt sigur că te poți descurca mai bine.

Recomandat: