Laboratorul 2 - Intreruperi, Timere, PWM

Acest laborator are ca scop familiarizarea voastră cu lucrul cu timerele prezente în microcontrollerul Atmega16, acoperind atât modul normal de funcționare cât și cel de PWM. Folosirea timerelor implică și familiarizarea cu întreruperile hardware ale procesorului, prezentate în prima parte a laboratorului.

1. Întreruperi
O întrerupere hardware reprezintă un semnal sincron sau asincron de la un periferic ce semnalizează apariția unui eveniment care trebuie tratat de către procesor. Tratarea întreruperii are ca efect suspendarea firului normal de execuție al unui program și lansarea în execuție a unei rutine de tratare a întreruperii (RTI). Întreruperile hardware au fost introduse pentru a se elimina buclele pe care un procesor ar trebui să le facă în așteptarea unui eveniment de la un periferic. Folosind un sistem de întreruperi, perifericele pot comunica cu procesorul, acesta din urma fiind liber sa-și ruleze programul normal in restul timpului și să își întrerupă execuția doar atunci când este necesar. Înainte de a lansa în execuție o RTI, procesorul trebuie sa aibă la dispoziție un mecanism prin care să salveze starea în care se afla în momentul apariției întreruperii. Aceasta se face prin salvarea într-o memorie, de cele mai multe ori organizata sub forma unei stive, a registrului contor de program (Program Counter), a registrelor de stare precum și a tuturor variabilelor din program care sunt afectate de execuția RTI. La sfârșitul execuției RTI starea anterioară a registrelor este refăcută și programul principal este reluat din punctul de unde a fost întrerupt. Pentru a asocia o întrerupere cu o anumită rutină din program, procesorul folosește tabela vectorilor de întrerupere (TVI), ilustrată în figura de mai jos. În această tabelă, fiecărei întreruperi îi este asociată adresa rutinei sale de tratare, la care programul va face salt în cazul apariției acesteia. Aceste adrese sunt predefinite și sunt mapate în memoria de program într-un spatiu contiguu care alcătuiește TVI. Adresele întreruperilor în TVI sunt setate în funcție de prioritatea lor, cu cât adresa este mai mică cu atât prioritatea este mai mare.

Figura 1. Tabela de vectori de întrerupere pentru atmega16 După cum se observă din figura 1, pe lângă întreruperile componentelor interne uC-ului(timer-e, interfețe seriale, convertor analog-digital), există și 3 linii pentru întreruperi de la periferice externe: INT0, INT1, INT2. Semnalele pentru aceste întreruperi externe vin pe pinii INT0, INT1 și INT2 (portul D pinii 2, 3 respectiv portul B pinul 2).

Figura 2. Pini întreruperi externe pe capsula ATMega16 Microcontroller-ul oferă posibilitatea mascării întreruperilor prin scrierea pe 0 a bitului I din registrul de status (SREG). Valoarea inițială a acestui bit este 0, deci chiar dacă întreruperile unui periferic sunt activate din unul din registrele acestuia, tot nu sunt luate în considerare decât când se scrie 1 pentru acest flag. Totodată, la apariția unei întreruperi, în afară de salvarea stării, procesorul dezactivează întreruperile, iar la revenirea din rutina de tratare le reactivează. Activarea lor poate fi realizată forțat și din handler-ul de întrerupere(de exemplu suntem în handler-ul pt reset, și dorim să activăm întreruperile unui timer).

1.1. Tratarea unei intreruperi

Figura 3. Status Register (SREG) • • • • contine flag-uri setate in urma operatiilor unitatii aritmetice logice contine flag-ul I de activare/dezactivare intreruperi nu este salvat la aparitia unei intreruperi !!! descris in datasheet in capitolul AVR CPU Core . Cu toate acestea. In timpul executiei unei intreruperi. External Interrupts.2.0xFF. Registre Descrierea completa a acestor registre o gasiti in datasheet in capitolele Interrupts. Dupa efectuarea instructiunii. programul gaseste instructiunea jmp $2FF care-i permite sa sara la rutina efectiva de tratare a intreruperii. adica orice alta intrerupere care poate aparea in timpul intreruperii curente nu va fi luata in seama. Acest lucru se traduce prin saltul programului de la adresa curenta ($123) la adresa $002. 1. registrul contor program (PC) este automat salvat in stiva si apoi initializat la valoarea corespunzatoare adresei lui INT0 ($002). permitand astfel executia de intrerupere in intrerupere. utilizatorul poate sa reseteze bitul I din software. Aici. La sfarsitul oricarei RTI trebuie sa existe instructiunea reti care reface din stiva registrul PC (programul sare inapoi la adresa de unde ramasese inainte de intrerupere). Tratarea unei intreruperi pentru ATMega16 Sa presupunem ca programul nostru primeste intreruperea externa INT0 in timp ce executa instructiunea ldi R16. bitul I din SREG este setat la 0 si resetat la iesire.

