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];

}

}

}

}

Similar Posts