Subsemnatul Nistorescu Cosmin, student la specializarea Tehnologii Informatice în Ingineria Sistemelor din cadrul Facultății de Automatică,… [310803]
PROIECT DE DISERTAȚIE
Nistorescu Cosmin
COORDONATOR ȘTIINȚIFIC
Dr. Ing. Constantin Pătrașcu
Iulie 2018
CRAIOVA
Sarcină rezistivă programabilă
Nistorescu Cosmin
COORDONATOR ȘTIINȚIFIC
Dr. Ing. Constantin Pătrașcu
Iulie 2018
[anonimizat]: [anonimizat], Calculatoare și Electronică a [anonimizat], [anonimizat]:
[anonimizat]. Ing. [anonimizat] 2018.
[anonimizat]:
reproducerea exactă a [anonimizat]-o [anonimizat]-o [anonimizat],
[anonimizat], [anonimizat] a unor aplicații realizate de alți autori fără menționarea corectă a [anonimizat] a [anonimizat].
Pentru evitarea acestor situații neplăcute se recomandă:
plasarea între ghilimele a citatelor directe și indicarea referinței într-o [anonimizat] a [anonimizat] a sursei originale de la care s-a [anonimizat] s-[anonimizat], figuri, imagini, statistici, [anonimizat], a căror paternitate este unanim cunoscută și acceptată.
Data, Semnătura candidat: [anonimizat],
PROIECTUL DE DIPLOMĂ
REFERATUL CONDUCĂTORULUI ȘTIINȚIFIC
În urma analizei lucrării candidat: [anonimizat]:
[anonimizat]:
Data, [anonimizat] o sarcină rezistivă programabilă care poate să ofere o rezistență maximă de ~870 Ω și o rezistență minimă de 0.1 Ω. Rezoluția sistemului trebuie să fie de 0.1 Ω.
Sarcină rezistivă programabilă va trebuii să afișeze și controleze rezistențele cu ajutorul butoanelor. Acesta trebuie să suporte:
Tensiunea maximă 26V
Curentul maxim 30A
Puterea maximă 300W
MULȚUMIRI
Vreau să mulțumesc coordonatorului științific pentru ajutorul acordat și cadrelor didactice care m-[anonimizat]-a lungul a celor doi ani de studiu.
„Citește. Numai citind mereu creierul tău va deveni un laborator nesfîrșit de idei și imagini.”
Mihai Eminescu
CUPRINS
LISTA FIGURILOR
Figura 1. Schema bloc a proiectului 16
Figura 2. Schema electronică a plăcii de control 17
Figura 3. Schema electronică a plăcii de comandă a rezistențelor de valoare mică 18
Figura 4. Schema electronică a plăcii de comandă a rezistențelor de valoare mare 19
Figura 5. Schema electronică a plăcii de alimentare 20
Figura 6. Diagrama logică a proiectului 20
Figura 7. Schema familiei AVR8 21
Figura 8. Structura internă generală a microcontrolerului Atmega16 22
Figura 9. Diagrama bloc (Atmega16) 23
Figura 10. Registrul de stare 25
Figura 11. Schema echivalentă a unui pin 29
Figura 12. Semnificația pinilor 29
Figura 13. Indicator de stivă 31
Figura 14. Organizarea spațiului de memorie 31
Figura 15. Schema electronică a rezonatorului ceramic 32
Figura 16. Redresare în punte cu filtraj 33
Figura 17. Transformatorul electric al proiectului 34
Figura 18. Schema bloc a circuitului integrat LM7805 34
Figura 19. Schema electronică a sursei de 5V 35
Figura 20. Display LCD 16X2 35
Figura 21. Diagrama bloc (LCD 16X2) 36
Figura 22. Ajustarea contrastului pentru modulul LCD 16X2 37
Figura 23. Caracteristici de timp, segment de timp scriere 39
Figura 24. Caracteristici de timp, segment de timp citire 39
Figura 25. Senzorul de temperatură NTC-100K 41
Figura 26. Caracteristica putere consumată – temperatură ambiantă 42
Figura 27. Caracteristica valoare citită – valoare afișată (ntc-100k) 42
Figura 28. Schema electronică pentru protecția termică 43
Figura 29. Mesaj de supraîncălzire 43
Figura 30. Poziționarea senzorului de temperatură pe radiator 44
Figura 31. Schema electronică a unei perechi Darlington 45
Figura 32. Diagrama logică a componentei ULN2803 45
Figura 33. Releul 46
Figura 34. Schema electronică a acționării releului 47
Figura 35. Conexiunea rezistențelor pentru sarcina rezistivă programabilă 48
Figura 36. Schema electrică a cititorului de tensiune 49
Figura 37. Divizorul rezistiv 50
Figura 38. Sarcina rezistivă programabilă în format 3D 51
Figura 39. Meniul principal al sarcinei rezistive programabile 52
Figura 40. Meniul de limitare a sarcinei rezistive programabile 52
Figura 41. Programatorul USBASP 53
Figura 42. Schema electronică a programatorului USBASP 53
Figura 43. Fereastra de dialog project 54
Figura 44. Fereastra de dialog Create new project 54
Figura 45. Fereastra de dialog debug platform and device 55
Figura 46. Fereastra de dialog configurations options 55
Figura 47. Fereastra de dialog configurations settings 56
Figura 48. Fereastra de lucru 56
Figura 49. Fereastra de dialog build 56
Figura 50. Fereastra de dialog microcontroler 57
Figura 51. Fereastra de dialog pentru tipul programării 57
Figura 52. Fereastra de dialog pentru deschiderea fișierului pentru microcontroler 58
Figura 53. Fereastra de configurare a biților ceasului de tact 58
Figura 54. Fereastra de scriere a microcontrolerului 59
Figura 55. Cablajul (placa) de alimentare 60
Figura 56. Cablajul (placa) de control 60
Figura 57. Cablajul (placa) de comandă a rezistențelor de valoare mică 61
Figura 58. Cablajul (placa) de comandă a rezistențelor de valoare mare 61
Figura 59. Placa de alimentare 62
Figura 60. Placa de control 62
Figura 61. Placa de comandă a rezistențelor de valoare mică 63
Figura 62. Placa de comandă a rezistențelor de valoare mare 63
Figura 63. Interiorul sarcinei rezistive programabile 64
Figura 64. Sarcina rezistivă programabilă ansamblată 64
LISTA TABELELOR
TABELUL 1. SPECIFICAȚII GENERALE (16X2) 36
TABELUL 2. CARACTERISTICI ELECTRICE 37
TABELUL 3. CARACTERISTICILE OPTICE 37
TABELUL 4. FUNCȚIILE PINILOR 38
TABELUL 5. CARACTERISTICI DE TIMP PENTRU SCRIERE 38
TABELUL 6. CARACTERISTICI DE TIMP PENTRU CITIRE 39
TABELUL 7. CARACTERISTICILE MATERIALELOR ( PLATINĂ, NICHEL, CUPRU) 42
TABELUL 8. PUTEREA DE DISIPARE A REZISTENȚELOR 49
Introducere
Bancul de sarcină cunoscut și sub numele de ‘load bank’ este un dispozitiv care dezvoltă o sarcină electrică. Rezultatul obținut după aplicarea sarcinei unei surse electrice este convertirea sau disiparea puterii.
Scopul bancului de sarcină este de a înlocuii o sarcină reală precum un motor, un bec etc. Spre deosebire de o sarcină reală care poate fi nepredictibilă și aleatoare în valori, bancul de sarcină poate oferii o sarcină organizată și ușor de controlat.
Scopul unei sarcini reale este de a folosii energia generată de către sursă în scopuri productive, în timp ce bancul de sarcină folosește emergia generată de sursă pentru teste sau chiar pentru protecția acesteia.
Bancul de sarcini este folosit în multe aplicații precum:
Testarea în fabrică a turbinelor și a generatorului motorului diesel
Testarea bateriilor și a sistemelor UPS
Testarea împământării
Reducerea carbonului de pe inelele pistonului al generatorului
Testarea electricității și a aerului condiționat
Cele mai comune bancuri de sarcini sunt cele rezistive, inductive și capacitive.
Sarcina unui banc de sarcină rezistivă este creată de conversia energiei electrice în căldură cu ajutorul rezistențelor de putere. Această temperatură trebuie sa fie disipată din bancul de sarcină în aer.
În testarea sistemului, sarcinile rezistive trebuie să simuleze sarcini reale precum becurile incandescente și sarcini predispuse la încălzire, precum rezistența sau puterea componentelor magnetice a motoarelor sau a transformatoarelor.
2. sarcina rezistivă programabilă
Unitatea centrală a sistemului este un microcontroller Atmega16, ce are rolul de a achiziționa, prelucra și de a controla sistemul. De asemenea acesta este responsabil și de controlul și achiziția de perifice precum ventilatoarele, butoanele, senzorul de temperatură și display-ul.
Microcontrolerul este un circuit care integrează o serie de dispozitive periferice și un microprocesor într-un singur chip, punându-se accentul pe un cost redus al producției și un consum redus de energie electrică. Diferența principală dintre un microcontroler și un microprocesor este reprezentată de faptul ca un microcontroler integrează o memorie în care se incarcă programul, o memorie de date și interfețe de intrare-ieșire unde se pot conecta diferite dispozitive periferice. Din cauza costului redus de productie și a integrării unui numar foarte mare de dispozitive periferice, un microcontroler operează la viteze mai reduse, frecvența lui de ceas fiind de zeci sau chiar sute de MHz și un ordin de marime mai mic decat cea de la un microprocesor.
Cu toate acestea, microcontrolerele sunt utilizate într-o gamă foarte mare de aplicații fiind folosite în mediul industrial, de la sisteme din industria aerospațială până la cuptoare cu microunde, telefoane mobile și jucarii. Majoritatea sistemelor de calcul pe care le intâlnim în ziua de astăzi au evoluat din suportul unui calculator obișnuit și au fost integrate în multe alte dispozitive cum ar fi automobilele sau produsele electronice care formează ceea ce se cheamă un sistem embedded. Sistemul embedded poate veni intr-un “pachet” foarte diferit în comparatie cu un calculator obișnuit. Spre exemplu, aceste sisteme pot sa nu fie dotate cu o tastatura sau un display, intrarile și ieșirile fiind alcatuite din simple comutatoare si led-uri. Un astfel de sistem poate să aibă cerințe de performanță minime sau o capacitate de memorie și viteză de execuție mică. Un microcontroler dintr-un sistem embedded poate să execute o gamă foarte variată de operații, de la controlul unor led-uri sau motoare electrice până la comunicarea cu alte device-uri asemănătoare într-o rețea wireless. Majoritatea microcontrolerelor nu au nevoie de magistrale externe de adrese sau de date, deoarece toate memoriile de date sunt interne. Acest lucru a dus la integrarea acestora în capsule cu un numar redus de pini și dimensiuni mici, ceea ce a dus în schimb la reducerea costurilor de producție.
Unele microcontrolere aparțin arhitecturii Harvard, unde magistralele de date sunt separate de cele de instructiuni, permițând astfel un acces concurent. În cazul in care folosim aceasta arhitectură, lungimea instructiunilor poate fi diferită de registrele și memoria internă. De exemplu, in familia AVR de la Atmel registrele interne sunt de 8 biți, iar instructiunile au lungimea de 16 biți. Costul unui astfel de microcontroler depinde in mare măsură de numărul de despozitive periferice integrate în microcontroler. Cu cât numarul acestor periferice este mai mare cu atât nivelul de integrare crește, iar costul de producție este mai mare. Din această cauză, arhitecturile de microcontrolere pe piață la această ora variază in limite destul de largi, de la microchipuri cu doar 6 pini de intrare/iesire până la procesoare digitale de semnal(DSP) sau procesoare cu arhitecturi ARM. La ora actuală, în lume sunt cateva zeci de firme producatoare care oferă o gamă variată de microcontrolere din punct de vedere al dotărilor, vitezei de execuție sau arhitecturii.
În figura 1 este prezentată schema bloc a proiectului. După cum se poate observa sistemul este alcătuit din sursa de alimentare de curent continuu, unitatea centrală a acestuia și perifericele aferente precum butoanele, ventilatoarele, rezistențele, afișorul etc. Microcontrollerul Atmega16 este responsabil de achiziția informațiilor de la senzorul de temperatură, a butoanelor și a tensiunii aplicate sarcinei; de comanda un afișorului LCD, a ventilatoarelor și a releelor.
.
Figura 1. Schema bloc a proiectului
Sarcina rezistivă programabilă este format din patru plăcuțe electronice:
Placa de alimentare
Placa de control
Placa de comandă a rezistențelor de valoare mică
Placa de comandă a rezistențelor de valoare mare
Figura 2. Schema electronică a plăcii de control
Figura 3. Schema electronică a plăcii de comandă a rezistențelor de valoare mică
Figura 4. Schema electronică a plăcii de comandă a rezistențelor de valoare mare
Figura 5. Schema electronică a plăcii de alimentare
Figura 6. Diagrama logică a proiectului
2.1 Microcontrolerul ATmega16
ATmega16 este un microcontroler RISC pe 8 biți realizat de firma Atmel. ATmega16 este de mică putere bazat pe arhitectura RISC AVR îmbunatațită. Memoriile ROM, EEPROM și SRAM sunt integrate în același chip, înlaturând nevoia de memorie externă. Dispune de un set de 131 instrucțiuni și 32 de regiștri de uz general. Cele 32 de registre sunt direct adresabile de Unitatea Logică Aritmetică (ALU), permițând accesarea a două registere independente într-o singură instrucțiune. Astfel se obține o eficiența mai mare in execuție (de până la 10 ori mai rapide decât cele convenționale CISC).
Microcontrolerele AVR pe 8 biți (Atmel) au la bază un nucleu RISC cu arhitectura Harvard. Aceste microcontrolere sunt destinate aplicațiilor simple: controlul motoarelor, controlul fluxului de informație pe portul USB, aplicații din domeniul automobilelor, controlul accesului de la distanță, etc.
Figura 7. Schema familiei AVR8
2.1.1 Caracteristici
Principalele caracteristici ale acestuia sunt:
16 KB de memorie Flash reinscriptibilă pentru stocarea programelor;
1 KB de memorie RAM;
512 B de memorie EEPROM;
două numărătoare/temporizatoare de 8 biți;
un numărător/temporizator de 16 biți;
conține un convertor analog – digital de 10 biți, cu intrări multiple;
conține un comparator analogic;
conține un modul USART pentru comunicație serial(port serial);
dispune de un cronometru cu oscilator intern;
oferă 32 de linii I/O organizate in patru porturi (PA, PB, PC, PD).
Figura 8. Structura internă generală a microcontrolerului ATmega16
Funcția principală a nucleului CPU-AVR este aceea de a asigura executia corectă a programului. Pentru aceasta, nucleul este capabil să acceseze memoriile, sa execute calcule, sa controleze perifericele și sa prelucreze întreruperile. Structura internă generală a controlerului este prezentată în figura 8. Se poate observa că există o magistrală generală de date la care sunt conectate mai multe module:
unitatea aritmetică și logică (ALU) ;
registrele generale ;
memoria RAM și memoria EEPROM ;
liniile de intrare (porturile I/O) și celelalte blocuri de intrare/ieșire.
O caracteristică foarte importantă pentru orice procesor și în particular pentru microcontrolere este sistemul de întreruperi. O întrerupere reprezintă un semnal generat de un modul extern unității centrale de procesare (CPU) pentru a anunța apariția unui eveniment care trebuie tratat. Utilizarea unui astfel de sistem permite implementarea de module specializate care să execute operații în paralel cu CPU și să solicite intervenția acestuia numai la terminarea operațiilor sau în alte cazuri definite.
Figura 9. Diagrama bloc (Atmega16)
ATmega16 dispune de 21 surse de întrerupere. Atunci când una dintre ele devine activă se suspendă cursul normal de execuție și se face salt automat la o adresă prestabilită din memoria program.
Reset – Generată la alimentare sau la un semnal pe pinul RESET
EXT INT0 – Întrerupere externă 0
EXT INT1 – Întrerupere externă 1
TIM2_COMP – Generată când Timer/Counter2 atinge valoarea de prag
TIM2_OVF – Generată când Timer/Counter2 atinge valoarea maximă
TIM1_CAPT – Generată de unitatea de captură a timerului pe 16 biți
TIM1_COMPA – Generată când timerul pe 16 biți atinge valoarea de prag A
TIM1_COMPB – Generată când timerul pe 16 biți atinge valoarea de prag B
TIM1_OVF – Generată când timerul pe 16 biți atinge valoarea maximă
TIM0_OVF – Generată când Timer/Counter0 atinge valoarea maximă
SPI_STC – Generată de unitatea SPI
UART_RXC – Generată la recepția completă a unor date de catre modulul USART
UART_DRE – Generată când registrul de date al modulului USART este gol
UART_TXC – Generată la transmisia completă a unor date de către modulul USART
ADC – Generată de modulul ADC
EE_RDY – Generată de modulul EEPROM
ANA_COMP – Generată de comparatorul analogic
TWI – Generată de modulul TWI
INT2 – Întrerupere externă 2
TIM0_COMP – Generată când Timer/Counter0 atinge valoarea de prag
SPM_RDY – Generată de modulul de auto-scriere a memoriei Flash
Dacă o singură întrerupere nu este utilizată se recomandă ca pe poziția acesteia să se introducă o instrucțiune de salt către eticheta RESET. Primele patru instrucțiuni care apar după eticheta RESET sunt utilizate pentru a inițializa pointer-ul de stivă definit de registrele SPH și SPL.
ATmega16 este susținut de o serie completă de instrumente de program și de dezvoltare a sistemului, care include: compilatoare, macroasambloare, programe debug/simulare etc.
Registrul de stare (SREG)
Registrul de stare contine informații despre ultima operație aritmetică efectuată de ALU. După fiecare operație aritmetică, starea registrului este actualizată. Conținutul registrului de stare poate fi salvat/restaurat prin program, de exemplu, la accesarea unei subrutine.
Figura 10. Registrul de stare
Bitul 7 (I – Global Interrupt Enable) – activare/dezactivare globală întreruperi
Acest bit trebuie să aibă valoarea „1” pentru a permite execuția oricărei întreruperi. Dacă are valoarea „0” orice sursă de întrerupere este dezactivată.
Bitul 6 (T – Bit Copy Storage) – bit de copiere
Bitul 5 (H – Half Carry Flag) – indicator de transport la jumătate
Bitul 4 (S – Sing bit) – indicator de semn
Bitul 3 (V – Two’s Complement Overflow Flag) – indicator de depășire în cazul operațiilor în complement față de 2
Bitul 2 (N – Negative Flag) – indicator de rezultat negativ
Bitul 1 (Z – Zero Flag) – indicator de zero
Acest bit devine „1” dacă rezultatul unei operații aritmetice sau logice a fost zero.
Bitul 0 ( C – Carry Flag) – indicator de transport
Acest bit devine „1” în cazul unei depășiri la operații pe 8 biți.
Instrucțiuni aritmetice și logice
Cele mai uzuale instrucțiuni aritmetice și logice sunt:
– ADD Rd,Rr
Efectul: se adună conținutul registrului Rd cu cel al registrului Rr și rezultatul se pune în Rd.
– ADC Rd,Rr
Efectul: se adună conținutul registrului Rd cu cel al registrului Rr și cu indicatorul de transport și rezultatul se pune în Rd.
– SUB Rd,Rr
Efectul: se scade conținutul registrului Rr din cel al registrului Rd și rezultatul se pune în Rd.
– AND Rd,Rr
Efectul: se face „ȘI logic” între conținutul registrului Rd și cel al registrului Rr iar rezultatul se pune în Rd.
– INC Rd
Efectul: incrementează conținutul registrului Rd și pune rezultatul în Rd.
– DEC Rd
Efectul: decrementează conținutul registrului Rd și pune rezultatul în Rd.
Instrucțiuni de salt
Cele mai uzuale instrucțiuni de salt sunt:
– JMP k
Efectul: se face salt necondiționat cu „k” poziții față de adresa curentă din memoria program. Instrucțiunea se poate utiliza și în forma „JMP etichetă”.
– RCALL subrutină
Efectul: se apelează o subrutină. Pentru a reveni din aceasta se utilizează instrucțiunea RET.
– RETI
Efectul: se revenire dintr-o subrutină de tratare a unei întreruperi.
– CPSE Rd,Rr
Efectul: se compară valorile regiștrilor Rd și Rr și în caz de egalitate instrucțiunea imediat următoare nu se mai execută.
– CP Rd,Rr
Efectul: compară valorile regiștrilor Rd și Rr fără să modifice conținutul acestora. Ca urmare a ecuției acestei instrucțiuni se vor schimba corespunzător biții registrului de stare.
– SBRC Rd,b
Efectul: dacă bitul b din registrul Rd are valoarea „0” instrucțiunea imediat următoare nu se mai execută.
– SBRS Rd,b
Efectul: dacă bitul b din registrul Rd are valoarea „1” instrucțiunea imediat următoare nu se mai execută.
– SBIC P,b
Efectul: dacă bitul b din registrul de intrare/ieșire P are valoarea „0” instrucțiunea imediat următoare nu se mai execută.
– SBIS P,b
Efectul: dacă bitul b din registrul de intrare/ieșire P are valoarea „1” instrucțiunea imediat următoare nu se mai execută.
– BREQ etichetă
Efectul: dacă indicatorul Z are valoarea „1” se face salt la etichetă.
Instrucțiuni de transfer
Cele mai uzuale instrucțiuni de transfer sunt:
– MOV Rd,Rr
Efectul: copiază conținutul registrului Rr în registrul Rd.
– LDI Rd,k
Efectul: copiază valoarea k în registrul Rd. Această instrucțiune lucrează numai cu registrele
r16 – r31.
– IN Rd,P
Efectul: copiază conținutul registrului de intrare/ieșire P în registrul Rd.
– OUT P,Rr
Efectul: copiază conținutul registrului Rr în registrul de intrare/ieșire P.
Instrucțiuni care lucrează la nivel de bit
Cele mai uzuale instrucțiuni care lucrează la nivel de bit sunt:
– SBI P,b
Efectul: bitul b din registrul de intrare/ieșire P ia valoarea „1”. Instrucțiunea se poate utiliza numai pentru regiștri P situați la adresele de memorie 20h – 3Fh.
– CBI P,b
Efectul: bitul b din registrul de intrare/ieșire P ia valoarea „0”. Instrucțiunea se poate utiliza numai pentru regiștri P situați la adresele de memorie 20h – 3Fh.
– LSL Rd
Efectul: Registrul Rd este deplasat logic la stânga cu o poziție.
– ROR Rd
Efectul: Registrul Rd este rotit la dreapta cu o poziție prin bitul indicator de transport.
Instrucțiuni speciale
Instrucțiunile speciale sunt:
– NOP
– SLEEP
– WDR
Descrierea pinilor
Majoritatea pinilor au funcții alternative legate de funcționarea dispozitivelor periferice. Activarea funcțiilor alternative ale unor pini nu afectează utilizarea altor pini ca port I/O general.
Figura 11. Schema echivalentă a unui pin
Figura 12. Semnificația pinilor
VCC – Tensiunea de alimentare
GND – Masa
Portul A (PA7…PA0)
Portul A este un port bidirecțional de 8 biți programabil. Liniile portului A sunt folosite și ca intrări analogice pentru convertorul A/D. Liniile portului pot fi conectate optional la VCC prin rezistente de agațare (pull-up resistor). Buffer-ele de ieșire ale portului A au caracteristici de amplificare.
Portul B (PB7…PB0)
Portul B este un port I/O de 8 biți bidirecțional prevazut cu rezisțente de agațare interne (optional). Buffer-ele de ieșire ale portului B au caracteristici de amplificare. Portul B indeplinește de asemenea funcții speciale ale microcontrolerului ATmega 16.
Portul C (PC7…PC0)
Portul C este un port I/O de 8 biți bidirecțional prevazut cu rezistențe de agațare interne (optional). Buffer-ele de ieșire ale portului C au caracteristici de amplificare. Daca interfata JTAG (de depanare) este activată, rezistentele pinilor PC5(TDI), PC3(TMS) si PC2(TCK) vor fi activate, chiar dacă are loc o resetare. Port-ul C îndeplinește de asemenea funcții ale interfeței JTAG și alte funcții speciale ale ATmega 16.
Port D (PD7…PD0)
Portul D este un port I/O de 8 biți bidirecțional prevazut cu rezistențe de agațare interne (optional). Buffer-ele de ieșire ale portului D au caracteristici de amplificare. Portul D îndeplinește de asemenea funcții speciale ale ATmega 16.
Reset – inițializarea procesorului.
XTAL 1 și XTAL 2 – intrarea și ieșirea amplificatorului inversor al generatorului de tact.
AVCC – pin de alimentare pentru portul A și pentru convertorul A/D.
AREF – pin de intrare pentru referința analogical a convertorului A/D.
Stiva
Microcontrolerele AVR folosesc o stivă organizată în memoria SRAM de date. Stiva se folosește în principal pentru stocarea temporară a datelor, pentru stocarea variabilelor locale dar și pentru stocarea adreselor de revenire din întreruperi. Accesarea stivei se face prin registrului contor de stiva SP (Stack Pointer) care este actualizat de procesor la fiecare accesare a stivei. Stiva lucrează pe principiul LI-FO (Last Input – First Output) și evoluează prin decrementarea adreselor. La încarcarea unei date în stivă SP este decrementat, iar la citire este incrementat, de aceea SP indică întotdeauna prima locație liberă din vârful stivei. Dimensiunea memoriei SRAM instalate condiționează dimensiunea propriu-zisă a stivei. Utilizatorul setează prin program adresa de început a stivei (care este adresa cea mai mare a zonei de memorie alocată stivei). Procesorul folosește instrucțiunea PUSH pentru transferul de date în stivă, iar instrucțiunea POP este folosită pentru transferul din stivă.
Indicatorul de stivă (SP) este decrementat cu 1 când se introduc date în stivă cu instructiunea PUSH, și decrementat cu 2 când sunt salvate în stivă adresele de revenire la apelarea subrutinelor cu instructiunile CALL sau GOTO sau la acceptarea unei întreruperi. Indicatorul de stivă este incrementat cu 1 când datele sunt citite din stivă cu instructiunea POP, și incrementat cu 2 când sunt citite din stivă adrese la executia unei instructiuni de revenire dintr-o subrutina (RET) sau dintr-o întrerupere (RETI).
Indicatorul de stivă este implementat cu două registre de 8 biți. Aceste registre sunt adresate în spatiul de adrese al dispozitivelor I/O (registrele SPH și SPL). De structura implementării depind numărul de biți folosiți. Spațiul de adrese poate fi mic la unele implamentări ale arhitecturii AVR, deoarece este folosit doar registrul SPL(SP Low). În acest caz registrul SPH (SP High) nu mai este utilizat.
Figura 13. Indicatorul de stivă
Organizarea memoriei
Atmega16 are două spații de memorie principală: memoria de date și memoria de program. În plus Atmega16 are și o memorie nevolatilă EEPROM pentru memorarea datelor. Cele trei tipuri de memorie sunt adresate liniar.
Figura 14. Organizarea spațiului de memorie
Oscilatorul
Oscilatorul care este prezent pe placa de control a sarcinii rezistive programabile este un rezonator ceramic cu fecvența de 16 Mhz.
Datorită factorului de calitate extrem de ridicat și a unei stabilități foarte bune cu temperatura, rezonatorul ceramic se utilizează pe scara largă în realizarea oscilatoarelor cu o înalta stabilitate a frecvenței de oscilație, din punct de vedere electric oscilatorul oferă o impedenața cu proprietați de circuit rezonant.
În figura 2.13 este prezentată schema electrică a rezonatorului ceramic.
Figura 15. Schema electronică a rezonatorului ceramic.
Sursa de alimentare
În momentul actual, sursele de alimentare liniare sunt mai rar utilizate. În locul acestora se folosesc surse in comutație care au randamente mai bune si preț mai scăzut mai ales in cazul puterilor mari. Totuși, sursele liniare prezint o serie de avantaje dintre care pot fi menționate:
fiabilitate sporită;
zgomot redus pe tensiunile furnizate;
perturbatii de înalta frecventa aproape inexistente;
separare excelenta a consumatorului de rețea.
Din aceste motive, sursele liniare sunt recomandate pentru alimentarea circuitelor cu consum redus (de pina la 10..25W) sau a acelora care sunt sensibile la zgomote (amplificatoare audio, receptoare radio, etc.).
În proiect alimentarea sursei de curent continuu se face de la un transformator de rețea care modifică amplitudinea tensiunii sinusoidale (de la 220V la 9V) la valoarea convenabilă aparatului care trebuie alimentat. Această tensiune este apoi redresată printr-o punte de diode; în timpul semialternanței pozitive conduc diodele D2 și D4, pe când în timpul semialternanței negative intră în conducție diodele D1 și D3.
Tensiunea produsă de redresor nu poate fi utilizată direct la alimentare sistemului, chiar dacă are o singură polaritate; deoarece ea suferă variații importante în timp și curentul prin sarcină este zero jumătate din timp. Pentru a rezolva această problemă se folosește un filtru de netezire cu ajutorul unui condensator care va inmagazina sarcina electrică.
Figura 16 Redresare în punte cu filtraj
Transformatorul utilizat în sarcina rezistivă programabilă este format din două înfășurări identice în secundar de 10VA cu 9V fiecare. Pentru obținerea curentului maxim debitat de către transformator înfășurările au fost legate în paralel.
– curentul maxim debitat de transformator
Necesitatea proiectului din punct de vedere al curentului consumat este de 1.551A. Având consumatorii următori:
Consumul ventilatoarelor 160mA
Consumul releelor 1.375A
Consumul afișajului LCD 16mA
– tensiunea obținută dupa redresare și filtrare este suficientă pentru a alimenta ventilatoarele și releele
Pentru obținerea tensiunii de 5V s-a folosit regulatorul de tensiune LM7805 care prezintă următoarele caracteristici: tensiunea de intrare intre 5V-18V, curentul maxim de ieșire de 1.5A, protectie termica si la scurtcircuit. În figura de mai jos este prezentata schema bloc a circuitului integrat LM7805.
De asemenea proiectul este protejat prin două siguranțe fuzibile una în înfășurarea primară a transformatorului de 0.1A și cea dea doua în înfășurarea secundară a acestuia de 0.2A.
Figura 17.Tranformatorul electric al proiectului.
Figura 18. Schema bloc a circuitului integrat LM7805.
Figura 19.Schema electronică a sursei de 5V
2.4 Afișajul LCD 16×2
Ecranul LCD 16×2 este folosit într-o gamă largă de aplicații, dispunând de funcții de afișare a caracterelor speciale, personalizate, animații etc. Acesta este comandat de către microcontrollerul Atmega16.
Figura 20 Display LCD 16×2
Specificații:
Număr de caractere: 16×2;
Culoare caracatere: alb;
Culoare fundal: albastru;
Tensiune de lucru 5 V;
Interfața utilizată pentru comunicația cu microcontrollerul este paralelă pe 4biți.
Interfața paralelă folosește o combinație între activare și ceasul de tact pe pinul ‘E’ care primește sau transmite datele de la afișaj pe pantea descrescătoare. Un bit de control ‘RS’ determină data comandă este scrisă sau transferată către afișaj.
Scopul principal al magistralei pe 4 biți este de a salva din pinii microcontrolerului. Sunt necesari patru pini de date (D4-D7) pentru comunicare, în timp ce restul pot fi lăsați neconectați. Fiecare pachet de date este trimis în două etape a câte 4 biți fiecare. Ca un rezultat al procesului de inițializare afișorul este capabil să lege și să interpreteze correct biți.
Pentru obținerea contrastului se folosește un divisor rezistiv.
2.5.1 Caracteristici
1. Specificații generale
Tabelul 1. Specificații generale (16×2)
2. Diagrama bloc
Figura 21. Diagrama bloc (LCD 16×2)
3. Caracteristici electrice
Tabelul 2. Caracteristici electrice
4. Caracteristici optice
Tabelul 3. Caracteristici optice
5. Ajustarea Contrastului LCD
Figura 22. Ajustarea contrastului pentru modulul LCD 16×2
6. Funcțiile pinilor
Tabelul 4. Funcțiile pinilor
7. Caracteristici de timp pentru scriere
Tabelul 5. Caracteristici de timp pentru scriere
Figura 23. Caracteristici de timp, segment de timp scriere
8. Caracteristici de timp pentru citire
Tabelul 6. Caracteristici de timp pentru citire
Figura 24. Caracteristici de timp, segment de timp citire
Senzori
Creșterea automatizării sistemelor de producție necesită folosirea unor componente care să fie capabile să primească și să transmită informații referitoare la anumite procese de producție. Senzorii îndeplinesc diferite funcții și importanța lor a crescut destul de mult în ultimii ani în procesul de măsurare și de control al proceselor tehnologice. Acesti senzorii furnizează diferite informații unui microcontroler sub forma unor variabile. Prin aceste variabile se înțeleg mărimile fizice ce definesc procesul tehnologic, respectiv: temperatură, presiune, forță, lungime, unghi de rotație, nivel, debit, distanță.
Senzorii pot să transforme variația mărimilor fizice în semnale electrice digitale sau analogice.
Senzorii care furnizează semnale digitale sunt:
de temperatură
de proximitate
de presiune
de nivel
Senzorii analogici furnizează la ieșire semnale electrice analogice – tensiuni sau curenți.
Senzorii care furnizează semnale analogice sunt:
Senzori pentru lungime, distanță și de deplasare
Senzori pentru mișcare lineară sau de rotație
Senzori pentru suprafață, configurație, geometrie
Senzori de forță
Senzori acustici
Senzori de cuplu
Senzori de debit
Senzori de greutate
Senzori de presiune
Senzori de nivel
Senzori de temperatură
Senzori optici
Caracteristicile senzorilor:
Un senzor este un convertor care transformă o mărime fizică ( de exemplu distanță, presiune) într-o altă mărime mai ușor de evaluat și anume o mărime electrică.
Senzorul este un dispozitiv care poate monitoriza un proces prin semnalizarea erorilor, analizarea acestora și transmiterea informațiilor către alte componente.
2.5.1 Senzorul rezistiv de temperatură NTC-100K
Figura 25. Senzorul de temperatură NTC-100K
Termometrele cu rezistență metalică acoperă un domeniu relativ larg de temperaturi, fiind folosite pentru măsurarea temperaturii gazelor și lichidelor, a temperaturii suprafețelor unor solide sau temperature din interiorul unor solide ușoare. Ele sunt stabile și rezistente la condiții de mediu neprietenoase, fiind des folosite în industria chimică sau industria alimentară. Termometrele cu rezistență metalică au o acuratețe bună dar un raspuns lent în timp, fiind destul de fragile și uneori scumpe.
Metalele cele mai des folosite ca traductori de temperatură sunt platina, cuprul și nichelul. Valorile standard pentru rezistența la temperatura de referință Ro (valori nominale) sunt 10, 50, 100, 500 și 1000 ohmi.
În tabelul de mai jos sunt prezentate caracteristicile acestor materiale, cu precizarea că ele se referă la termometrele cu rezistența nominală de 100 Ω.
Tabelul 7. Caracteristicile materialelor (Platină, Nichel, Cupru)
Figura 26. Caracteristica putere consumată – temperatură ambiantă
Temperatura care poate fi masurată de acest senzor este în domeniul -55°C ~ +125°C, iar puterea este de 0,5W. [12]
Valoare citită de la senzor
Temperatură afișată
Figura 27. Caracteristica valoare citită – valoare afișată (NTC-100K)
Domeniul de masurare fixat pentru acest proiect este cuprins între 0 și 105 grade Celsius, se alimentează cu o tensiune 3-5V, iar pe ieșirea are o tensiune analogică care variază între 0 și tensiunea de alimentare.
Sezorul de temperatură este utilizat cu scopul de a cunoaste temperatura din interiourul proiectului pentru a putea porni ventilatoarele și de asemenea de a proteja sarcina rezistivă programabilă cu ajutorul softwarelui.
Figura 28. Schema electronică pentru protecția termice
Protecția software este concepută ca la o temperatură de 50˚C să pornească ventilatoarele lăsând funcționalitatea sarcinii rezistive programabile neschimbată. Dacă temperatura va crește peste 90˚C, pe afișajul LCD va aparea mesajul ” OVERHEAT” care va notifica utilizatorul iar sistemul se va bloca pentru siguranța acestuia până va scadea temperature la 85˚C. Temperatura de repornire a sistemului a fost aleasă 85˚C în loc de 90˚C cu scopul de a crea un histereziz și de a nu avea fluctuații continue de pornit-oprit.
Figura 29. Mesaj de supraîncălzire
Figura 30. Poziționarea senzorului de temperatură pe radiator
2.6 ULN2803
Componenta electronică ULN2803 este formată din opt perechi NPN Darlington. Această componentă este ideală pentru interfațarea între nivelele joase logice digitale și tensiuni/curenți mari necesari pentru lămpi, relee sau pentru sarcini similare pe o scară largă în calculatoare, industrie și aplicații de consum.
Fiecare pereche Darlington este formată din doi tranzistori bipolari astfel încât curentul amplificat de primul tranzistor să fie amplificat de al doilea pentru a putea obține un curent de bază mai mare. Curentul debitat de fiecare pereche Darlington este de 500mA.
Figura 31. Schema electronică a unei perechi Darlington
Figura 32. Diagrama logică a componentei ULN2803
În cazul în care este aplicată la intrare o tensiune de 0V tranzistorul 1 și tranzistorul 2 nu vor conduce, deoarece curentul nu există curentu de bază pentru aceștia.
În momentul aplicării unei tensiuni de 5V curentul de intrare va crește, iar ambii tranzistori vor conduce. Curentul de intrare al tranzistorului 2 este o combinație a curentului de intrare cu curentul plus curentul din emitorul tranzistorului 1, astfel încât tranzistorul 2 va conduce mai mult decât tranzistorul 1 rezultatul fiind un curent de ieșire mult mai mare, necesar acționării unui releu, un motor etc.
2.7 Releul
Figura 33. Releul
Releul este o un comutator electric care folosește un electromagnet pentru a putea mișca poziția din pornit în oprit. Releul este utilizat în diverse aplicații în special unde este necesar să controlăm o putere sau o tensiune mare cu o putere mică. De asemenea acesta este preferat datorită faptului că îndeplinește un rol important ca izolator galvanic.
Bobina releului nu este numai un electromagnet de asemenea este și o bobină. Când curentul este aplicat pe bobină acesta crește și energia este înmagazinată în câmpul magnetic. În momentul opririi curentului necesar alimentării bobinei toată energia stocată trebuie să se consume.
Tensiunea de pe bobină va crește rapid încercând să mențină curentul pe aceeași direcție. Această tensiune poate ajunge la sute chiar mii de volți distrugând componentele electronice.
Pentru a evita probleme provocate de câmpul magnetic se adaugă o diodă în paralel cu bobina, astfel încât curentul să își mențină calea pe bobină până este consumat. Această diodă mai este denumită ca și diodă de ‘flyback’. De asemenea diode va limita tensiunea de pe bobină să ajungă la componentele electronice la aproximativ 0.7V.
.
Figura 34. Schema electronică a acționării releului
Microcontrollerul va genera la ieșire o tensiune de 5V care se va duce la intrarea în ULN2803. Acesta va avea la ieșire 0V oferind o conexiune între masa și un terminal al bobinei releului. Bobina releului având permanentă conexiune la 12V.
Aceeași configurație electronică este utilizată și șa ventiloare, datorită faptului că acestea sunt la rândul lor niște motoare care au ca alimentare un electromagnet.
Principiul de funcționare
Pentru a putea alege rezistența dorită în pași de 0.1Ω am ales 15 valori de rezistențe astfel încăt să pot crea toate valorile până la ~870 Ω. Acestea sunt : 0.1Ω, 0.2Ω, 0.4Ω, 0.8Ω, 1Ω, 2Ω, 4Ω, 8Ω, 10Ω, 20Ω, 40Ω, 80Ω, 100Ω, 200Ω, 400Ω
Toate rezistențele sunt înseriate. Principiul care stă la baza creerii valorii dorite este înserierea rezistențelor corespunzatoare obținerii valorii dorite iar rezistențele care nu sunt necesare să fie ștrapate prin contactorul releului corespunzător.
De exemplu pentru creearea valorii:
359.7Ω = 200Ω + 100Ω + 40Ω + 10Ω + 8Ω + 1Ω + 0.4Ω + 0.2Ω + 0.1Ω
Figura 35. Conexiunea rezistențelor pentru sarcina rezistivă programabilă
Contactorul unui releu are o rezistentă de 2mΩ. Dacă se dorește o valoare mare, rezistența addițională obținută din contactoarele releelor este nesemnificativă. În schimb pentru a nu influența valorile mici ale rezistențelor a fost adăugat încă un releu pentru a ștrapa releele aferente rezistențelor mari.
Pentru a putea alege rezistențele necesare din puct de vedere al puterii sa creat tabelul de mai jos, ținând cont de o putere maximă de 400W și o tensiune nominală de 14V.
Tabelul 8. Puterea de disipare a rezistențelor
Datorită faptului că pe rezistențe este aplicată o tensiune externă, iar acesta poate fi setat peste limitările care au fost luate în calcul în momentul proiectării sarcinei rezistive programabilă, protecția acesteia este obligatorie.
Sarcina rezistivă programabilă are la intrare un cititor de tensiune format din două divizoare rezistive. Câte una pentru fiecare bornă externă, deoarece utilizatorul nu trebuie să fie restricționat în vederea polarității aplicate sarcinei rezistive.
Figura 36. Schema electrică a cititorului de tensiune
În funcție de tensiunea aplicată microcontrolerul va citi la intrare o tensiune maximă de 5V. Rezistențele R7 și R8 sunt folosite pentru a limita curentul la microcontroler.
Tensiunea care va fi aplicată trebuie să fie în plaja 0-20V.
Figura 37. Divizorul rezistiv
Pentru ca tensiunea aplicată sarcinei să poată fi interpretată corect, în software tensiunea citită de către microcontroler va fi înmulțită cu 4 deoarece ea este scalată de către divizorul rezistiv.
Exemplu1:
Exemplu2:
Pentru a controla releele, a citii tensiunea și temperatura, a alege rezistențele și a afișa pe afișajul LCD este folosit microcontrolerul ATMEGA 16, deoarece are numărul de pini și memoria necesară.
Figura 38. Sarcina rezistivă programabilă în format 3D
Sistemul dispune de trei butoane fără reținere cu funcțiile următoare:
1-Activare/Dezactivare rezistența selectată
2-Incrementare rezistență
3-Decrementare rezistență
În momentul în care vom ține apăsat pe butonul de incrementat rezistență, aceasta va crește îmcet în pași de 0.1Ω pentru cinci secunde. După cele cinci secunde viteza de incrementare a rezistenței va crește. Același procedeu este folosit și pentru decrementare.
În cazul în care se vor ține apăsate ambele butoane de incrementare și decrementare rezistența va rămâne la ultima sa valoare până în momentul apăsării ambelor butoane.
În momentul pornirii sarcinei rezistive programabile va fi afișat mesajul : ‘Programable Load’, pentru câteva secunde, după care va apărea și rămăne în meniul principal. După cum se poate vedea în imaginea de mai jos avem în colțul din dreapta pe prima linie mesajul ‘OFF’. Ceea ce înseamnă că sarcina așteaptă din partea utilizatorului selectarea și activarea rezistenței.
Figura 39. Meniul principal al sarcinei rezistive programabile
În momentul activării rezistenței, sarcina rezistivă programabilă va citi tensiunea aplicată și împreună cu valoarea rezistenței selectate va calcula curentul și puterea disipată. Sarcina rezistență programbilă are protecție software. În cazul în care curentul trece de 30A sau puterea disipată trece de 300W, sarcina nu va activa rezistența și va apărea mesajul ‘OVER’ în loc de ‘OFF’ și se va întoarce în meniul principal în care se va selecta rezistența.
Rezistența se poate incrementa sau decrementa doar dacă nu este actvată.
Figura 40. Meniul de limitare a sarcinei rezistive programabile
Conceperea programului pentru microcontroller
Codul pentru microcontroller este cod C și a fost scris în softul AVR Studio și programat pe microcontrolerul ATMEGA 16 cu programatorul USBASP și a softwerului eXtreme Burner AVR.
Figura 41. Programatorul USBASP
Programatorul USBASP are ca elemente de bază un microcontroller Atmega8.
Figura 42. Schema electronică a programatorul USBASP
Codul a fost scris și compilat în AVR Studio. În momentul compilării programul generează printre alte fișiere și codul în formatul HEX.
Utilizare AVR STUDIO și WINAVR
Pentru a se lucra în AVR STUDIO trebuie parcurși următorii pași:
Se creează un proiect nou. La prima lansare a programului după instalare avem:
Figura 43. Fereastra de dialog Project
Stabilim numele proiectului, locul unde va fi creat și numele fișierului initial.
Proiectul va fi de tip AVR GCC.
Se vor bifa căsuțele „Create initial file” și „Create folder”(adică în locația indicatș/aleasș la Location se va crea un folder în care vor fi toate fișierele proiectului, de exemplu C:/lucru).
Numele proiectului va fi ProgramableLoad, care va fi dat în mod automat și lui „Initial file” (în cazul acesta fișierul sursă inițial ProgramableLoad.c).
Figura 44. Fereastra de dialog Create new project
Se apăsa Next pentru a trece la următorul meniu.
Se va alege în fereastra Debug Platform: AVR simulator și de asemenea microcontrolerul folosit, Atmega16 în cazul de față.
În final se apasă Finish.
Figura 45. Fereastra de dialog debug platform and device
Se deschide Project-> Configurations Options.
Figura 46. Fereastra de dialog configurations options
Stabilirea opțiuni compilare, stabilire nivelului de optimizare (Optimization)..
Figura 47. Fereastra de dialog configurations options
Scriere cod în fereastra de lucru.
Figura 48. Fereastra de lucru
Compilarea
Figura 49. Fereastra de dialog build
Din acest moment fișierul hex (în cazul nostru ProgramableLoad.hex) care se găsește în subfolderul …/default poate fi utilizat pentru programarea microcontrolerului cu ajutorul eXtreme Burner AVR.
Utilizare eXtreme Burner AVR
Selectarea microcontrolerului utilizat Atmega16
Figura 50. Fereastra de dialog microcontroler
Selectarea tipul de programare utilizat. În proiect a fost folosit protocolul ISP.
Figura 51. Fereastra de dialog pentru tipul programării
Deschiderea fișierului de tip HEX generat de către AVR Studio. În cazul în care se folosește și memoria eeprom a microcontrolerului, trebuie încărcat și fișierul cu extensia EEP.
Figura 52. Fereastra de dialog pentru deschiderea fișierul pentru microcontroler
Configurația biților ceasului de tact. Se va selecta “Clock Configuration” din partea de jos a meniului Fuse Bits/Settings. În fereastra ajutătoare vom selecta tipul generatorului de tact în cazul actual ca fiind extern, frecvența acestuia, acțiunile de pornire și de asemenea opțiunile oscilatorului.
Figura 53. Fereastra de configurația biților ceasului de tact
Scrierea microcontrolerului.
Figura 54. Fereastra de scriere a microcontrolerului
Dacă se utilizează memoria eeprom trebuie scris în microcontroller de asemenea și fișierul încărcat în programul eXtreme Burner AVR. De asemenea trebuie scrise și setările biților împreună cu configurația ceasului de tact.
4. Proiectarea și realizarea sistemului
Proiectarea schemei electronice și a cablajului imprimat s-au realizat in programul Target 3001. S-a conceput un cablaj simplu cablat, iar amplasarea pieselor sa realizat decat pe fața plăcuței de textolit.
Plasarea componentelor sa făcut strategic datorita nevoii de accesibilitate a anumitor componente, dar si datorită traseelor dintre ele. S-a folosit două tipuri de ansamblstr și anume „top” si „bottom”, s-a apelat la plan de masă pentru atenuare fluctuațiilor parazite.
După cum a fost menționat la începutul proiectului, sarcina rezistivă programabilă este format din patru plăcuțe electronice:
Placa de alimentare
Placa de control
Placa de comandă a rezistențelor de valoare mică
Placa de comandă a rezistențelor de valoare mare
Figura 55. Cablajul (placa) de alimentare
Figura 56. Cablajul (placa) de control
Figura 57. Cablajul (placa) de comandă a rezistențelor de valoare mică
Figura 58. Cablajul (placa) de comandă a rezistențelor de valoare mare
După ce s-au realizat cablajele in EAGLE, acestea au fost imprimate pe plăcuțele de textolit, după care au fost introduse la corodat în clorură ferică și stanate cu fludor.
După corodare au rămas doar traseele dorite, urmrând realizarea de găuri pentru terminale si pini, urmat de plasarea componentelor. După terminarea plasării pieselor au rezultat plăcile.Pentru lipirea componentelor sa folosit stația de lipit, fludor si sacâz și sa mai folosit un multimetru pentru măsurarea componentelor si continuitatea traseelor.
Figura 59. Placa de alimentare
Figura 60. Placa de control
Figura 61. Placa de comandă a rezistențelor de valoare mică
Figura 62. Placa de comandă a rezistențelor de valoare mare
De asemenea în proiect sa utilizat două radiatore puse în paralel, iar pe fiecare parte au fost montate rezistențele de putere și un ventilator în capăt. Tot ansamblu a fost montat într-o carcasă metalică.
Figura 63. Interiorul sarcinei rezistive programabile
Figura 64. Sarcina rezistivă programabilă ansamblată
Concluzii
Datorită acestui sistem am avut posibilitatea să studiez microcontrollerul Atmega16 și să îmi imbunătățesc abilitățile softwer dar și mecanice datorită modelării carcasei și a radiatoarelor.
Cea mai mare provocare încă de la început a fost asigurarea unei răcire optime rezistențelor.
Avantajele proiectului:
Poate fi utilizat într-o varietate mare de aplicații,
Costul proiectului este cu mult mai mic decât un proiect asemănător cumpărat.
În ceea ce privește posibilitatea de dezvoltare a proiectului, pot spune că montarea sau schimbarea rezistențelor pot îmbunătații proiectul din punct de vedere al curenților suportați.
Există multe îmbunătățiri și funcții care pot fi adăugate in cadrul acestui proiect, dar din cauza lipsei de timp, nu le-am putut pune în aplicare, dar poate, în timp, voi aduce aceste îmbunătățiri la proiectul meu. Una dintre ele este de a face sistemul capabil să comunice cu calculatorul pentru o eficiență sporită.
Bibliografie
http://tet.pub.ro/files/studenti/materiale/an_III/miccurs/CURS_ATMEGA_16_III_TET.doc
http://vega.unitbv.ro/~ogrutan/Microcontrollere2011/6-220V.pdf
mecatronicastiintaviitorului.wikispaces.com/file/view/Curs-Senzori.doc
https://en.wikipedia.org/wiki/Load_bank
https://en.wikipedia.org/wiki/Relay
http://www.ti.com/lit/ds/symlink/uln2803a.pdf
https://en.wikipedia.org/wiki/Flyback_diode
https://www.openhacks.com/uploadsproductos/eone-1602a1.pdf
https://www.sparkfun.com/datasheets/Components/LM7805.pdf
ANEXE
Codul proiectului:
#include <avr/io.h>
#include <avr/interrupt.h> // biblioteca necesara pentru utilizarea intreruperilor
#include <util/delay.h> // o biblioteca cu functiile de intarziere software-in avrlib
#include "lcd.h" // o biblioteca utilizator cu functiile aferente afisorului LCD
#include <stdio.h>
#include <avr/eeprom.h>
#define F_CPU 1000000UL
// constante care identifica sursa de referinta
#define ADC_REF_AREF 0x00 // borna AREF
#define ADC_REF_AVCC 0x40 // borna AVCC
#define ADC_REF_INT 0xC0 // ref. interna
unsigned char ADC_REF_TYPE;
volatile uint16_t count=0; // variabile globale
volatile uint16_t valcitita;
volatile uint16_t A=0;
volatile uint16_t V=0;
void wait ()
{
uint8_t i;
for(i=0;i<2;i++)
{
_delay_loop_2(0); // 4 cicluri CPU
}
}
/////////////////////// variabile locale //////////////////////////
volatile uint16_t curent=0;
unsigned int tensiune=0;
unsigned int tensiune1=0;
unsigned int tensiune2=0;
unsigned int temperatura;
unsigned int nr=0;
unsigned int aux;
unsigned int putere=0;
unsigned countbuton=0;
unsigned f=0;
unsigned z=0;
unsigned int EEMEM myVar =0 ;
////////////// programul principal///////////////////////////////
int main (void)
{
////////// definire pini de intrare/////////////////////////////////
DDRB &= ~(1 << DDB0); // pentru SW1 : Enable/ Disable
DDRA &= ~(1 << DDA7); // pentru SW2
DDRA &= ~(1 << DDA6); // pentru SW3
//////////// definire pini de iesire//////////////////////////////
DDRA |= (1 << DDA5) ; // activare releu intrerupere
DDRA |= (1 << DDA3) ; // activare releu general rezistente
DDRA |= (1 << DDA2) ; // activare fan-dc
// PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7 iesiri
DDRD |= ((1 << DDD0) | (1 << DDD1) | (1 << DDD2) | (1 << DDD3) | (1 << DDD4)| (1 << DDD5)| (1 << DDD6)| (1 << DDD7));
// PC0, PC1, PC2, PC3, PC4, PC5, PC6, PC7 iesiri
DDRC |= ((1 << DDC0) | (1 << DDC1) | (1 << DDC2) | (1 << DDC3) | (1 << DDC4)| (1 << DDC5)| (1 << DDC6)| (1 << DDC7));
///////////////// scriem un mesaj de inceput //////////////////////
// initializare afisor LCD, fara cursor: LS_NONE
// avem linia y=0,1 si coloana x=0..15 (16 caractere pe linie)
LCDInit(LS_NONE);
// scrie sir la adresa curenta, initial 0,0
LCDGotoXY(0,0);
LCDWriteString("Programable Load");
wait(); wait(); wait(); wait();wait();wait();// o intarz. inainte de a incepe masurarea/ afisarea propriu-zisa
LCDClear(); // sterge afisorul
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////read eeprom /////////////////////////////////
aux=eeprom_read_word(&myVar);
////////////////////////////////////////////////////////////////////////////////
while(1) // o bucla fara sfarsit
{
void adc_init(unsigned char ADC_REF)
{
// activare ADC si factor de divizare (prescaler) = 128
ADCSRA = 0x87;
ADC_REF_TYPE = ADC_REF;
}
// citeste de pe canalul specificat ca parametru returneaza un intreg fara semn 0…65535
unsigned int read_adc(unsigned char adc_channel)
{
ADMUX = ADC_REF_TYPE | adc_channel;
ADCSRA |= 0x40;
while (ADCSRA & 0x40);
return ADC; // 16 biti aliniati la dreapta
}
adc_init(ADC_REF_AVCC); // referinta este 5V
//////////////////////////// citire tensiune /////////////////////////
/* 10 biti, Nmax=1023,1024 de valori distincte VREF=5V;
1 UCAN = 5V/ 1024 = 0.00488V = 4.88mV
Vadc [mV] = ADC * 4.88mV = ADC * 4.9mV (rotunjire prin adaugare)
V = 10 * Vadc [mV] = ADC * 49mV
V/1000 [V], adica ADC*49/100 */
tensiune1=(int)((read_adc(4)*49/100*4));
_delay_us (50);
tensiune2=(int)((read_adc(1)*49/100*4));
_delay_us (50);
if(tensiune1>tensiune2){
tensiune=tensiune1*2;
}
if(tensiune2>tensiune1){
tensiune=tensiune2*2;
}
if(tensiune1==tensiune2){
tensiune=tensiune1*2;
}
if(tensiune<10 && (temperatura<39200)){
LCDGotoXY(2,1);
LCDData(' ');
LCDData('0');
LCDData('.');
LCDData('0');
LCDData('0');
}
//////////////////////////// citire temperatura ///////////////////////
temperatura=read_adc(0)*49;
_delay_us (50);
//////////////////////////// Porneste FAN daca temperatura>60grade////////////////
if(temperatura>27000){
PORTA |= (1<<PA2);
}
if(temperatura<27001){
PORTA &=~(1<<PA2);
}
/////////////////////////////// scriem partea fixa a mesajelor ///////////////////
if(temperatura<39200){
LCDWriteStringXY(0,0,">>R=");
LCDWriteStringXY(9,0," <<");
LCDWriteStringXY(0,1,"A=");
LCDWriteStringXY(8,1,"Pd=");
LCDWriteStringXY(7,1," ");
}
////////////////MESAJ TEMPERATURA PESTE 100GRADE ///////////////////
if(temperatura>39200){
PORTA &=~(1<<PA5);
LCDGotoXY(0,0);
LCDWriteString(" OVERHEAT ");
LCDGotoXY(0,1);
LCDWriteString(" ");
wait();wait();wait();wait(); wait(); wait(); wait();wait();wait(); wait();wait(); wait(); wait(); wait();wait();wait(); wait(); wait();wait();wait(); wait(); wait();wait(); wait(); wait(); wait();wait();wait(); wait();wait();wait();wait(); wait(); wait(); wait();wait();wait();
}
///////////////////////////mesaje de inceput OFF rezistenta, curent, putere = 0 //////////////////
if(aux<1 && (temperatura<39200)){
LCDGotoXY(4,0);
LCDData(' ');
LCDData(' ');
LCDData('0');
LCDData('.');
LCDData('0');
LCDGotoXY(2,1);
LCDData(' ');
LCDData('0');
LCDData('.');
LCDData('0');
LCDData('0');
LCDGotoXY(11,1);
LCDData(' ');
LCDData('0');
LCDData('.');
LCDData('0');
LCDData('0');
LCDGotoXY(12,0);
LCDData(' ');
LCDData('O');
LCDData('F');
LCDData('F');
}
///////////////////////// Mesaj reintoarcere din OVERHEAT /////////////////////////////
for(f=0;f<1;f++){
if (temperatura<39200){
if(aux<1){
LCDGotoXY(4,0);
LCDData(' ');
LCDData(' ');
LCDData('0');
LCDData('.');
LCDData('0');
LCDGotoXY(2,1);
LCDData(' ');
LCDData('0');
LCDData('.');
LCDData('0');
LCDData('0');
LCDGotoXY(11,1);
LCDData(' ');
LCDData('0');
LCDData('.');
LCDData('0');
LCDData('0');
LCDGotoXY(12,0);
LCDData(' ');
LCDData('O');
LCDData('F');
LCDData('F');
}
//////////////////////////////
if (nr==0){
curent=0;
tensiune=0;
putere=0;
LCDGotoXY(2,1);
LCDData(' ');
LCDData('0');
LCDData('.');
LCDData('0');
LCDData('0');
}
//////////REZISTENTA ///////////////////////
valcitita = valcitita+1;
valcitita=aux;
if(aux>0 && (temperatura<39200)){
if (aux<10)
{
LCDGotoXY(4,0);
LCDData(' ');
LCDData(' ');
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
}
if(aux>9 && aux<100)
{
LCDGotoXY(4,0);
LCDData(' ');
LCDData(' ');
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
}
if (aux>99 && aux<1000)
{
LCDGotoXY(4,0);
LCDData(' ');
LCDData((aux%1000)/100+48);
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
}
if (aux>999){
LCDGotoXY(4,0);
LCDData((aux%10000)/1000+48);
LCDData((aux%1000)/100+48);
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
}
/////// calculator curent/////////////////
if(tensiune>9 ){
if(nr==0){
curent=0;
LCDGotoXY(2,1);
LCDData(' ');
LCDData(' ');
LCDData('0');
LCDData('.');
LCDData('0');
}
if(nr==1){
curent= ((tensiune*10)/aux);
if(curent>9999){
LCDGotoXY(2,1);
LCDData((curent%100000)/10000+48);
LCDData((curent%10000)/1000+48);
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
}
if(curent>999 && curent<10000){
LCDGotoXY(2,1);
LCDData((curent%10000)/1000+48);
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
LCDData((curent%10)/1+48);
}
if(curent>99 && curent<1000){
LCDGotoXY(2,1);
LCDData(' ');
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
LCDData((curent%10)/1+48);
}
if(curent>9 && curent<100){
LCDGotoXY(2,1);
LCDData(' ');
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
LCDData((curent%10)/1+48);
}
}
}
///////////// putere disipata//////////////////////////
if (curent>9999 ){
putere= ((tensiune/100)*(curent/10));
if(putere>9999){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%100000)/10000+48);
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData((putere%100)/10+48);
}
}
if (curent>999 && curent<10000){
putere= ((tensiune/100)*(curent/10));
if(putere>9999){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%100000)/10000+48);
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData((putere%100)/10+48);
}
if(putere<10000){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData((putere%100)/10+48);
LCDData(' ');
}
}
if (curent<1000){
putere= (tensiune/100)*curent;
if(putere>9999 ){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%100000)/10000+48);
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData(' ');
}
if(putere>999 && putere<10000){
LCDGotoXY(11,1);
LCDData(' ');
LCDData(' ');
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData(' ');
}
if(putere<1000){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%1000)/100+48);
LCDData('.');
LCDData((putere%100)/10+48);
LCDData((putere%10)/1+48);
}
}
}
}
}
/////////////// pentru lcd push button ////////////
///////////////////// up ////////////////////////
countbuton =0;
valcitita=0;
if (!(PINA & (1<<PA6)) ) {
while (!(PINA & (1<<PA6)) && aux<4000 && (temperatura<39200) && nr==0 && (PINA & (1<<PA7)))
{
valcitita = valcitita+1;
aux = aux+1;
valcitita=aux;
if (aux<9)
{
LCDGotoXY(4,0);
LCDData(' ');
LCDData(' ');
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
_delay_ms (100);
}
if(aux>9 && aux<100)
{
LCDGotoXY(4,0);
LCDData(' ');
LCDData(' ');
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
_delay_ms (100);
}
if (aux>99 && aux<1000)
{
LCDGotoXY(4,0);
LCDData(' ');
LCDData((aux%1000)/100+48);
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
_delay_ms (100);
}
if (aux>999){
LCDGotoXY(4,0);
LCDData((aux%10000)/1000+48);
LCDData((aux%1000)/100+48);
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
_delay_ms (100);
}
/////// calculator curent up /////////////////
if(tensiune>9 ){
if(nr==0){
curent=0;
LCDGotoXY(2,1);
LCDData(' ');
LCDData(' ');
LCDData('0');
LCDData('.');
LCDData('0');
}
if(nr==1){
curent= ((tensiune*10)/aux);
if(curent>9999){
LCDGotoXY(2,1);
LCDData((curent%100000)/10000+48);
LCDData((curent%10000)/1000+48);
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
}
if(curent>999 && curent<10000){
LCDGotoXY(2,1);
LCDData((curent%10000)/1000+48);
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
LCDData((curent%10)/1+48);
}
if(curent>99 && curent<1000){
LCDGotoXY(2,1);
LCDData(' ');
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
LCDData((curent%10)/1+48);
}
if(curent>9 && curent<100){
LCDGotoXY(2,1);
LCDData(' ');
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
LCDData((curent%10)/1+48);
}
}
}
///////////// putere disipata up //////////////////////////
if (curent>9999 ){
putere= ((tensiune/100)*(curent/10));
if(putere>9999){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%100000)/10000+48);
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData((putere%100)/10+48);
}
}
if (curent>999 && curent<10000){
putere= ((tensiune/100)*(curent/10));
if(putere>9999){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%100000)/10000+48);
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData((putere%100)/10+48);
}
if(putere<10000){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData((putere%100)/10+48);
LCDData(' ');
}
}
if (curent<1000){
putere= (tensiune/100)*curent;
if(putere>9999 ){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%100000)/10000+48);
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData(' ');
}
if(putere>999 && putere<10000){
LCDGotoXY(11,1);
LCDData(' ');
LCDData(' ');
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData(' ');
}
if(putere<1000){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%1000)/100+48);
LCDData('.');
LCDData((putere%100)/10+48);
LCDData((putere%10)/1+48);
}
}
countbuton++;
/////////////////////// up cu viteza ////////////////////////////////////
if (countbuton>3){
countbuton=0;
while (!(PINA & (1<<PA6)) && (temperatura<39200) && aux<4000 && nr==0 && (PINA & (1<<PA7)))
{
valcitita = valcitita+1;
aux = aux+1;
valcitita=aux;
if (aux<9)
{
LCDGotoXY(4,0);
LCDData(' ');
LCDData(' ');
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
_delay_us (50);
}
if(aux>9 && aux<100)
{
LCDGotoXY(4,0);
LCDData(' ');
LCDData(' ');
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
_delay_us (50);
}
if (aux>99 && aux<1000)
{
LCDGotoXY(4,0);
LCDData(' ');
LCDData((aux%1000)/100+48);
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
_delay_us (50);
}
if (aux>999){
LCDGotoXY(4,0);
LCDData((aux%10000)/1000+48);
LCDData((aux%1000)/100+48);
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
_delay_us (50);
}
/////// calculator curent up cu viteza /////////////////
if(tensiune>9 ){
if(nr==0){
curent=0;
LCDGotoXY(2,1);
LCDData(' ');
LCDData(' ');
LCDData('0');
LCDData('.');
LCDData('0');
}
if(nr==1){
curent= ((tensiune*10)/aux);
if(curent>9999){
LCDGotoXY(2,1);
LCDData((curent%100000)/10000+48);
LCDData((curent%10000)/1000+48);
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
}
if(curent>999 && curent<10000){
LCDGotoXY(2,1);
LCDData((curent%10000)/1000+48);
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
LCDData((curent%10)/1+48);
}
if(curent>99 && curent<1000){
LCDGotoXY(2,1);
LCDData(' ');
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
LCDData((curent%10)/1+48);
}
if(curent>9 && curent<100){
LCDGotoXY(2,1);
LCDData(' ');
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
LCDData((curent%10)/1+48);
}
}
}
///////////// putere disipata up cu viteza //////////////////////////
if (curent>9999 ){
putere= ((tensiune/100)*(curent/10));
if(putere>9999){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%100000)/10000+48);
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData((putere%100)/10+48);
}
}
if (curent>999 && curent<10000){
putere= ((tensiune/100)*(curent/10));
if(putere>9999){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%100000)/10000+48);
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData((putere%100)/10+48);
}
if(putere<10000){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData((putere%100)/10+48);
LCDData(' ');
}
}
if (curent<1000){
putere= (tensiune/100)*curent;
if(putere>9999 ){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%100000)/10000+48);
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData(' ');
}
if(putere>999 && putere<10000){
LCDGotoXY(11,1);
LCDData(' ');
LCDData(' ');
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData(' ');
}
if(putere<1000){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%1000)/100+48);
LCDData('.');
LCDData((putere%100)/10+48);
LCDData((putere%10)/1+48);
}
}
}
}
}
}
////////////////// down ////////////////////////
if (!(PINA & (1<<PA7)))
{
while (!(PINA & (1<<PA7)) && (temperatura<39200) && aux>0 && nr==0 && (PINA & (1<<PA6)))
{
valcitita = valcitita-1;
aux = aux-1;
valcitita=aux;
if (aux<10)
{
LCDGotoXY(4,0);
LCDData(' ');
LCDData(' ');
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
_delay_ms (100);
}
if(aux>9 && aux<100)
{
LCDGotoXY(4,0);
LCDData(' ');
LCDData(' ');
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
_delay_ms (100);
}
if (aux>99 && aux<1000)
{
LCDGotoXY(4,0);
LCDData(' ');
LCDData((aux%1000)/100+48);
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
_delay_ms (100);
}
if (aux>999){
LCDGotoXY(4,0);
LCDData((aux%10000)/1000+48);
LCDData((aux%1000)/100+48);
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
_delay_ms (100);
}
/////// calculator curent down /////////////////
if(tensiune>9 ){
if(nr==0){
curent=0;
LCDGotoXY(2,1);
LCDData(' ');
LCDData(' ');
LCDData('0');
LCDData('.');
LCDData('0');
}
if(nr==1){
curent= ((tensiune*10)/aux);
if(curent>9999){
LCDGotoXY(2,1);
LCDData((curent%100000)/10000+48);
LCDData((curent%10000)/1000+48);
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
}
if(curent>999 && curent<10000){
LCDGotoXY(2,1);
LCDData((curent%10000)/1000+48);
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
LCDData((curent%10)/1+48);
}
if(curent>99 && curent<1000){
LCDGotoXY(2,1);
LCDData(' ');
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
LCDData((curent%10)/1+48);
}
if(curent>9 && curent<100){
LCDGotoXY(2,1);
LCDData(' ');
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
LCDData((curent%10)/1+48);
}
if(curent<10){
LCDGotoXY(2,1);
LCDData(' ');
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
LCDData((curent%10)/1+48);
}
}
}
///////////// putere disipata down //////////////////////////
if (curent>9999 ){
putere= ((tensiune/100)*(curent/10));
if(putere>9999){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%100000)/10000+48);
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData((putere%100)/10+48);
}
}
if (curent>999 && curent<10000){
putere= ((tensiune/100)*(curent/10));
if(putere>9999){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%100000)/10000+48);
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData((putere%100)/10+48);
}
if(putere<10000){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData((putere%100)/10+48);
LCDData(' ');
}
}
if (curent<1000){
putere= (tensiune/100)*curent;
if(putere>9999 ){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%100000)/10000+48);
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData(' ');
}
if(putere>999 && putere<10000){
LCDGotoXY(11,1);
LCDData(' ');
LCDData(' ');
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData(' ');
}
if(putere<1000){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%1000)/100+48);
LCDData('.');
LCDData((putere%100)/10+48);
LCDData((putere%10)/1+48);
}
}
//////////////// down cu viteza////////////////////////////////
countbuton++;
if (countbuton>3){
countbuton=0;
while (!(PINA & (1<<PA7)) && (temperatura<39200) && aux>0 && nr==0 && (PINA & (1<<PA6)))
{
valcitita = valcitita-1;
aux = aux-1;
valcitita=aux;
if (aux<9)
{
LCDGotoXY(4,0);
LCDData(' ');
LCDData(' ');
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
_delay_us (50);
}
if(aux>9 && aux<100)
{
LCDGotoXY(4,0);
LCDData(' ');
LCDData(' ');
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
_delay_us (50);
}
if (aux>99 && aux<1000)
{
LCDGotoXY(4,0);
LCDData(' ');
LCDData((aux%1000)/100+48);
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
_delay_us (50);
}
if (aux>999){
LCDGotoXY(4,0);
LCDData((aux%10000)/1000+48);
LCDData((aux%1000)/100+48);
LCDData((aux%100)/10+48);
LCDData('.');
LCDData((aux%10)/1+48);
_delay_us (50);
}
/////// calculator curent down cu viteza /////////////////
if(tensiune>9 ){
if(nr==0){
curent=0;
LCDGotoXY(2,1);
LCDData(' ');
LCDData(' ');
LCDData('0');
LCDData('.');
LCDData('0');
}
if(nr==1){
curent= ((tensiune*10)/aux);
if(curent>999){
LCDGotoXY(2,1);
LCDData((curent%100000)/10000+48);
LCDData((curent%10000)/1000+48);
LCDData('.');
LCDData((curent%1000)/100+48);
LCDData((curent%100)/10+48);
}
if(curent>999 && curent<10000){
LCDGotoXY(2,1);
LCDData((curent%10000)/1000+48);
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
LCDData((curent%10)/1+48);
}
if(curent>99 && curent<1000){
LCDGotoXY(2,1);
LCDData(' ');
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
LCDData((curent%10)/1+48);
}
if(curent>9 && curent<100){
LCDGotoXY(2,1);
LCDData(' ');
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
LCDData((curent%10)/1+48);
}
if(curent<10){
LCDGotoXY(2,1);
LCDData(' ');
LCDData((curent%1000)/100+48);
LCDData('.');
LCDData((curent%100)/10+48);
LCDData((curent%10)/1+48);
}
}
}
///////////// putere disipata down cu viteza //////////////////////////
if (curent>9999 ){
putere= ((tensiune/100)*(curent/10));
if(putere>9999){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%100000)/10000+48);
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData((putere%100)/10+48);
}
}
if (curent>999 && curent<10000){
putere= ((tensiune/100)*(curent/10));
if(putere>9999){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%100000)/10000+48);
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData((putere%100)/10+48);
}
if(putere<10000){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData((putere%100)/10+48);
LCDData(' ');
}
}
if (curent<1000){
putere= (tensiune/100)*curent;
if(putere>9999 ){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%100000)/10000+48);
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData(' ');
}
if(putere>999 && putere<10000){
LCDGotoXY(11,1);
LCDData(' ');
LCDData(' ');
LCDData((putere%10000)/1000+48);
LCDData((putere%1000)/100+48);
LCDData(' ');
}
if(putere<1000){
LCDGotoXY(11,1);
LCDData(' ');
LCDData((putere%1000)/100+48);
LCDData('.');
LCDData((putere%100)/10+48);
LCDData((putere%10)/1+48);
}
}
}
/////////////////////////////////////////////////////
}
}
}
/////////////////mesaj OFF/ON/ERR ///////////////////////
if (!(PINB & (1<<PB0)) && aux>0){
nr =! nr;
_delay_ms (100);
}
if (nr==0){
if ((curent<4001 && putere<4001) && (temperatura<39200))
{
PORTA &=~(1<<PA5);
PORTA &=~(1<<PA3);
PORTD=0x00;
PORTC=0x00;
LCDGotoXY(12,0);
LCDData(' ');
LCDData('O');
LCDData('F');
LCDData('F');
_delay_ms (170);
}
}
if (nr==1){
if ((curent>4000 || putere>4000) && aux>0 && (temperatura<39200)){
for(z=0;z<7;z++){
PORTA &=~(1<<PA5);
PORTA &=~(1<<PA3);
PORTD=0x00;
PORTC=0x00;
LCDGotoXY(12,0);
LCDData('O');
LCDData('V');
LCDData('E');
LCDData('R');
_delay_ms (300);
LCDGotoXY(12,0);
LCDData(' ');
LCDData(' ');
LCDData(' ');
LCDData(' ');
_delay_ms (300);
}
nr= ! nr;
}
if ((curent<4001 || putere<4001) && aux>0 && (temperatura<39200)){
if( aux!=myVar ){
eeprom_write_word(&myVar,aux);
}
LCDGotoXY(12,0);
LCDData(' ');
LCDData(' ');
LCDData('O');
LCDData('N');
_delay_ms (170);
PORTA |= (1<<PA5);
if (aux>0 && aux<20 ){
PORTA |= (1<<PA3);
}
int varrelay[15]={4000,2000,1000,800,400,200,100, 80,40,20,10,8,4,2,1};
char pinOutput[2] = {0,0};
int rest=0,j=0;
rest=aux;
for (j=0; j<15; j++)
{
if (rest/varrelay[j] == 1)
{
if (j < 7)
{
pinOutput[0] = pinOutput[0] | (1 << (8-j-2));
}
else
{
pinOutput[1] = pinOutput[1] | (1 << (15-j-1));
}
rest = rest – varrelay[j];
}
}
PORTD = ~pinOutput[0];
PORTC = ~pinOutput[1];
}
}
}
}
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Subsemnatul Nistorescu Cosmin, student la specializarea Tehnologii Informatice în Ingineria Sistemelor din cadrul Facultății de Automatică,… [310803] (ID: 310803)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