h) Întrerupere ADC INT0 INT1 INT2 TIMER2 COMP TIMER2 OVF Identificator ADC_vect INT0_vect INT0_vect INT0_vect TIMER2_COMP_vect TIMER2_OVF_vect Descriere ADC conversion complete Întreruperea externă 0 Întreruperea externă 0 Întreruperea externă 0 Compare match pe timer-ul 2 Overflow pe contorul timer-ului 2 . INT0 combinatiile a cate doi biti stabilesc frontul(crescator sau descrescator) pe care se genereaza cererea de intrerupere.h pentru definirea rutinelor de tratare a întreruperilor.inceputul memoriei Flash.Figura 4. Registrul SREG General Interrupt Control Register (GICR) • • • contine flag-uri pentru activarea/dezactivarea intreruperilor externe INT0.2 bitul IVSEL controleaza unde se plaseaza vectorii de intreruperi(0 . 1 . Lucrul cu întreruperi în avr-gcc avr-libc oferă interfața din avr/interrupt.3. acesta este descris in datasheet in capitolul External Interrupts MCU Control and Status Register (MCUCSR) * bitul ISC2 seteaza modul de generare a intrerupererii externe asincrone INT2 (0 .1. Registrul MCUCSR 1.inceputul sectiunii de Boot Loader din Flash) bitul IVCE activeaza scrierea bitului IVSEL MCU Control Register (MCUCR) • • • contine biti pentru power management si selectarea modului de generare a intreruperilor externe INT1. Tabela de vectori specifică fiecărui microcontroller (în cazul nostru pentru ATMega16) este declarată în header-ul de IO specific (ex: iom16.front descrescator. 1 front crescator) Figura 5.

h> ISR(INT0_vect) { . adică salvarea SREG și apelul reti() ISR_ALIASOF: rutina este identică cu cea a altui vector de întrerupere #include <avr/interrupt.. RXC … USART_RXC_vect … Primirea unui octet pe seriala USART … Definirea rutinei de tratare se face cu macro-ul ISR: #include <avr/interrupt.. în care întreruperile globale sunt dezactivate atunci când se intră într-o întrerupere ISR_NOBLOCK: facilitează existența întreruperilor imbricate (poate fi util dacă se dorește ca o altă întrerupere să fie întârziată) ISR_NAKED: omite prologul și epilogul rutinei de tratare. Timer . flag) { . Ar trebui sa fie ultima instructiune apelata intr-o rutina care foloseste flag-ul ISR_NAKED. care acum este deprecated! #include <avr/interrupt.. } Pentru rutine există și sintaxa cu SIGNAL(…). activează întreruperile globale.. dezactivând întreruperile globale.întoarcerea dintr-o rutină de tratare a intreruperii. Apelează instrucțiunea assembler cli reti() . activând întreruperile globale.. } ISR(INT1_vect.h> ISR(INT0_vect) { .h> ISR(vector.setează pe 1 bitul I din SREG.. Întreruperile întâlnite care nu au un rutină de tratare vor cauza o întrerupere de reset! 2. Apelează instrucțiunea assembler sei cli() . } Macro-ul ISR definește rutina de tratare pentru perifericul respectiv. salvează SREG și apelează instrucțiunea reti la ieșirea din rutină.USART. ISR_ALIASOF(INT0_vect)) Alte wrapper-e (în jurul unor instrucțiuni ale core-ului AVR) oferite de interfață sunt: • • • sei() . Rutinele pot fi definite cu următoarele flag-uri: • • • • ISR_BLOCK: comportamentul default.setează pe 0 bitul I din SREG.

Componentele si functionarea unui timer pt atmega16 Timerele sunt prevazute cu mai multe canale astfel in paralel se pot desfasura diferite numaratori. Registrul numarator (Timer Counter.2. TCNT) care masoara efectiv intervalele de timp si care este incrementat automat cu o frecventa data.1. Principiul de functionare a unui Timer poate fi descris in linii mari de cele trei unitati: 1. odata initializat va functiona independent de unitatea centrala (core μP). Acesta are menirea de a diviza in functie de necesitatile aplicatiei frecventa de ceas si odata cu divizarea sa incrementeze registrul TCNT. Principalele caracteristici sunt: . La fiecare incrementare a TCNT are loc o comparatie intre acest registru si o valoare stocata in registrul OCRn. 2. Principiul de functionare al unui Timer Timerul/Counterul. dupa cum ii spune si numele ofera facilitatea de a masura intervale fixe de timp si de a genera intreruperi la expirarea intervalului masurat. 3. Acest lucru permite eliminarea buclelor de delay din programul principal. Avand ceasul intern sau alt ceas conectat pentru a obtine diferite intervale folosim un “Prescaler”. Figura 6. Un timer. Aceasta valoare poate fi incarcata prin software de utilizator. ATmega16 este prevazut cu 3 unitati de timer: doua de opt biti si una de numarare pe saisprezece biti. Daca are loc egalitatea se genereaza o intrerupere. in caz contrar incrementarea continua.

2. detalii despre combinatiile de biti pentru aceste registre sunt prezente in datasheet.5. trebuie folosită forma precisă. si prin cand se face resetarea contorului. TCCR2) • • • registre de 8 biti si nu au restrictii de acces CPU. 2. ce se diferentiaza prin valorile pana la care se face incrementarea. TCCR0. Registre Deoarece Timer/Counter 1 functioneaza pe 16 biti. . Atunci cand se foloseste registrul sau bitul definit intr-un program. in tabelele de la descrierea registrelor TCCR pentru fiecare timer. Moduri de functionare Figura 7. Configuratie pentru moduri generatoare de unda Timer/Counter0 si Timer/Counter2 au patru moduri de functionare.Un “n” mic inlocuieste numarul timerului si un “x” mic inlocuieste unitatea de comparare de output. rolul lor este de a configura Timerul pentru un anumit mod de functionare. TIMSK (Timer/Counter Interrupt Mask Register) • • • • 8 biti contine biti pentru a activa sau dezactiva intreruperile generate de timere(overflow si output compare) este folosit pentru toate cele trei timere intreruperile sunt activate doar daca si bitul I din SREG este setat (intreruperile sunt activate global) Registrele de control T/C(TCCR1A/B. el prezinta si registre pe 16 biti. a caror accesare este descrisa in sectiunea 2.• • • • • • • • • • Design true 16bit(permite 16bit PWM) Doua unitati de independente de comparare output(doua canale) Unitate de captura input Un anulator de zgomot pe intrare Stergerea cronometrului la potrivirea compararii (auto reincarcare) Puls de corectare a fazelor cu modulator (PWM) Perioada PWM variabila Generator de frecventa Counter extern de evenimente Patru surse de intrerupere independente Majoritatea registrelor si referintelor de biti din aceasta sectiune sunt prezentate intr-o forma generala. 2.3.

fie de scriere. 2. 2.1.ului de date de 8 biti. fie de citire pe 8 biti.5. Un controller PWM este in esenta un convertor digital-analog (DAC) pe un singur bit. Valoarea TOP poate fi desemnata astfel incat sa fie una din aceste valori fixe: 0x00FF. 0X01FF.6.2 (Output Compare Register) • • • • contin o valoare comparata cu valoarea din TCNT la fiecare incrementare a acesteia. Pentru a executa o scriere de 16 biti.modularea factorului de umplere al unui semnal) permite controlul circuitelor analogice din domeniul digital. 0X003FF sau valoarea memorata in registrele OCR1A sau ICR. nu feature hardware). rezultatul comparatiei poate fi folosit de catre generatorul de unde pentru a genera un semnal PWM la pinul de Comparare a Output-ului(OC1A/B) OCR1 este pe 16 biti ICR0. OCR1A/B si ICR1 sunt registre de 16 biti care pot fi accesate de catre AVR CPU cu ajutorul bus. operatia de comparare seteaza semnalul de potrivire-comparare (OCF1A/B) la generarea unei cereri de intrerupere de comparare output. Această modulație vine în sprijinul multor aplicații deoarece înseamnă consum mic. Definitii • • • BOTTOM = counterul ajunge la capat la valoarea 0x0000.TCNT0.2 (Input Capture Register) • • se scrie in el valoarea din TCNT de fiecare data cand apare un eveniment pe pinul ICP1. Calculator 3.4. Pulse width modulation (PWM) PWM (Pulse Width Modulation . TCNT1 este pe 16 biti OCR0. ICP1 este pe 16 biti 2. byte-ul HIGH trebuie sa fie scris inaintea byte-ului LOW (bug de compilator. . Accesarea registrelor pe 16 biti TCNT1.1.1. Un registru de 16 biti poate sa sa fie accesat folosind doua operatii. eliminarea zgomotelor și aplicații cu cost redus.2 • • contin valoarea contorului timerului. MAX = Counterul ajunge la maxim la valoarea 0xFFFF TOP = Counterul ajunge la valoarea TOP cand devine egal cu cea mai mare valoare din secventa de numarare.

Pentru a implementa o asemenea facilitate ele se folosesc de un numărator care este incrementat periodic (conectat direct sau indirect la o unitate de ceas) si care este resetat la sfarsitul fiecărei perioade a PWM-ului. Tipuri de PWM • • Modulatie Delta Modulatie Delta-Sigma Multe circuite digitale pot genera semnale PWM.3. iesirea PWM (output-ul) trece din starea inalta in stare joasa (sau invers). Cand valoarea numaratorului este mai mare decat valoarea de referinta. Considerand o forma de unda dreptunghiulara f(t) cu o valoare minima ymin si o valoare maxima ymax si factorul de umplere D(ca in figura) valoarea medie a formei de unda e data de relatia: cum f(t) este o forma de unda dreptunghiulara valoarea sa maxima se atinge pentru 0<t<D*T. Principiul de functionare Modularea foloseste variatia factorului de umplere a unei forme de unda dreptunghiulara pentru a genera la iesire o tensiune analogica. .1. Majoritatea microcontrollerelor dispun de aceasta facilitate.

Porturile 13:01 C. Programul şi schema electrică le puteţi downloada de la secţiunea Download-Porturi-Aplicaţie1.PC0-P6 portului C iar PD0-PD7 portului D.La apăsarea butoanelor vom dori ca led-urile corespunzătoare butoanelor apăsate să se aprindă.PORT care setează datele de ieşire ale portului la nivel de pin şi PIN care memorează intrările microcontrolerului la nivel de pin. putându-se astfel relaiza schimbul a mai multor biţi de date simultan.În cazul nostru. pentru portul C avem PC iar pentru portul D avem PD.Avantajul cel mare este că ele sunt paralele. Pentru a exemplifica modul de configurare şi de utilizare a porturilor din ATMega8 voi crea un exempu simplu în care vom avea setaţi primii 4 pini ai portului B ca pini de intrare iar primii 4 pini ai portului C ca pini de ieşire. Microcontrolerului ATMega8 are asociat unui port 3 regiştrii.C şi D.Ei bine ultimul bit din regiştrii asociaţi portului nu este flosit.De obicei unui port sunt asociaţi 2 regiştrii.În cazul de faţă pinii sunt notaţi cu P.Dacă ne uităm pe schema generală avem următoarea configuraţie: Pinii PB0-PB7 corespund portului B. Schema electrică în Proteus a aplicaţiei este următoarea: . microcontrolerul ATMega8 este pe 8 biţi deci şi dimensiunea regiştrilor va fi tot de 8 biţi. No comments Trimiteţi prin e-mail Postaţi pe blog! Distribuiţi pe Twitter Distribuiţi pe Facebook Porturile unui microcontroler sunt cele mai folosite dispozitive de schimb de date cu exteriorul.La pinii de intrare vor fi legate 4 butoane iar la pinii de ieşire ai portului C vom lega 4 LED-uri.Lungimea unui port este influenţată de numărul de biţi pe care procesorul îi poate executa la un moment dat.În viziunea programatorului porturile nu sunt altceva decât niste regiştrii prin care se pot scrie şi citi date.DDR care setează direcţia pinilor. pentru portul B avem PB .Pentru a vă face o imagine mai bună asupra legăturii dintre pinii microcontrolerului şi regiştri asociaţi portului urmăriţi figura de mai jos: Obse rvăm că pinului 0 îi corespunde locaţiei 0 a portului.Numărul porturilor este tot 3 şi sunt numite B.Observăm că portul C are doar 7 intrări.C. unul care setează direcţia pinilor iar altul care realizează schimbul de date între unitatea centrală a microcontrolerului şi exterior. pinului 1 locaţiei 1 şi tot aşa.

direcţia pinilor se setează cu ajutorul registrului DDR(Data Direction Register).Programul din memoria microcontrolerului nu va face alceva decât să preia informaţia de la portul B şi să o transmită la portul C.adică toţi pinii sunt setaţi ca intrare. adică doar primii 4 pini sunt setaţi ca ieşiri.Reprezentarea valorii 0x0F este o reprezentare în hexazecimal şi este echivalentă cu 0b00001111 în binar şi cu 15 în .Save and exit: După cum am mai spus. Pentru scrierea programului în CodeVision AVR procedaţi exat cum v-am arătat mai înainte la prezentarea generală a programului însă la secţiunea de setare mergeţi la Ports>Port C şi setaţi primii 4 biţi de direcţie ca în figura de mai jos apoi daţi din meniul File. Generate . restul fiind setaţi ca intrări. iar DDRC = 0x0F.Dacă veţi urmări în secţiunea de setare a programului la începutul funcţiei main veţi observa că DDRB =0x00.

dacă se apasă butonul 2.vom avea modul 2 de funcţionare şi tot aşa până la butonul 4.Pentru încărcarea programului în schema din Proteus daţi dublu click pe micorocontroler.Dacă compilarea codului a decurs normal ar trebui să aveţi ca rezultat un fişier cu extensia *.Fizic aplicaţia o puteţi vedea aici: Următoarea aplicaţie este ceva mai complexă.zecimal.Acest fişier se găseşte în locţia în care aţi salvat anterior proiectul din Code Vision AVR.bucla de ciclare infinită.La apăsarea butoanelor ar trebui să se aprindă LED-urile corespunzătoare.Mergeţi la câmpul Program File şi adăugaţi fişierul program. Schema elecrtrică a aplicaţiei în Proteus va fi următoarea: . adică bitul 1 al registrului PINB este 1 logic.Ca rezultat veţi deschide o fereastră cu titlul Edit Component. Programul este gata putând fi deja compilat.Dacă se apasă primul buton.org/wiki/Sistem_binar În bucla while.wikipedia. ea având rolul simulării unei instalaţii luminoase pentru pomii de crăciun la care vom avea posibilitatea alegerii unui program de funcţionare prin apăsarea unor butoane. vom avea modul 1 de funcţionare.De data asta vom folosi tot portul B ca port de intrare la care vom lega la primii 4 pini.Dacă nu este apăsat nici un buton se vor activa pe rând toate cele 4 moduri. în directorul Exe.hex. 4 butoane cu care vom alege modul de funcţionare iar ca port de ieşire vom folosi portul D la pinii căruia vom lega 8 LED-uri. vom avea o singură linie care va transfera datele de la intrarea portului B la ieşirea portului C adică vom transfera conţinutul registrului PINB în registrul PORTC: PORTC = PINB.Dacă se apasă două sau mai multe butoane nu se va întâmpla nimic.Dacă nu sunteţi familiarizaţi cu sistemul binar şi hexazecimal puteţi afla cum se fac conversile aici:http://ro. Programul şi schema electrică le puteţi downloada de la secţiunea Download-Porturi-Aplicaţie 2. Dacă totul a decurs bine până aici puteţi simula aplicaţia fără nici o problemă. adică bitul 0 al registrului PINB este 1 logic.

Probabil că vă întrebaţi de ce este nevoie de aşa ceva. while(PORTD) { delay_ms(100). } } La început iniţializăm PORTD-ul cu valoarea 0b00000001 deoarece dorim ca primul led să fie aprins.Pentru a folosi această funcţie trebuie să includeţi librăria delay. Pentru modul 2 de funcţionare codul este asemănător însă operaţia de şiftare se face de la . în cazul nostru 100 de milisecunde.Acest lucru se face prin codul PORTD = PORTD<<1 care reprezintă şiftare bitului 1. Pentru o lizibilitate mai buna a codului am ales să am câte o funcţie pentru fiecare mod de funcţionare. Observăm că aici apare o funcţie pe care nu am avut ocazia să o folosesc mai înainte şi anume delay_ms.Pentru ca al doilea LED să se aprindă şi să se stingă primul trebuie să mutăm 1-ul de pe prima poziţie pe poziţia a doua.Aceasta are rolul de a întârzia programul cu n milisecunde.După execuţia primului ciclu while noua valoare a PODRTD-ului va fi 0b00000010. PORTD = PORTD<<1.Pentru modul 1 codul este următorulul: void mod1(void) { PORTD = 0b00000001.Pentru a vă face o idee cum funcţionează funcţia urmăriţi codul de mai jos: Iniţializare :PORTD = 0b00000001 Ciclu 1:PORTD = 0b00000010 Ciclu 2:PORTD = 0b00000100 Ciclu 3:PORTD = 0b00001000 Ciclu 4:PORTD = 0b00010000 Ciclu 5:PORTD = 0b00100000 Ciclu 6:PORTD = 0b01000000 Ciclu 7:PORTD = 0b10000000 Ciclu 8:PORTD = 0b00000000 Deoarece la ciclul 8 valoarea PORTD va fi 0 se va ieşi din ciclu while şi totodată şi din funcţia mod1.funcţii care sunt plasate înaintea funcţiei main.h.Pentru scrierea codului procedaţi exact ca la primul exerciţiu însă setaţi de data aceasta toţi pinii portului D ca fiind pini de ieşire.Ei bine dacă nu am avea un timp între schimbările portului am vedea toate LED-urile aprinse datorită vitezei mari de comutare.

PORTD = 0b01000010. delay_ms(100). break. delay_ms(100). PORTD = PORTD>>1. delay_ms(100). apoi vom stinge led-urile din mijloc aprinzând led-urile următoare( pinii 2 şi 5) şi tot aşa până la aprinderea led-urilor 1 şi 8(pinii 0 şi 7). while(PORTD) { delay_ms(100). } } În modul 3 vom aprinde mai întâi led-urile din mijloc (pinii 3 şi 4). //se apasa al doilea buton si se seteaza modul 2 de functionare case 0b00000010: mod2(). void mod4(void) { PORTD = 0b10000001. void mod3(void) { PORTD = 0b00011000. while(1) { switch(PINB) { //se apasa primul buton si se seteaza modul 1 de functionare case 0b00000001: mod1(). PORTD = 0b10000001. PORTD = 0b00011000. delay_ms(100).aprinzând ledurile din exterior spre interior. delay_ms(100). delay_ms(100). PORTD = 0b00100100. PORTD = 0b01000010. delay_ms(100). void mod2(void) { PORTD = 0b10000000. //se apasa al treilea buton si se seteaza modul 3 de functionare . PORTD = 0b00100100. } În bucla de ciclare infinită vom face o selecţie a acestor 4 moduri în funcţie de butoanele pe care le-am apăsat. break. delay_ms(100).stânga la dreapta. } Modul 4 se va comporta exact invers modului 3.

etc. No comments Trimiteţi prin e-mail Postaţi pe blog! Distribuiţi pe Twitter Distribuiţi pe Facebook Întreruperile într-un microcontroler sunt văzute ca nişte evenimente speciale generate de elementele periferice. atingerea unei valor a numărătorului. //daca s-a apasat mai multe butoane nici un mod va fi activ default: PORTD = 0x00. } }. Pentru a vedea ce butoane au fost apăsate trebuie să verificăm pinii portului B.C. mod3().Toate acestea sunt gestionate de un sistem intern numit sistem de întreruperi . sistem care are rolul de a oferi procesorului informaţii referitoare la natura întreruperii şi de a opri funcţionarea ciclică tratând întreruperea într-o rutină specială. mod4().Această verificare se face prin swhitch care verifică valorile registrului PINB.În cazul chip-ului ATMega8 adresele rutinelor de tratare corespunzătoare întreruperilor sunt următoarele: .terminarea de citit a unei valori a convertorului analog digital.case 0b00000100: mod3().Dacă nu s-a apăsat nici un buton . mod2(). Din păcate programul nostru are un neajuns şi anume atunci când este apăsat un buton nu se rulează rapid modul selectat ci trebuie să aşteptăm teminarea modului anterior.Acest lucru se poate rezolva prin întreruperi după cum vom vedea mai târziu. //se apasa al patrulea buton si se seteaza modul 4 de functionare case 0b00001000: mod4(). şi tot aşa până la butonul 4.iar dacă avem altă combinaţie a registrului PINB valoarea lui PORTD va fi 0..adică PINB = 0b00000000 atunci se vor executa pe rând cele 4 funcţii. break. break.Aceste evenimente pot fi reprezentate de apăsarea unui buton. Această rutină are o adresă specială de început. Sistemul de întreruperi 04:25 C.Dacă s-a apăsat butonul 1 vom avea valoarea 0b00000001 şi se execută funcţia mod1.dacă s-a apăsat butonul 2 vom avea valoarea 0b00000010 şi se execută funcţia mod2. //daca nu s-a apasat nici un buton se vor parcurge toate cele 4 moduri case 0b00000000: mod1().

Pentru a putea folosi orce întrerupere trebuie mai întâi să informăm microcontrolerul că întreruperile sunt activate.Prioritatea de tratare a unei întreruperi în cazul în care avem mai multe cereri de întrerupere este marcată de prima coloana.apoi întreruperea externă INT0 .Primii doi biţi ai . astfel cea mai mare prioritate o are întreruperea generată de semnalul RESET. întreruperea externă INT1 şi tot aşa. Momentan voi trata doar întreruperile externe.în C fiind #asm("cli"). P entru dezactivarea întreruperilor se foloseşte comanda cli.bitul I. deoarece sunt cele mai simple de configurat.Acest lucru se face prin comana sei.Trebuie să precizez că aceste adrese sunt mascate în CodeVisionAVR dar totuşi e bine să ştiţi cum funcţionează modul intern de tratare al întreruperilor.INT0 şi INT1. comandă care în C se poate scrie astfel: #asm("sei") Această comandă nu face altceva decât să seteze valoarea 1 în cel mai semnificativ bit. Activarea întreruperilor externe se face prin registrul GICR(General Interrupt Control Register) care are următoarea formă: Pentru a activa întreruperea externă INT0 trebuie să setăm valoarea 1 în locaţia 6 din registru iar pentru activarea întreruperii externe INT1 trebuie setată valoarea 1 în bitul 7.bit care permite folosirea sistemului de întreruperi. din regist SREG.

lucru necesar pentru a se evita ciclarea la infinit a rutinei.Frontul descrescător al semnalului va genera o cerere de întrerupere.Valorile variabilelor care contorizează de câte ori au fost apăsate butoanele vor fi afişate pe un LCD.primii doi biţi(ISC00 şi ISC01) fiind atribuiţi întruperii INT0 iar biţii 3 şi 4(ISC10 şi ISC11) sunt atribuiţi întruperii INT1. IVCE şi IVSEL se folosesc atunci când în memoria microcontrolerului avem o secţiune boot însă în acest tutorial nu o să folosim aşa ceva.Nivelul de jos al semnalului va genera o cerere de întrerupere.Acest registru se verifică pentru a vedrea sursa întreruperii.Orce schimbare a formei semnalului va genera o cerere de întrerupere. . bitul corespunzător întreruperii îi va fi automat atribuită valoarea 1. va trebui să setăm în ce moment să se activeze întreruperea. 10.ei fiind rezervaţi. Dacă întreruperea a fost generată ea va fi semnalată în registrul GIFR: Dacă pe parcursul rulării programului bitul 6 ia valoarea 0 atunci înseamnă că avem o cerere de întrerupere generată de întreruperea externă 0 iar dacă bitul 7 ia valoarea 0 înseamnă că avem o cerere de întrerupere generată de întreruperea externă 1. 11.La unul dintre pinii microrontrolerului va fi legat un LED care îşi va schimba starea din aprins în stins şi invers la intervalul de o secundă.Codul programului îl puteţi descărca de la secţiunea Download-Întreruperi-Aplicaţie 1. 01.registrului. În exemplul următor voi incrementa 2 variabile prin apăsarea a 2 butoane legate la pinii corespunzători cererii de întrerupere INT0 şi INT1.Următoarea configuraţie este valabilă pentru ambele întreruperi încât biţii ISC11/ISC01 şi ISC00/ISC10 pot lua următoarele valori: ISC11/ISC01 ISC00/ISC10 00.Restul biţilor 2-5 nu sunt folosiţi.Acest lucru se poate seta prin registrul MCUCR: Din acest registru doar primii 4 biţi(0-3) sunt atribuiţi întreruperilor externe. După ce am setat ce întreruperi externe sunt folosite.Frontul crescător al semnalului va genera o cerere de întrerupere.Ddupă execuţia rutinei de tratare.aceşti biţi având valoarea 1 atâta timp cât nici o cerere nu a fost lansată.

vom seta LCD-ul pe portul B . MCUCR = 0b00001111 .adică se va lansa o cerere de întrerupere la trecerea semnalului de intrare de la valoarea 0 la valoarea 1: Pentru această configurare programul va seta regiştrii de mai sus cu următoarele valori: GICR =0b11000000 – se activează ambele întreruperi INT0 şi INT1.Schema electrică a aplicaţiei este următoarea: Dacă ne uităm la schema chip-ului observăm că pinii portului D.LED-ul îl vom lega la pinul 0 al portului D.se vor semnala cereri de întrerupere la trecerea semnalului din starea 0 în starea 1.Înainte de generarea programului în CodeVision AVR.Vom selecta ambele întreruperi iar în dreptul lor vom alege Rising Edge. După ce aţi generat programul veţi observa că două noi funcţii au fost generate: interrupt [EXT_INT0] void ext_int0_isr(void) şi interrupt [EXT_INT1] void ext_int1_isr(void) funcţii prin care vom trata apariţia întreruperilor.pinul PD0 ca pin de ieşire iar pentru setarea întreruperilor externe vom merge la External IRQ.PD2 şi PD3 sunt folosiţi şi ca pini pentru întreruperi acest lucru înpingându-ne să legăm LCD-ul la portul B.Codul din .

//afisarea datelor pe LCD } In aceste funcţii pe lângă incrementare am convertit variabilele corespunzătoare întreruperilor. //adaugam la sirul linie1 textul"INT1=" strcat(linie2. char convert[4]. am concatenat şirurile de caractere care conţin sursele întreruperilor şi valorile variabilelor transformate în şir de caractere şi apoi le-am afişat pe LCD.in1). delay_ms(1000). char linie1[16]. //mutarea cursorului in LCD la linia 1 coloana 0 lcd_puts(linie2).apăsarea nu este .convert). //convertim valoarea lui int1 in sir de caractere strcpy(linie2.linie2[16]. //mutarea cursorului in LCD la linia 0 coloana 0 lcd_puts(linie1).interiorul funcţiilor care tratează apăsarea unui buton este următorul: interrupt [EXT_INT0] void ext_int0_isr(void) { int0++.//adaugam la sirul linie1 valoarea variabilei int1 lcd_gotoxy(0.h. //la apasare se incrementeaza variabila int0 itoa(int0.convert).convert).Pentru conversia din short în şir de caractere.funcţia itoa. am inclus biblioteca stdlib.Acest lucru se întâmplă deoarece există situaţia în care programul aşteaptă să treacă o secundă iar dacă se apasă butonul şi se eliberează în acest timp.end).int1=0.Totuşi dacă veţi încerca să dezvoltaţi aplicaţia fără întreruperi veţi observa că sunt situaţii în care apăsaţi butoanele şi variabilele nu se incrementează. //atribuim sirului linie1 valoarea '\0' strcat(linie1. //convertim valoarea lui int0 in sir de caractere strcpy(linie1. //afisarea datelor pe LCD } interrupt [EXT_INT1] void ext_int1_isr(void) { int1++. Este necesară declararea lungimii şirurilor deoarece microcontrolerul nu poate aloca dinamic spaţii de memorie în memoria program de tip flash. //la apasare se incrementeaza variabila int1 itoa(int1. Pentru a folosi funcţiile de concatenare şi copiere (strcat şi strcpy) a fost necesară includerea bibliotecii string.in2). din short în sir de caractere.end[1]="".convert). Poate că vă întrebaţi care e scopul folosirii întreruperilor pentru această aplicaţie când puteam să folosim doar citirea normală la nivel de port.//adaugam la sirul linie1 valoarea variabilei int0 lcd_gotoxy(0.0). //adaugam la sirul linie1 textul"INT0=" strcat(linie1. char in2[6] = "INT1=". }. PORTD = 0x01. char in1[6] = "INT0=". //atribuim sirului linie1 valoarea '\0' strcat(linie2.1). delay_ms(1000).h.end).Variabilele cu care am lucrat în aceste funcţii sunt declarate în partea de declarare a variabilelor globale: unsigned short int0=0. În bucla infinită while avem doar codul care va aprinde şi va stinge LED-ul după o secundă: while (1) { PORTD = 0x00.

C.Tot în momentul resetării numărătorul trimite un semnal către sistemul de întreruperi.Acest NLC este de fapt un registru de 8 sau 16 biţi care la fiecare impuls este incrementat cu o unitate.Tot cu ajutorul timer-elor se pot genera trenuri de impulsuri de o anumită frecvenţă sau compararea a 2 intervale de timp.Dacă NLC-ul are valoarea FFh/FFFFh şi primeşte un impuls el se resetează.Timer 1 şi Timer 2 însă momentan ne vom concentra asupra Timer-ului 0. Microcontrolerul ATMega8 oferă 3 timere:Timer 0. Timer-ele conţin un numărător liber central(NLC) care are rolul de a număra fiecare impuls de tact. Funcţionarea fizică a aplicaţiei o puteţi vedea mai jos: Timer-ele .Folosind întreruperile se elimină acest neajuns.Observăm din schemă că o dată ce s-a atins valoarea 0xFF se trimite un semnal către logica de control care poate genera o cerere de întrerupere.Timer-ele funcţionează independent de unitatea centrală a micrcontrolerului astfel eliminându-se momentele de timp în care microcontrolerul este blocat într-o buclă de aşteptare. 1 comment Trimiteţi prin e-mail Postaţi pe blog! Distribuiţi pe Twitter Distribuiţi pe Facebook Timer-ele sunt sisteme integrate în microcontroler care au ca scop măsurarea unor intervale fixe de timp şi de a genera întreruperi la expirarea intervalului măsurat. Timer/Counter 0 Timer-ul 0 este un timer de uz general pe 8 biţi care are următoarea schemă bloc: În cazul de faţă NLC-ul este reprezentat de registrul TCNT0 la care avem acces de citire şi scriere.Numărătorului i se poate da o valoare de start cuprinsă între 00h/0000h şi FFh/FFFFh.Timer 0 02:57 C.noua valoare fiind 00h/0000h.Sursa semnalului care incrementază NLC-ul poate fi externă(T0) sau internă(semnalul de tact al microcontrolerului) .contorizată.

care poate fi prescalată.La fiecare tact clkT0 numărătorul TCNT0 este incrementat:

Registrul TCCR0 are rolul de a selecta şi prescala susra semnalului de tact, el având forma:

D in acest registru vom folosi numai ultimii 3 biţi (CS02, CS01, CS00) pentru setare.Valorile pe care le poate lua şi seminificaţiile lor sunt următoarele: 000– nu se selectează nici o sursă de tact; 001– foloseşte ceasul intern fără prescalare; 010– foloseşte ceasul intern cu prescalarea 8 (clkT0/8); 011– foloseşte ceasul intern cu prescalarea 64 (clkT0/64); 100– foloseşte ceasul intern cu prescalarea 256 (clkT0/256); 101– foloseşte ceasul intern cu prescalarea 1024 (clkT0/1024); 110– foloseşte o sursă externă de tact la pinul T0.Se ia în considerare frontul descrescător; 111– foloseşte o sursă externă de tact la pinul T0.Se ia în considerare frontul crescător; Pentru a se putea genera o cerere de întrerupere a timer-ului 0 trebuie ca cel mai semnificativ bit al registrului SREG(bitul I) să fie 1 şi cel mai nesemnificativ bit al registrului TIMSK, bitul TOIE0 să fie tot 1.

Cererea de întrerupere este semnalizată în registrul TIFR în cel mai nesemnificativ bit,TOV0.Dacă registrul TCNT0 a fost umplut,TOV0 devine 0 şi atunci sistemul va genera o întrerupere executându-se codul de la adresa 0x009. În majoritatea aplicaţiilor cu timere se foloseşte prescalarea sursei de tact.Calcului prescalării se face în felul următor: Mai întâi calculăm frecvenţa la care dorim să se genereze o întrerupere.Frecvenţa va fi raportul dintre o secundă şi intervalul la care dorim să primim semnalul de la timer.

În funcţie de această frecvenţă vom alege frecvenţa externă sau vom prescala ceasul intern.Prescalarea ceasului intern se face în aşa fel încât frecvenţa rezultantă să fie egală sau mai mică cu frecvenţa dorită.

Dacă prescalând timerul nu obţinem o

frecvenţă egală cu cea dorită şi obţinem o frecvenţă mai mică, atunci se calculează valoarea de start a NLC-ului.Această valoare va fi raportul dintre frecvenţa internă şi prescalarea aleasă la pasul anterior înmulţită cu frecvenţa dorită:

Pentru a înţelege mai bine cum se calculează frecvenţa vom calcula prescalarea şi n-ul pentru timpul de 0,2 secunde.Ceasul folosit va fi cel intern.Datele de pornire sunt: tdorit = 0.2s,fint =1MHz.

Observăm ca această frecvenţă este mai mică decât frecvenţa pe care dorim să o scoată timerul(5Hz), în consecinţă vom calcula valoarea de pormire a lui TCNT0.

Din păcate în numărător nu se pot reţine date în virgulă mobilă aşa că lui TCNT0 i se va atribui valoarea 195.Acest lucru va duce însă la o mică eroare de măsurare a timpului care totuşi este insesizabilă la o funcţionare pe termen scurt. Pentru acest exempu configurarea regiştrilor va fi următoarea: TCNT0=195; TCCR0=0x05; TIMSK=0x01; Vom considera că la generarea unei întreruperi se va schimba starea unui pin la care avem legat un LED.Pinul de care vom lega LED-ul este PB0. Programul îl puteţi downloada de la secţiunea Download-Timer0-Aplicaţie 1. Schema electrică este una simplistă:

Când creaţi proiectul în CodeVision AVR,la secţiunea de setare a caracteristicilor, veţi seta pinul PB0 ca pin de ieşire iar pentru setarea parametrilor timer-ului veţi merge la Timers-Timer 0 şi veţi alege la Clock Source: System Clock, la Clock Value:0.977Hz,selectaţi Owerflow Interrupt şi la Time value treceţi C3h(195 în decimal).Observăm că frecvenţa aleasă nu este cea calculată de noi însă aceată alegere va seta TCCR0=0x05, adică prescalarea cu 1024.

Observăm că la generare avem următoarele setări: TCCR0=0x05; TCNT0=0xC3; TIMSK=0x01; În concsecinţă setările sunt bine făcute.Ce a mai apărut nou în program este funcţia de tratarea a întreruperilor generate de timer,funcţie în care vom iniţializa de fiecare dată TCNT0 şi în care vom schimba valoarea PORTB-ului: interrupt [TIM0_OVF] void timer0_ovf_isr(void) { // Reinitializam valoarea timerului TCNT0=0xC3; // Schimbam starea PORTB-ului PORTB =~PORTB; } Bun, probabil aţi observat că acest program se putea face şi fără timere de aceea următorul exemplu va fi unul mai complex şi anume un ceas digital reglabil.Aplicaţia va avea un LCD pe care vom putea citi ceasul şi 2 butoane prin care se va regla minutul şi ora,butoane care vor fi

Acest lucru se face prin modificarea sirului de caractere linie1. erori care pot fi înlăturate folosind un oscilator extern special pentru ceas.În aceste funcţii sunt verificate variabilele de ceas dacă au ajuns la valoarea maximă şi dacă da ele sunt resetate şi totodată sunt incrementate variabilele care le urmează.Când se ajunge la valoarea 10.Configurarea pentru generarea programului în CodeVision AVR se face la fel ca mai înainte însă la Timer Value treceţi 62(98 în decimal). adică echivalentul unei secunde.81Hz. ele trebuiesc resetate. existând erori de măsurare a timpului. Schema electrică este următoarea: Următorul lucru pe care trebuie să îl facem este să calculăm frecvenţa timerului astfel încât să avem o întrerupre la o secundă.Pentru aceasta frecvenţa dorită este 1 MHz.Dacă minutul a ajuns la valoarea 60 sau ora la valoarea 24 .Timer 0Aplicaţie 2.Funcţia care tratează întreruperea externă INT0 are rolul de a incrementa minutul iar funcţia care tratează întreruperea externă INT1 are rolul de a incrementa ora.Dacă folosim ceasul intern şi prescalăm cu maximul adică cu 1024 observăm că noua frecvenţă obţinută este de 3. Programul va avea 3 funcţi de tratare a cererilor de întrerupere.De asemenea nu uitaţi să configuraţi LCD-ul pe portul B şi să activaţi întreruperile externe. frecvenţă care este mai mare decât frecvenţa pe care dorim să o folosim.Aplicaţia o puteţi downloada de la secţiunea Download.1 secunde.adică la 10Hz.la această valoare ea resetându-se şi incrementând variabila secundă(sec) cu o unitate. Aplicaţia realizată fizic o puteţi vedea aici: .Pentru a elimina acest neajuns vom folosi o variabilă suplimentară în program care se incrementează la fiecare 0.În consecinţă vom folosi iar prescalarea cu 1024 însă vom calcula n-ul pentru 10Hz: Pentru a mai diminua din erori vom rotunji n-ul la 98 şi nu 97. variabila care reţine secundele se incrementează iar valoarea variabilei suplimentare va deveni 0.legate la pinii INT0 şi INT1.Momentan vom calcula valorile regiştrilor pentru frecvenţa dorită de 10Hz.două pentru tratarea butoanelor care modifică ora şi minutul şi una pentru tratarea întreruperii generate de timerul 0. Din păcate ceasul nostru nu este unul exact.Funcţia care tratează timerul 0 are rolul de a incrementa o variabilă suplimentară până la valoarea 10 . În cele trei funcţii se are grijă ca după fiecare modificare a variabilelor să se scrie noua stare a ceasului pe LCD.

La scrierea acestui registru trebuie mai întâi să scriem registrul TCNT1H apoi TCNT1L.Citirea se face exact invers citind mai întâi registrul TCNT1L apoi registrul TCNT1H.TCNT1H şi TCNT1L. opreste sistemul de intreruperi #endasm // copiaza TCNT1 in variabila i i = TCNT1. .Timere-le Timer 1 07:11 C.Timerul 1 are mai multe facilităţi.C. unsigned int i.generator de semnale PWM şi numărător de evenimente externe. #asm cli. Un alt registru important pentru setarea caracteristicilor numărătorului este registrul de control TCCR1B: Biţii 7 şi 6 sunt folosiţi pentru captura la intrare .Acest lucru este periculos atunci când o rutină de tratare a unei întreruperi a fost lansată în timpul citirii sau scrierii acestui registru. el putând fi folosit ca şi comparator la ieşire şi la intrare. Momentan ne vom concentra asupra modului standard de folosire ca numărător.Numărătorul liber central este reprezentat de registrul TCNT1: Acest registru este împărţit în doi regiştrii de 8 biţi.Biţii 2:0 sunt cei care ne interesează mai mult deoarece prin ei setăm selecţia sau prescalarea ceasului: CS12 CS11 CS10 Sursă/Prescalare 000-timerul este oprit. bitul 5 este un bit rezervat iar biţii 4 şi 3 sunt folosiţi pentru comparatoare. No comments Trimiteţi prin e-mail Postaţi pe blog! Distribuiţi pe Twitter Distribuiţi pe Facebook Timer-ul 1 funcţionează exact ca timerul 0 singura diferenţă fiind că regiştrii sunt pe 16 biţi. //pornim sistemul de intreruperi SREG = sreg.De exemplu în C codul necesar pentru o citire sigură arată cam aşa: unsigned char sreg.Folosind un compilator în C citirea şi scrierea se face folosind o singură variabilă însă procesorul va face aceste operaţii în doi paşi.Aceste reguli sunt utile pentru păstrarea cât mai mare a preciziei NLC-ului deoarece el se incrementează şi în momentul operaţiei de scriere sau citire. generator de frecvenţă. //salveaza starea registrului SREG sreg = SREG.Pentru a înlătura această problemă înainte de a efectua o operaţie cu regiştrii de 16 biţi se blochează sistemul de întreruperi.

În exemplu următor vom avea un LED conectat la microcontroler care îşi va schimba starea la intervalul de 5 secunde.Timer1.Cererea de întrerupere este marcată în registrul TIFR prin bitul TOV1: Dacă se generează o cerere de întrerupere bitul TOV1 devine 0 el fiind automat setat cu valoarea 1. 111-sursă externă a tactului la pinul T1. 110-sursă externă a tactului la pinul T1.După ce este executată rutina de tratare a întreruperii bitul se setează automat 1. să fie 1.Aplicaţia1.incrementare pe frontul descrescător.incrementare pe frontul crescător. 010-ceasul intern prescalat cu 8.001-ceasul intern fară prescalare.Schema electrică este una simplă: Calculul frecvenţei de numărare a NLC-ului se face ca la timer 1 însă se va lua în calcul că numărătorul este pe 16 biţi: .LED-ul va fi conectat la pinul 0 al portului B.Programul îl puteţi downloada de la secţiunea Download. 100-ceasul intern prescalat cu 256. bitul TOIE. 011-ceasul intern prescalat cu 64. Dacă dorim să folosim şi sistemul de întreruperi va trebui să folosim registrul TIMSK: Pentru ca timerul să genereze o întrerupere la supraîncărcarea registrului TCNT1 trebuie să se permită folosirea sistemului de întreruperi şi trebuie ca bitul 2 din registru. 101-ceasul intern prescalat cu 1024.

. TCNT1L=0x4B.În CodeVision AVR va trebui să aveţi următoarea setare a timerului 1 pe lângă setarea pinului 0 al portului B: Partea în care se întâmplă toată acţiunea este reprezentată de rutina de tratare a întreruperii generate de supraîncărcarea NLC-ului: interrupt [TIM1_OVF] void timer1_ovf_isr(void) { // setarea valorilor NLC-ului #asm cli #endasm TCNT1H=0x4C.

} În această rutină nu facem altceva decât să initializăm TCNT-ul şi să schimbăm valoarea portului B. De obicei intervalul T este dat de 256 de tacte de ceas astfel TPlin sau TGol putând modifica viteza motorului cu pasul de aproximativ 0. Generatorul de semnale PWM 08:04 C.Această perioadă este compusă din timpul în care semnalul este 1 logic(Tplin care se mai numeşte şi factor de umplere) şi timpul în care semnalul este 0 logic(Tgol). Semnale PWM generate de microcontrolerul ATMega8 Microcontrolerul ATMega8 foloseşte pentru generarea semnalelor PWM Timer-ul 1 şi 2 însă momentan ne vom concentra asupra timer-ului 1.#asm sei #endasm //schimbarea starii portului PORTB. Cam atât despre timerul 1 momentan.C.4% la fiecare modificare cu o unitate a registrului de control al factorului de umplere.Aceste motoare permit controlul vitezei prin modificarea tensiunii de alimentare însă viteza se modifică neliniar. -Rregiştrii OCR1A şi OCR1B care contrlează factorul de umplere în felul următor: . PWM generat de Timer-ul 1 Regiştrii care ne interesează pentru setarea generatorului sunt următorii: -Reginstrul TCNT1 care se incrementează la apariţia fiecărui impuls de tact.0 = ~PORTB.0. No comments Trimiteţi prin e-mail Postaţi pe blog! Distribuiţi pe Twitter Distribuiţi pe Facebook Generalităţi Semnalele PWM sunt folosite în general pentru a controla viteza unui motor de curent continuu.intern sau extern. prescalat sau nu.Pentru a controla această viteză liniar s-a recurs la metoda de control prin semnale PWM.Semnalele PWM au următoarea formă: În schema de mai sus observăm că semnalul este de perioadă T.

atunci valoarea lui OCR1x va fi 128.TCNT1<=OCR1x-1 logic la ieşire.În schemă mai observăm că numărarea se face în două sesuri. Biţii FOC1A.Comparatoarele sunt oprite 0 1 .TCNT1<=OCR1x-0 logic la ieşire. Biţii WGM13 şi WGM12 din TCCR1B împreună cu biţii WGM11 şi WGM10 din TCCR1A sunt folosiţi pentru alegerea modului de funcţionare a timerului: Totuşi cele mai folosite moduri PWM sunt primele 3 care permit numărarea pe 8. -Registrul TCCR1B: Biţii ICNC1 şi ICES1 sunt folosiţi pentru captura la intrare iar bitul 5 este un bit rezervat.6 şi 7 au următoarea semnificaţie: COM1A1/COM1B1 COM1A0/COM1B0 0 0 .Observăm că timpul în care semnalul de ieşire este 1 este dat de registrul OCR1x.Atunci când sunt .9 sau 10 biţi.Setarea modului PWM se face prin biţii WGM13:0 după cum vom vedea mai jos. lucru pe care l-am mai discutat la prezentarea timerului 1.Comparatoarele sunt active însă depind de biţii WGM13:0 10 .5.Prin biţii 2:0 setăm prescalarea.Dacă folosim de exemplu numai TCNT1L numărătorul va număra de la 0 la 255 şi dacă dorim ca factorul de umplere să fie 50%. FOC1B sunt folosiţi pentru modul rapid aşa că îi vom seta 0. 11 .crescător şi descrescător. -Registrul TCCR1A: Biţii 4.TCNT1>OCR1x -0 logic la ieşire. Un lucru important pe care trebuie să îl cunoaşteţi când folosiţi generatoarele PWM sunt pinii de ieşire PWM notaţi cu OC1A şi OC1B în cazul microcontrolerului ATMega8.TCNT1>OCR1x -1 logic la ieşire.

Acest osciloscop se găseşte în Poteus la secţiunea de unelte(Virtual Instruments Mode) şi are numele OSCILLOSCOPE. modul PWM pe 8 biţi. 1 logic.Codul programului îl puteţi descărca de la secţiunea Download -PWM -Aplicaţie 1. . Schema electrică este următoarea: Observăm că la pinii OC1A şi OC1B avem legate 2 LED-uri iar în paralel cu ele un oşciloscop prin care vom vizualiza semnalele. Configurarea regiştrilor va fi următoarea: TCCR1A=0b10100001. adică 128 iar valoarea lui OCR1B este 25% adică 64. iar la pinul OC1B dorim să avem doar 25% din interval 1 logic. OCR1A =125.Pentru ca efectul să poată fi urmărit vizual vom prescala ceasul cu 1024.Vom alege ca semnalul să fie 1 logic când TCNT1<=OCR1x şi 0 altfel iar modul de operare să fie primul. OCR1B =64.Pentru uşurinţă vom folosi modul pe 8 biţi iar perioada T se va lua suficient de mare astfel încât să se poată observa comutarea. TCCR1B=0b00000101.Valoarea lui OCR1A este 50% din valoarea perioadei. În următorul exemplu vom dori ca la pinul OC1A să avem 50% din perioada T.folosiţi pentru acest scop ei trebuiesc setaţi ca pini de ieşire ai portului.

Configurarea şi funcţionarea generatorului PWM este asemănătoare cu cea din Timer-ul 1 regiştrii având formă şi nume diferit.perioada semnalului putând fi urmărită pe oşciloscopul simulării: PWM generat de Timer-ul 2 Timer-ul 2 este asemănător cu timer-ul 1 diferenţa majoră fiind că el este doar pe 8 biţi şi că avem doar un singur canal de comparare la ieşire(OC2).Configurarea în Code Vision AVR a timerului este următoarea: Foarte important este să nu uitaţi să setaţi pinii 1 şi 2 ai portului B ca pini de ieşire.Regiştrii pe care îi vom folosi sunt următorii: -Registrul TCNT2 . -Registrul TCCR2 care are rolul de a controla modul de funcţoinare a timerului 2: .După generare şi compilare programul funcţionează exact cum am dorit.registrul care numără fiecare impuls de ceas şi care joacă rolul de numărător liber central al timerului.

1 1 – Funcţionare ca PWM rapid. Pinul prin care preluăm semnalul PWM este plasat pe portul B la pinul 3: Următorul exemplu are ca scop modificara factorului de umplere a semnalului în funcţie de anumite semnale de intrare. 001-Frecvenţa ceasului intern.1 logic la ieşire.Frecvenţa ceasului intern prescalată cu 256.1 şi 0 sunt folosiţi la prescalare timerului: CS22 CS21 CS20 000-Timer oprit.Bitul 7 nu îl vom folosi pentru setarea generatorului aşa că îl vom seta 0. 11-TCNT2<=OCR2-0 logic la ieşire. Biţii 2.numărarea se face în două sensuri.vom prescala ceasul 1024 şi vom alege următoarea regulă : TCNT2<=OCR2. 010. -Registrul OCR2. 100. 10-TCNT2<=OCR2-1 logic la ieşire. 101.TCNT2>OCR2 -1 logic la ieşire.TCNT2-ul numără într-un singur sens. 0 1 – Funcţionare ca PWM.Frecvenţa ceasului intern prescalată cu 32. Schema electrică este următoarea: .Frecvenţa ceasului intern prescalată cu 1024. 0 1-Combinaţie rezervată. 111.Frecvenţa ceasului intern prescalată cu 8.TCNT2>OCR2 -0 logic la ieşire.Pentru reglare vom folosi 3 butoane legate la primi 3 pini ai portului C în felul acesta având 8 trepte de reglare a factorului de umplere.Regiştrii vor avea următoarele valori: TCCR2 = 0b01100111. Biţii 5 şi 4 setează modul de funcţionare al comparatorului: COM21 COM20 –Modul PWM 00-Comparatorul dezactivat. 110.Frecvenţa ceasului intern prescalată cu 64.Valoarea maximă pe care o poate avea POTRC-ul este 7 iar dacă împărţim 256 la 7 obţinem aproximativ 36 deci valoarea lui OCR2 va fi PORTC*36. Bitul 6 şi 3 (WGM20 şi WGM21) sunt folosiţi la setarea modului de funcţionare a timerului: WGM21 WGM20 0 0 – Funcţionare normală. Codul programului şi simularea o puteţi downloada de la secţiunea Download -PWM -Aplicaţie 2. OCR2 = 0. 1 0 – Funcţionare ca CTC. modul PWM de numărare în ambele sensuri .Vom folosi al doilea mod. este registrul prin care setăm factorul de umplere al semnalului generat.TCNT2>OCR2 -0 logic la ieşire. 011.Frecvenţa ceasului intern prescalată cu 128.

Pe lângă acestea trebuie să configuraţi şi timerul 2 în felul următor: Dacă rulaţi simularea veţi putea modifica factorul de umplere în funcţie de combinaţia celor 3 butoane. No comments .C. După informaţiile prezentate mai sus observăm că microcontrolerul ATMega 8 poate genera 3 canale PWM în felul acesta putând controla vitezele în mod diferit a 3 motoare de curent continuu.Când configuraţi proiectul în Code Vision AVR trebuie să aveţi grijă ca primii 3 pini ai PORTC-ului să fie configuraţi ca pini de intrare iar pinul 3 al PORTB-ului să fie configurat ca pin de ieşire. Cam atât momentan despre generatorul PWM. Convertorul Analog-Digital(AD) 09:59 C.

pinul PC1 0010– ADC2 .3V 1111– GND Pinul 5. astfel se folosesc ambii regiştrii pentru memorare în felul urmăror: . acest lucru făcându-se prin pinul AREF.internă egală cu cu tensiunea de alimentare sau internă egală cu 2. 11.Trimiteţi prin e-mail Postaţi pe blog! Distribuiţi pe Twitter Distribuiţi pe Facebook Convertorul Analog Digital.pinul PC2 0011– ADC3 . 01.56V cu rezistenţă şi condensator la pinul AREF(R=1K şi C=14pF ).Convertorul microcontrolerului ATMega8 permite mai multe moduri de alegere a referinţei de tensiune cum ar fi o referinţa externă prin pinul AVCC.Referinţă internă ca la combinaţia 0 1 însă reversată.Referinţă externă la pinul AREF. 10. are rolul de a converti valorile semnalelor analogice în valori numerice.după cum îi spune şi numele.ADLAR are rolul de a selecta modul de scriere a valorii citite în regiştrii ADCL şi ADCH.Semnalele analogice care intră în convertor pot proveni de la diverse dispozitive însă în cele mai multe cazuri acestea provin de la diverşi senzori(senzori de lumina.Aceşti regiştrii sunt de 8 biţi însă rezutatul este pe 10 biţi.56V.Timpul de citire poate fi şi el prescalat iar numărul de tacte necesare pentru citire este 13.convertorul trebuie legat şi la masă.pinul PC4 1110– 1.Referinţă internă VCC cu rezistenţă şi condensator la pinul AREF(R=1K şi C=14pF ). temperatura.Rezultatatul citirii va fi depus în regiştrii de 8 biţi ADCH şi ADCL.etc.pinul PC3 0100– ADC4 .La un moment dat se poate citi doar un singur canal.pinul PC0 0001– ADC1 . Pentru a putea folosi un convertor mai întâi trebuie setat pragul minim şi maxim de tensiune la care el funcţionează.Convertorul acestui chip are 6 canale de intrare care se găsesc pe portul C şi sunt notate cu ADC(ADC0-ADC5). Biţii 2-0 (MUX3-MUX0) au rolul de a selecta canalul de unde va fi citit semnalul: MUX3 MUX2 MUX1 MUX0 0000– ADC0 . Acest convertor stochează valoarea tensiunii numeric într-un registru de 10 biţi.). Selecţia referinţei şi a canalului se face prin registrul ADMUX care are următoarea formă: Biţii 7 şi 8 (REFS1 şi REFS0) folosesc la selecţia referinţei astfel: REFS1 REFS0 00.Referinţă internă de 2.În momentul folosirii .

Dacă s-a trimis o cerere de întrerupere el devine 0 până când se execută rutina de tratare. periodică sau nu.Dacă citirea se face periodic atunci nu ne rămâne decât să citim valoarea .registru în care trebuie să avem mare grijă ca cel mai semnificativ bit să fie setat.Acest bit rămâne setat până când se realizează conversia. Pentru generarea unui semnal de întrerupere în momentul terminării conversiei trebuie ca bitul ADIF să fie 1.Dacă dorim să citim valoarea unei tensiuni la un moment dat se setează bitul ADSC=1.modul de citire şi canalul şi apoi se setează ADCSRA .Dacă ADLAR = 1 atunci primii 8 cei mai semnificativi biţi sunt reţinuţi în ADCH iar restul de 2 biţi sunt reţinuţi în ADCL. Prin bitul 5. este folosit pentru a porni convertorul.setând referinţa. după conversie valoarea lui va deveni 0.ADPS2-ADPS0 au rolul de a prescala timpul de citire a tensiunii astfel: ADPS2 ADPS1 ADPS0 Prescalarea frecvenţei interne 000 2 001 2 010 4 011 8 100 16 101 32 110 64 111 128 Algoritmul de setare şi citire a convertorului este următorul: În partea de setare a programului se setează registri ADMUX.bitul ADEN are rolul de a permite folosirea convertorului astfel dacă ADEN = 1 convertorul poate fi folosit.ADSC. Bitul 6.Bitul ADIE are valoarea 1 atâta timp cât nu a fost trimis nici un semnal de întrerupere. caz în care putem citi doar registrul ADCH. se setează modul de citire al tensiunii.astfel dacă ADRF=1 convertorul citeşte repetat valoarea tensiunii iar dacă ADRF = 0 citirea se face doar când ADSC = 1.Dac ă bitul ADLAR = 0 avem primul mod de reţinere în care primii doi cei mai semnificativi biţi sunt reţinuţi în ADCH iar restul de 8 biţi sunt reţinuţi în ADCL.ADRF.La terminarea execuţiei rutinei ADIE ia valoarea 1. Ultimii 3 biţi.Modul doi de reţinere se poate folosi atunci când dorim ca rezultatul să fie returnat pe 8 biţi. Controlul convertorului se face prin registrul ADCSRA care are următoarea formă: Cel mai seminiciativ bit. În partea de ciclare infinită trebuie să vedem cum am configurat citirea.

Vcit reprezintă valoarea returnată de convertor iar Vref tensiune de referinţă. -citim valoarea convertorului.Dacă nu. Calcularea tensiunii efective se face după următoarea formulă: Unde Tens reprezintă tensiunea efetivă. Înainte de scrierea programului . citirea se face conform paşilor: -pornim citirea:ADCSRA =ADCSRA | 0x40.Precizia citirii se calculează în felul următor: Unde P este precizia şi Vref este tensiunea de referinţă care se poate împărţi la 1024 sau 256 în funcţie de numărul de biţi ai registrului de stocare. la partea de setarea a generării codului vom avea .convertorului. -aşteptăm să se termine citirea: while(ADCSRA | 0x40 == 1). În exemplul următor vom citi valoarea unei tensiuni şi o vom afişa pe un LCD. Valoarea returnată va fi un număr cuprins între 0 şi 1024 dacă citirea se face pe 10 biţi sau între 0 şi 256 dacă citirea se face pe 8 biţi.Schema electrică este următoarea: Progamul îl puteţi downloada de la secţiunea Download -Convertorul A/D -Aplicaţie 1.

sprintf(linie1. valoare[1] = '. După generare. //copiem valoarea in sirul linie1 //afisam rezultatul pe LCD lcd_clear().următoarea setare: Important aici este să nu uitaţi partea de setarea a LCD-ului pe portul D.0). Adică se permite folosirea convertorului. lcd_gotoxy(0. delay_ms(200). //asteptam 2 milisecunde Aici microcontrolerul începe cu citirea tensiunii apoi se calculează valoarea efectivă a .se activează permisia trimiterii cererii de întreruperea la terminarea citirii şi se prescalează ceasul cu 2."V=%s". //pornim conversia while(ADCSRA&0x40). setările dinaintea părţii de ciclare vor fi următoarele: ADMUX=0x00.se citesc 10 bţi din partea stângă a registrului ADCH şi se selectează canalul 1. valoare[2] = (adc_data/10)%10+48. valoare[4] = '\0'. ADCSRA=0x89. lcd_puts(linie1). Adică referinţa va fi externă la pinu AREF.'.valoare). //astempam ca citirea sa se finalizeze adc_data = (adc_data*5*100)/1023. Codul din bucla infinită este următorul: ADCSRA |= 0x40. //calculam valoarea tensiunii //transformam valoarea obtinuta in sir valoare[0] = adc_data/100+48. valoare[3] = adc_data%10+48.

Aţienie.Acest mod de afişare a informaţiilor de ieşire ale unui microcontroler nu este întotdeauna mulţumitor deoarece există cazuri în care dorim să afişăm un număr sau un text.Avem nevoie de această funcţie deoarece LCD-ului îi trebuie un timp de iniţializare după ce a fost pus în funcţiune.Pe lângă linile de date vom avea nevoie şi de 3 linii de control: -E(Enable) care permite sau nu transmiterea de date şi comenzi.RS=1. void lcd_gotoxy(unsigned char x.După aceste operaţii se transformă valoarea din long în şir de caractere după care se afişează pe ecran rezultatul. 1 comment Trimiteţi prin e-mail Postaţi pe blog! Distribuiţi pe Twitter Distribuiţi pe Facebook Până acum ieşirile microcontrolerului reprezentau nişte LED-uri care puteau lua două valori. Transferul de date între microcontroler şi LCD se poate face pe 4 sau 8 biţi printr-un bus de date.C.Acesta se alimentează cu 5 volţi şi permite scrierea caracterelor alfanumerice principale.0 fiind pentru scrierea datelor iar 1 fiind pentru citirea datelor din LCD.Setând acestă linie 1 poate începe schimbul de date şi comenzi între LCD şi microcontroler. x reprezintă coloana iar y reprezintă linia.Dacă ia valoarea 0 înseamnă că trimitem LCD-ului o instrucţiune iar dacă scriem valoarea 1 înseamă că trimitem date.Dacă avem mai multe . în cazul nostru 16.y.y curentă. -R/W (Read/Write) are rolul de a stabili direcţia datetelor. lcd_columns reprezentând numărul de coloane ale LCD-ului.tensiunii. 1 sau 0.Acest lucru se poate realiza cu ajutorul unui afişaj LCD. Toate aceste lucruri sunt mascate în CodeVision AVR singurul lucru pe care trebuie să îi facem este să setăm la începutul proiectului portul prin care realizăm conexiunea LCD-ului cu microcontrolerul şi să includem biblioteca lcd.R/W=0. De exemplu pentru scrierea unor date în LCD trebuie ca: E=1.Dimensiunea LCD-ului pe care îl vom folosi în acest tutorial este de 2 linii şi 16 coloane şi se numeşte LM016L. void lcd_putchar(char c) – afişează un caracter la poziţia x.Se foloseşte trasferul de date pe 4 biţi deoarece această metodă salvează 4 pini ai microcontrolerului. -RS(Register Selec) foloseşte la selectarea regiştrilor interni ai LCD-ului. Afişajul LCD 15:20 C. void lcd_clear(void) – şterge tot ce este scris pe LCD şi duce cursorul la linia şi coloana 0. void _lcd_ready(void) – aşteaptă până când lcd-ul este gata să primească date.Legarea pinilor unui port cu pinii LCD-ului se face în felul următor: RS (pin4)--------bit 0 RD (pin 5)--------bit 1 EN (pin 6)--------bit 2 DB4 (pin 11)-----bit 4 DB5 (pin 12)-----bit 5 DB6 (pin 13)-----bit 6 DB7 (pin 14)-----bit 7 Funcţiile cele mai utilizate pentru controlul şi scrierea LCD-ului sunt următoarele: unsigned char lcd_init(unsigned char lcd_columns)– realizează iniţializarea LCD-ului. unsigned char y) – setează cursorul la poziţia x.h.

void lcd_puts(char *str) .y curentă.la partea de setare din wizard trebuie să mergem la panoul LCD . //afisam primul mesaj .Schema electrică este următoarea: În cazul de faţă folosim portul D pentru transmisia de date şi comenzi. să alegem portul D şi să selectăm numărul de coloane al LCD-ului precum în figura de mai jos: În program nu vom face altceva decâ să afişăm nişte caractere înainte de intrarea în bucla infinită while: lcd_init(16).afişează un şir de caractere începând de la poziţia x. //initializam LCD-il _lcd_ready().4).La crearea proiectului în CodeVision AVR .Codul şi schema aplicaţiei o puteţi downloada de la secţiunea Download-LCD-Aplicaţie 1.comenzi de acest gen nu însemnă că va scrie caracterul unul peste altul şi va scrie pe coloana sau linia următoare. //asteptam ca lcd-ul sa poata primi date lcd_gotoxy(1. //megem la coloana a 2-a pozitia 5 lcd_puts(mesaj1). Pentru a vă face o idee cam cum se conectează şi scrie pe LCD vom crea un exemplu simplu în care vom avea microcontrolerul ATMega8 şi un LCD LM016.

la începutul funcţiei main sau în exterior ca variabile globale.RS-422 sau RS-485 însă în aplicaţiile noastre vom folosi doar standardul RS-232 pentru comunicarea cu PC-ul.Pinul prin care un dispozitiv primeşte date este pinul RX.Slave-ul va trebui configurat astfel încât să primească cuvinte care au acelaş format cu cele generate de master şi să funcţioneze la aceeaşi frecvenţă. unitate care reprezintă numărul de biţi transmişi într-o secundă.Schema de principiu este următoarea: Dispozitivu l care transmite date se numeşte master iar cel care primeşte se numeşte slave. //afisam caracterul y lcd_putchar(80). //afisam caracterul cu codul 80(P) Puteţi observa că pentru afişarea unor şiruri de caractere am folosit o variabilă de şir. pe o legătură realizându-se transmisia iar pe alta recepţia. No comments Trimiteţi prin e-mail Postaţi pe blog! Distribuiţi pe Twitter Distribuiţi pe Facebook Prezentare generală USART(Universal synchronous/asynchronous receiver/transmitter) este un standard de comunicare serială între diverse dispozitive cum ar fi comunicarea între calculator(prin portul serial COM) şi alte dispozitive. Funcţionarea fizică a aplicaţiei o puteţi vedea aici: USART 11:13 C. adică există un trasmiţător şi un receptor sau invers. deoarece compilatorul nu ne lasă să scriem direct în funcţie sirul. Viteza de transmisie a datelor se măsoară in BAUD . unsigned char* mesaj3 = "Afisarea a 3 caractere:". //stergem caracterele de pe lcd lcd_puts(mesaj2).delay_ms(2000).Dacă se foloseşte modul sincron pe lâng[ legăturile de transmisie a datelor se mai foloseşte o legătură prin care se stabileşte acelaş semnal de tact între dispozitive.C. //asteptam o secunda lcd_clear().Această viteză trebuie să fie egală între dispozitivele care comunică . //afisam caracterul x lcd_putchar('y'). mesaj.Declararea şirurilor de caractere se poate face în program .De obicei masterul stabileşte formatul cuvântului şi frecvenţa ceasului iar datele furnizate se vor obţine la pinul TX.În programul nostru avem: unsigned char* mesaj1 = "Test LCD". //asteptam 2 secunde lcd_clear().Acesta se poate folosi pentru comunicare în conjuncţe cu standardele RS-232. unsigned char* mesaj2 = "LCD curatat". //afisam mesajul 3 lcd_putchar('x').Comunicarea serială presupune folosirea unei singure legături dacă ea este unidirecţională. //afisam mesajul 2 pe linia si coloana 1 delay_ms(1000).Dacă este bidirecţională avem nevoie de două legături . //stergem caracterele de pe lcd lcd_puts(mesaj3).

Schimbul de date se face prin doi regiştrii. La configurarea a două dispozitive care vor comunica serial asicron trebuie să avem grijă ca viteza de transfer să fie egală la transmisie şi recepţie şi să avem aceeaşi lungime a cuvântului de date.Pentru o mai bună securitate în transmisie se poate seta la sfârşitul cuvântului de date un bit de paritate care verifică paritatea biţilor de date. bitul de paritate şi bitul/biţii de final. Momentan ne vom concentra pe transmisia asincronă deoarece ea este cea mai folosită la comunicarea între dispozitivele periferice şi PC. La transmiterea sau recepţia a mai multor cuvinte consecutive trebuie verificat dacă USART-ul a realizat operaţia completă de trimitere sau citire.Transmiţătorul sau receptorul sunt libere doar atunci când s-au transmis biţii de stop şi sunt în stare Idle.USART-ul va trece automat conţinutul lui UDR în registrul serial apoi îl va transmite pe linia de legătură celuilalt dispozitiv care va prelua datele tot în registrul serial al cărui conţinut va fi transmis registrului UDR. altfel poate apărea o altă eroare de transmisie generată de data asta de partea soft. registrul serial va verifica dacă transmisia este corectă şi dacă da datele .Alte erori pot fi generate pe linile de transmisie.De exemplu pentru transmiterea unui caracter char pe 8 biţi trebuie să scriem caracterul în UDR. Cuvântul care este trimis este format din două părţi . Microcontrolerul ATMega8 poate trimite următorul format de cuvânt: Pri mul bit St reprezintă bitul de start. Principala sursă de eroare poate apărea atunci când configurarea între dispozitive nu este făcută corect. stare care este reprezentată de 1 logic pe linile de conexiune. una prin care trimitem şi una prin care primim datele.De asemenea trebuie totuşi să stabilim dacă folosim verificarea parităţii şi dacă folosim unul sau doi biţi de stop. va pune pe lângă date şi bitul de start .Registrul serial.având doar două legături. Transmisia asincronă După cum am văzut mai sus pentru ca această transmisie să fie bidirecţională trebuie să folosim două conexiuni.În ATMega8 datele se scriu sau se citesc din registrul UDR.Următorii biţi sunt biţii de date care pot avea o lungime între 5 şi 8 biţi iar la sfârşit avem un bit de stop care întodeauna trebuie să fie 1. aceasta fiind o problemă de incompatibilitate în comunicare.La transmisia asincronă pot apărea diverse erori deoarece frecvenţele de tact pot fi puţin diferite chiar dacă ele sunt setate aparent egal. unul în care se înscriu datele şi unul de şiftare prin care se transmite cuvântul. ele putând fi detectate prin bitul de paritate sau prin biţii de stop.dacă dispozitivul este configurat ca transmiţător.Sfârşitul cuvântului poate fi reprezentat de unul sau doi biţi care trebuie să aibă valoarea 1. o parte care reprezintă datele iar altă parte care reprezintă codul de verificare: Orce cuvânt începe cu un bit de start care trebuie să fie 0.Acest neajuns este înlăturat la transmisia sincronă deoarece semnalul de tact generat de master este transmis slave-ului prin legătura XCK.Dacă dispozitivul este configurat ca receptor.Lungimea cuvântului de date poate fi cuprinsă între 5 şi 9 biţi.serial.

Aceşti 3 biţi pot genera întreruperi care pot fi tratate în rutine speciale . Bitul 2 – PE – are rolul de a detecta eroarea de paritate.FE este 1 dacă s-a semnalat o astfel de eroare şi 0 dacă nu avem o eroare de acest fel.indică starea registrului de recepţiei.0 întreruperea nu .De exemplu la recepţie poate apărea o astfel de eroare dacă UDR şi registrul serial este plin şi alt caracter este pe cale de a fi primit.Dacă este 1 UDR poate fi scris.cuvântului vor fi copiate în UDR.Dacă încă se mai primesc date valoarea lui este 1 iar dacă recepţia a fost efectuată complet valoarea lui este 0.Detectează dacă există erori de suprascrierea USAR-tului. -Registrul UCSRA: Bit ul 7 –RXC. Bitul 5 – UDRE – indică dacă UDR poate fi citit sau scris. dacă este 0 nu se pot efectua operaţii cu acest registru. Bitul 6 –TXC.Dacă s-a detectat o astfel de eroare ia valoarea 1 iar dacă nu valoarea lui va fi 0. datele sunt stocate în TXB iar dacă se realizează recepţia datele se găsesc în RXB.Acest bit trebuie să aibă întotdeauna valoarea 0 dacă este folosit modul sincron.Dacă încă se mai transmit date valoarea lui este 1 iar dacă transmisia a fost efectuată complet valoarea lui este 0.Dacă totul este în regulă atunci valoarea lui FE va fi 0.Dacă acest/aceşti biţi au o valoare diferită de 1 atunci bitul FF ia valoarea 1. Bitul 3 –DOR . Bitul 4 – FE – Detectează dacă există erori la transmiterea cuvântului verificând bitul/biţii de final. Bitul 1 – U2X – Acest bit este 1 dacă dorim să dublăm viteza de transmisie în modul asicron şi 0 dacă se foloseşte viteza normală.Se setează 1 dacă se foloseşte comunicarea multiprocesor şi 0 dacă se foloseşte comunicarea uniprocesor.In exemplele ce vor urma îl vom seta ca 0. Regiştrii folosiţi în ATMega8 pentru comunicarea serială sunt următorii: -Registrul UDR care are rolul de a stoca datele necesare pentru transmisie sau recepţie: Dacă se realizează transmisia. -Registrul UCSRB: Bitul 7-RXCIE – 1 setează generarea unei întreruperi la terminarea recepţiei. Bitul 0 – U2X.indică starea registrului de transmisiei.

-Bitul 5 şi 4 –UPM1 şi UPM0 – Se folosesc pentru selecţia parităţii: UPM1 UPM0 00 .este flosită.Valorile pe care le poate lua sunt următoarele:0 – se foloseşte frontul crescător.RXEN – 1 setează USART-ul ca receptor. -Biţii 2 şi 1– UCSZ1 şi UCSZ0. 001 – 6 biţi. -Registrul UCSRC: -Bitul 7 –URSEL. -Bitul 5-RXCIE – 1 setează generarea unei întreruperi atunci când registrul UDRIE poate fi folosit.UCSZ2 – se foloseşte împreună cu o parte din biţii registrului UCSRC după cum vom vedea mai jos. 10 .se folosesc împreună cu UCSZ2 din UCSRB pentru a seta lungimea cunvântului de date: UCSZ2 UCSZ1 UCSZ0 Lungimea Cuvântului 000 – 5 biţi. -Bitul 3. -Bitul 1 – RXB8 – este al 9-lea bit din schimbul de date pe 9 biţi şi se foloseşte la recepţie. -Bitul 6 –UMSEL-Prin acest bit se setează modul de funcţionare al USART-ului:1 dacă funcţionează în modul sincron şi 0 dacă funcţionează în modul sincron. .se foloseşte pentru selecţia regiştrilor astfel:1 dacă se lucrează cu registrul UCSRC şi 0 dacă se lucrează cu registrul UBBRH. -Bitul 4. -Bitul 2.În modul asincron acesta se setează 0. -Bitul 6-RXCIE – 1 setează generarea unei întreruperi la terminarea transmisiei. 110 – Combinaţie rezervată.Se foloseşte bitul de paritete ca bit impar. 111 – 9 biţi.Combinaţie rezervată. 011 – 8 biţi. 101 – Combinaţie rezervată.Nu se foloseşte bitul de paritate. 010 – 7 biţi.0-se setează un singur bit de stop.0 întreruperea nu este flosită.TXEN – 1 setează USART-ul ca Transmiţător. -Bitul 0 – UCPOL-Se foloseşte pentru modul sincron şi setează ce front al semnalului de pe linia XCK va fi folosit în transmisie. 01 .se foloseşte pentru a seta numărul biţilor care reprezintă sfârşitul cuvântului: 1se setează doi biţi de stop. 100 – Combinaţie rezervată. 11 . 1 se foloseşte frontul descrescător. -Bitul 0 – TXB8 – este al 9-lea bit din schimbul de date pe 9 biţi şi se foloseşte la transmisie. -Bitul 3 –USBS.0 întreruperea nu este folosită.Se foloseşte bitul de paritete ca bit par.

vom folosi un singur bit de stop iar viteza de transmisie va fi de 4800 baud.13.f_int reprezită frecvenţa internă a procesorului iar UBBR este valoarea setată în registru.12 sunt nişte biţi rezervaţi nefolosiţi în acest microcontroler. Schema electrică a aplicaţiei este următoarea: .Datele pe care le va primi microcontrolerul le vom afişa pe un LCD. UBRRH=0x00. Programul îl puteţi downloada de la secţiunea Download -USART -Aplicaţie 1.Citirea şi trimiterea de date de la PC la microcontroler o puteţi face cu un program ca HiperTerminal.-Registrul UBRR – Acest registru se foloseşte pentru a seta viteza de transmisie a datelor. UBRRL=0x0C. -Biţii 11:0 sunt folosiţi pentru a seta viteza de transmisie a datelor. -Bitul 15 – URSEL – trebuie să fie 0 atunci când se efectuează operaţii cu acest registru. UCSRC=0x86. Înainte de a începe transmisia toate aceste setări vor fi făcute în regiştrii USART-ului după cum urmează: UCSRA=0x00.lungimea cuvântului de date va fi de 8 biţi .Totuşi setarea se face doar cu biţii cei mai semnificativi.Viteza de transmisie a datelor se calculează după formula: Unde BAUD reprezintă viteza de transmisie măsurată în Baud. UCSRB=0x98. -Biţii 12. 11:8. Eroarea la transmisie se calculează după formula: În tabelul de mai jos putem urmări ce influenţă are frecvenţa asupra erorii la transmisie: Următorul exemplu are ca scop schimbul de date între microcontrolerul ATMega8 şi PC.Transmisia de date se va face asincron .

Afişarea . Observăm că trimiterea de date se face foarte simplu cu ajutorul funcţiei printf().13). printf("%c". pinul 1 al portului D ca ieşire şi USART-ul după cum urmează: Pentru recepţie am folosit întreruperea deoarece dorim să afişăm caracterul pe LCD imediat ce el a fost primit. La secţiunea de generare a codului trebuie să setaţi LCD-ul pe portul D. pinul 0 al portului D ca pin de intrare. }. printf("%c". În partea de ciclare infinită a programului vom trimite date PC-ului: while(1) { //trimitem toate caracterele ASCII catre computer caracter ++.Pentru a simula PC-ul am folosit o unealtă oferită de Proteus numită Virtual Terminal. delay_ms(150).Aceasta împreună cu oşciloscopul se găsesc în partea dreaptă a ferestrei la butonul Virtual Instruments Mode.caracter).

Dacă s-a ajuns să se scrie 16 caractere pe LCD . nr_caractere = 0. } Afişarea se face pe o singură linie.caracterelor pe LCD se face în rutina de tratare a întreruperii generate de recepţia datelor după cum urmează: nr_caractere++. pentru a se putea realiza conexiunea este nevoie de un integrat MAX232 care face legătura între microcontroler şi cablu serial astfel: Momentan cam atât despre USART. lcd_putchar(data). LCD-ul este curăţat. . Fizic . if(nr_caractere > 15) { lcd_clear().Dacă simularea funcţionează cum trebuie ar trebui să vă afişeze cam aşa: Pentru a trimite date microcontrolerului trebuie să daţi click pe Virtual Terminal şi să tastaţi caractere. adică să se completeze prima linie.

No comments Trimiteţi prin e-mail Postaţi pe blog! Distribuiţi pe Twitter Distribuiţi pe Facebook Structura unui program scris pentru un microcontroler este puţin diferită de structura programelor scrise pentru un calculator de uz general. dacă este nevoie . No comments Trimiteţi prin e-mail Postaţi pe blog! Distribuiţi pe Twitter Distribuiţi pe Facebook Copierea programului în memoria flash a microcontrolerului se face cu ajutorul programului PonyProg .Structura unui program scris pentru un microcontroler 12:09 C. restul fiind partea de setare.Apoi urmează funcţia main.Atenţie mare.apoi se fac setările diferitelor funcţii ale microcontrolerului.C.În ultima parte a funcţiei main se va crea o buclă infinită lucru care în mod normal nu ar fi dorit în programele scrise pentru calculatoarele personale.Următoarea secţiune va fi reprezentată de declararea variabilelor globale şi de declararea/definirea funcţiilor program.h› //declararea/definirea functiilor si variabilelor globale void main(void) { //declarea variabilelor locale //realizarea setarilor microcotrolerului prin registrii de setare while(1) { //partea de prelucrare a datelor } } Când microcontrolerul este pornit mai întâi se va realiza setările funcţiilor chip-ului prin regiştrii de setare apoi el va cicla codul din bucla while până când apare un eveniment neaşteptat cum ar fi oprirea sursei de alimentare sau apariţia unei întreruperi.Înainte de a deschide programul şi de a alimenta placa se vor face conexiunile între pinii microcontrolerului . Încărcarea programului în microcontroler 11:30 C. program pe care puteţi să îl descărcaţi de la secţiunea Download.În această buclă are loc întreaga parte de prelucrare a datelor.De asemenea wizardul oferă şi explicaţii referitoare la setările pe care le-a realizat. Avatajul folosirii wizardului din CodeVision AVR este că el generează cod pentru structura de mai sus .C. funcţiile microcontrolerului nu însemnă acelaş lucru cu funcţiile programului. funcţia principală din program.setările micorcontrolerului putând fi făcute vizual. cea care este prima executată la rularea programului.De exempu pentru chipul ATMega8 programul ar trebui să urmeze modelul: //partea de includere a bibliotecilor utilizate #include ‹mega8.În această funcţie mai întâi se declară variabilele locale.Primele linii dintr-un program vor reprezenta bibliotecile pe care le utilizăm în cadrul aplicaţiei.

Portul COM1 îl găsiţi în spatele calculatorului el arătând cam aşa: Acum când toate conexiunile sunt făcute puteţi alimenta placa şi porni programul PonyProg.PB3 la MOSI.şi pinii programatorului după schema următoare: Pinii microcontrolerului la care va trebui să legaţi pinii programatorului îi veţi putea găsi în schema de mai jos: După cum vedem pinul PC6 trebuie legat la RESET. După ce aţi făcut toate conexiunile urmează să conectăm placa la portul serial.Acest lucru se face printr-un cablu de legătură serial.PB4 la MISO.PB5 la SCK. +5V la tensiunea de alimentare iar GND la masă. .

Următorul pas este selectarea chip-ului pe care vom încărca programul.După ce aţi deschis programul va trebui să îl configuraţi pentru a putea face legătura serială cu placa. . el generând codul într-un astfel de director.Aici am folosit numele directorului Exe deoarece am presupus că programul a fost compilat cu Code Vision AVR . Acum că setările sunt făcute urmează să copiem programul nostru in memoria microcontrolerului.Pentru configurare megeţi în meniu la Setup>Interface Setup.hex şi aleagând fişierul din directorul Exe corespunzător.Mai întâi va trebui să încărcăm codul în PonyProg apăsând File>Open Program Flash File selectând extensia *. depinde pe care doriţi să îl folosiţi).Această setare se face din bara plasată sub meniu.Aici selectaţi modul Serial şi COM1(sau COM2 .

În prima casetă selectaţi AVR micro iar în a doua Atmega8. însă nu foarte mari.La final placa ar trebui să arate cam aşa: . una uşoară şi mai scumpă şi una grea şi puţin mai ieftină.După această operaţie ea trebuie curăţată cu spirt industrial. fiecare placă putând fi adaptată pentru diferite sarcini.Toate aceste operaţii sunt necesare deoarece pe placă vom imprima un circuit.Dacă totul a decurs cum trebuie veţi primi un mesaj cum că totul este ok. Realizarea fizică a aplicaţiei 08:34 C.Mai aveţi nevoie şi de o bucată de smirghel fin cu care să smirgheluiţi placa foarte bine.Totuşi unele diferenţe vor exista între posibilităţile pe care le oferă placa pe care sunt simulate aplicaţiile în acest tutorial şi plăcile achiziţionate din magazin.Prima ar fi să achiziţionaţi de la o firmă de componente electronice o placă de dezvoltare gata făcută pe care să puteţi monta un microcontroler ATMega8.C. Prima dată aveţi nevoie de schema de imprimare şi o placă de plastic care are una sau două pelicule( faţă verso sau doar faţă) de cupru. Operaţia de încărcare propriuzisă pe chip se face tot din meiniu prin alegerea Command >Write All.A doua posibilitate ar fi să vă creaţi propria placă de dezvoltare asemănătoare cu placa pe care se testează aplicaţiile din acest tutorial.Înainte de încărcare mergeţi în meniu la Command > Erase pentru a şterge toate datele din memoria microcontrolerului. No comments Trimiteţi prin e-mail Postaţi pe blog! Distribuiţi pe Twitter Distribuiţi pe Facebook Pentru simularea fizică a aplicaţiilor puteţi alege două căi.Dacă doriţi să creaţi o placă identică cu placa mea puteţi încerca să o creaţi după detalile pe care vi le voi prezenta mai jos.

După ce aţi realizat imprimarea schemei pe placă va trebui să creăm circuitul fizic prin corodare cuprului nefolositor.Se poate face cu o imprimantă. . şi de un recipient în care să turnaţi o parte din soluţie amestecată cu apă caldă.Totuşi această operaţiune este destul de delicată. Trebuie să precizez că această schemă NU trebuie imprimată în oglidă.Puteţi să puneţi şi apă rece însă temperatura apei va spori procesul de corodare. fiind deja în oglindă. în consecinţă v-aş recomanda să mergeţi la o firmă care realizează imprimeuri. Imprimarea este o operaţie dificilă dacă doriţi să o faceţi acasă. soluţie pe care o puteţi găsi tot într-un magazin de componente electronice. o folie specială care va fi plasată pe placă si un fier de călcat care vă ajută la trecerea imprimeului după folie pe pelicula de curpru.Schema pe care o veţi imprima o puteţi descărca de la sectiunea Download -Tutoriale AVR -Schemă Placă.Acest lucru este important să îl spuneţi dacă mergeţi la o firmă de imprimeuri.Recipientul pe care îl veţi folosi ar fi bine să nu fie din metal pentru a se evita distrugerea lui.ea fiind plasată direct aşa cum e pe placă.Aveţi nevoie de Clorură Ferică.

Cel mai bine ar fi sa o puneţi într-o sticlă şi să o aruncaţi la un coş de gunoi din exterior. Dacă circuitul imprimat este mai mic decât placa vă recomand să decupaţi părţile nefolositoare cu un bomfaier sau un flex.După ce terminaţi operaţia v-aş sfătui să nu aruncaţi soluţia în sistemul de conducte al băii deoarece ea este extrem de corozivă şi vă poate ataca ţevile.Ţineţi placa în această soluţie 10-20 de minute până când se îndepărtează întreaga peliculă de cupru nefolositoare rămânând astfel doar circuitul. Din păcate nu dispun de schema electrică într-un program CAD. însă vă voi pune la dispoziţie schema electrică de imprimare cu componentele electronice pe ea .Dacă până aici toate sunt bune şi frumoase urmează să daţi găuri plăcii.Pentru a mări poza daţi click .Găurile se pot da cu o bormaşină mică dar înainte să le daţi ar fi bine să ştanţaţi locurile în care veţi plasa burghiul pentru o mai mare precizie în momentul când găuriţi placa.

o diodă 1N4148.pe ea: Componentele de care veţi avea nevoie pentru montaj sunt următoarele: un microcontroler ATMega8+slot.1 microfarazi. deoarece vă va fi mai uşor să montaţi pinii.2 rezistenţe de 4. o rezistenţă de 15K.9 LED-uri(20mA).7K.4 potenţiometre de 10K.partea de lipituri şi partea de componente: .2 rezistenţe de 10K. 4 butoan fără reţinere şi 4 cu reţinere.V-aş mai sfătui să aveţi mare grijă la montarea elementelor cu polaritate astfel plusul să fie la plus şi minusul la minus. un tranzistor BC549. în felul acesta riscând să ardeţi stabilizatorul de tensiune.8 rezistenţe de 10 ohmi. Pentru a vă face idee cum trebuie să arate piesele montate pe placă aveţi aici două fotografi cu ambele părţi ale plăcii. un conector de alimentare cu 2 intrări şi mai multe şiruri de pini (aprox. Sfatul meu ar fi să daţi în linie dreapta găurile unde vor fi montate şirurule de pini. 2 condensatori electrolitici de 1 microfarad şi unul de 0. Pentru lipirea pieselor pe circuit aveţi nevoie de un pistol de lipit.Când faceţi lipiturile trebuie să aveţi grijă să nu lipiţi două componente de circuit care nu au legatură pe schemă.nişte fludor şi nişte sacâz. 2 diode zener de 5V.un L7805 – stabilizator de tensiune de 5 volţi.un integrat MAX232 pentru conexiunea serială +slot. 2 conectori pentru portul serial cu pinii în jos.13 rezistenţe de 1K.aici mă refer la LED-uri şi la condensatori. 120 de pini) pe care le veţi tăia în funcţie de numărul de găuri de la ieşirea integratelor.8 rezistenţe de 470 ohmi. altfel puteţi să legaţi plusul de minus şi circuitul să se închidă fără ca el să aibă consumator.

Sursa de tensiune poate fi o sursă de calculator.Dacă aţi terminat de făcut toate lipiturile ar fi bine să verificaţi circuitul ca nu cumva să aveţi lipituri incorecte.Dacă rezistenţa este 0 înseamnă că avem o lipitura incorectă şi ea trebuie înlăturată.Mufa principală de alimentare a unei surse model ATX arată cam aşa: .Înainte să puneţi circuitul sub tensiune se vetifică mai întâi la bornele stabilizatorului dacă rezistenţa este diferită de 0 apoi se verifică din punct în punct între elemente dacă au sau nu rezistenţa 0.După ce toate conexiunile greşite au fost înlăturare puteţi alimenta placa.

Firele le puteţi face rost cumpărând un metru de cablu de alarmă pe care îl veţi desface.Ar fi bine să urmăriţi stabilizatorul să vedeţi dacă se încălzeşte iar dacă da deconectaţi repede circuitul de la alimentare deoarece aveţi o problemă pe care nu aţi rezolvat-o. Unelte Software 06:51 C. Conexiunile între pini se pot face cu fire subţiri.La capetele acestor fire vor fi legaţi cu fludor nişte papuci de conexiune.C.Pentru a porni placa trebuie să legaţi la plusul stabilizatorului de teinsiune de pe placa creată anterior ieşirea sursei 12VDC(firul galben) iar minusul la ieşirea COM (firul negru).aceste legături între papuci şi fir vor trebui izolate cu tub termocontractant sau bandă izolir.Modul de lucru este prezentat mai jos: După ce porniţi programul CodeVision AVR ar trebui să aveţi următoarea fereastră: .În continuare ele vor fi prezentate pe rând: CodeVision AVR CodeVision AVR este IDE-ul cu care vom scrie codul sursă al programelor care vor rula pe microcontrolerul ATMega8. Breadboard arată cam aşa: Linile din mijloc şi coloanele + şi – sunt legate în serie.Dacă toate sunt în regulă ar trebui să se aprindă LED-ul de lângă stabilizatorul de 5V.În felul acesta puteţi crea un circuit destul de simplu având la dispoziţie componentele electronice şi nişte fire cu care să le concetaţi. No comments Trimiteţi prin e-mail Postaţi pe blog! Distribuiţi pe Twitter Distribuiţi pe Facebook Uneltele software pe care le vom folosi în dezvoltarea aplicaţiilor pot fi download-ate de la secţiunea Download-Software.Pentru a porni sursa trebuie să legaţi pinul PS_ON# la COM(masă).Papucii îi puteţi găsi tot în magazinele de componente electronice însă când îi cumpăraţi trebuie să aveţi grijă să se potrivească cu pinii şirurilor de pini.O soluţie pe care am uitat să o precizez ar fi folosirea unui breadboard pe care să montaţi circuitul în funcţie de aplicaţie.Pentru protecţie . Prezentarea plăcii o puteţi urmări aici: Cam atâtea ar fi despre placa de dezvoltare.

Save and Exit. dacă arată ca aici înseamnă că totul este în regulă. După ce apăsaţi OK vă va întreba dacă doriţi să folosiţi CodeWizardAVR. Pentru crearea unui nou proiect megeţi la File-New Project.Bun. alegeţi Project şi apăsaţi OK.În continuare vom vedea cum se crează un proiect si cum se generează automat codul.După aceea mergeţi în meniu la File şi apăsaţi Generate.Următoarea etapă va fi de setare a funcţiilor microcontrolerului: Alegeţi la Chip ATmega8 şi setaţi frecvenţa de 1MHz. apoi veţi alege locaţia şi veţi da nume fişierelor proiectului. apăsaţi Yes.Dacă până aici totul este bine ar trebui să aveţi un cod asemănător: .

Pentru acest proiect avem nevoie de un buton . Bun.Va apărea o fereastră în care va trebui să selectaţi componentele. în lista DEVICES.Mai întâi vom aduce aceste piese din librărie în partea stângă.Pentru compilare va trebui să mergeţi în meniu şi să setaţi Project> Build All.La început s-ar putea să vă întrebe dacă doriţi să încărcaţi un exemplu.Pentru a aduce elementele în listă megeţi în meniu la Library şi selectaţi Pick Device/Symbol sau apăsaţi butonul P de lângă DEVICES.Ca rezultat vom avea 2 dispozitive ca în figura de mai jos: .Acest fişier reprezintă codul care va fi încărcat în microcontroler.În director veţi găsi un fişier cu extensia *.hex.Mergeţi în stânga sus la câmpul Keywords şi scrieţi button. de o sursă de tensiune şi de o rezistenţă pentru a limita curentul prin circuit.Ca rezultat al compilării vom găsi în directorul în care aţi salvat proiectul un director care se numeşte Exe. dacă aţi făcut toate acestea înseamnă că aţi realizat primul dumneavoastră proiect în CodeVision AVR. în acest caz alegeţi nu.în stânga o listă de unelte iar sus meniul: Pentru a exemplifica modul de funcţionare al programului voi crea o schemă simplă şi anume un led care va fi aprins prin apăsarea unui buton.de un led. ISIS Proteus Pentru a simula orce aplicaţie din acest tutorial deschideţi ISIS Proteus.Obserăvm că în dreapta avem planşa de lucru.

După ce aţi ales componentele închideţi fereastra pentru că urmează să alegem sursa de tensiune. Din lista de generatoare selectaţi DC adică sursa de tensiune continuă.Aceasta o puteţi obţine tot din stânga de la butonul Terminal Mode.Pentru acest lucru mergeţi în stânga şi selectaţi butonul Generator Mode. Procedaţi asemănător şi pentru alegerea rezistorului şi a LED-ului.Daţi dubluclick pe BUTTON pentru a fi adăugat în lista din dreapta de dispozitive. .Totuşi pentru circuitul nostru avem nevoie şi de conexiunea la masă(GROUND).apoi plasaţi această sursă în plaşa de lucru.Pentru rezistor căutaţi la Keywords cuvântul resistor iar pentru LED căutaţi LED-BIBY.

urmând ca la majoritatea aplicaţiilor să avem la bornele de alimentare tot această tensiune.Pentru setare se va da dublu click pe sursă şi se va seta 5 la caseta Voltage. . Tensiune de lucru a microcontrolerului ATMega 8 este de 5 volţi.Până acum avem sursa de tensiune continuă şi masa. deci pentru uşurinţă vom seta şi tensiunea sursei pentru aplicaţia curentă tot 5 volţi.Selectaţi ground şi plasaţi-l în fereastra de lucru.

astfel vom avea un curent de 5 miliamperi. Pentru plasarea rezistenţei şi a LED-ului vom alege din dreapta butonul Component Mode: Vom plasa butonul.Setarea rezistenţei se face prin apăsarea dublului click pe ea şi înscrierea valorii dorite în câmpul Resistence.Componentele se vot roti prin click dreapta-Rotate iar legăturile între elemente se fac prin ducerea creionului în dreptul elementului şi trasarea liniei până la elementul următor.Valoarea rezistenţei va fi 1K.Schema finală ar trebui să arate cam .În lipsa rezistenţei curentul ar creşte şi ar distruge sursa chiar dacă simularea funcţionează şi fără ea. circuitul nostru mai are nevoie de LED şi rezistenţa de limitare a curentului în circuit.Bun.rezitenţa şi LED-ul între sursă şi masă.

Dacă totul este în regulă veţi putea vedea led-ul aprins la apăsarea butoului: Cam acestea sunt bazele mediului Proteus. Pentru a simula schema creată apăsaţi butonul Play din stânga paginii jos. . asemănător putând crea simulări pentru fiecare aplicaţie pe care o vom dezvolta pe parcursul tutorialului.aşa : Totuşi dacă doriţi o intensitate mai mare a LED-ului puteţi scădea valoarea rezistenţei însă acest lucru va duce la un consum mai ridicat.