You are on page 1of 62

Laboratorul 2 - Intreruperi, Timere, PWM

Acest laborator are ca scop familiarizarea voastr cu lucrul cu timerele prezente n microcontrollerul Atmega16, acoperind att modul normal de funcionare ct 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 apariia unui eveniment care trebuie tratat de ctre procesor. Tratarea ntreruperii are ca efect suspendarea firului normal de execuie al unui program i lansarea n execuie 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 ateptarea 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 execuia doar atunci cnd este necesar. nainte de a lansa n execuie o RTI, procesorul trebuie sa aib la dispoziie un mecanism prin care s salveze starea n care se afla n momentul apariiei 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 execuia RTI. La sfritul execuiei RTI starea anterioar a registrelor este refcut i programul principal este reluat din punctul de unde a fost ntrerupt. Pentru a asocia o ntrerupere cu o anumit rutin din program, procesorul folosete tabela vectorilor de ntrerupere (TVI), ilustrat n figura de mai jos. n aceast tabel, fiecrei ntreruperi i este asociat adresa rutinei sale de tratare, la care programul va face salt n cazul apariiei acesteia. Aceste adrese sunt predefinite i sunt mapate n memoria de program ntr-un spatiu contiguu care alctuiete TVI. Adresele ntreruperilor n TVI sunt setate n funcie de prioritatea lor, cu ct adresa este mai mic cu att prioritatea este mai mare.

Figura 1. Tabela de vectori de ntrerupere pentru atmega16 Dup cum se observ din figura 1, pe lng ntreruperile componentelor interne uC-ului(timer-e, interfee 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 mascrii ntreruperilor prin scrierea pe 0 a bitului I din registrul de status (SREG). Valoarea iniial a acestui bit este 0, deci chiar dac ntreruperile unui periferic sunt activate din unul din registrele acestuia, tot nu sunt luate n considerare dect cnd se scrie 1 pentru acest flag. Totodat, la apariia unei ntreruperi, n afar de salvarea strii, procesorul dezactiveaz ntreruperile, iar la revenirea din rutina de tratare le reactiveaz. Activarea lor poate fi realizat forat i din handler-ul de ntrerupere(de exemplu suntem n handler-ul pt reset, i dorim s activm ntreruperile unui timer).

1.1. Tratarea unei intreruperi

Figura 3. Tratarea unei intreruperi pentru ATMega16 Sa presupunem ca programul nostru primeste intreruperea externa INT0 in timp ce executa instructiunea ldi R16,0xFF. Dupa efectuarea instructiunii, registrul contor program (PC) este automat salvat in stiva si apoi initializat la valoarea corespunzatoare adresei lui INT0 ($002). Acest lucru se traduce prin saltul programului de la adresa curenta ($123) la adresa $002. Aici, programul gaseste instructiunea jmp $2FF care-i permite sa sara la rutina efectiva de tratare a intreruperii. 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). In timpul executiei unei intreruperi, bitul I din SREG este setat la 0 si resetat la iesire, adica orice alta intrerupere care poate aparea in timpul intreruperii curente nu va fi luata in seama. Cu toate acestea, utilizatorul poate sa reseteze bitul I din software, permitand astfel executia de intrerupere in intrerupere.

1.2. Registre
Descrierea completa a acestor registre o gasiti in datasheet in capitolele Interrupts, External Interrupts. 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

Figura 4. Registrul SREG General Interrupt Control Register (GICR)


contine flag-uri pentru activarea/dezactivarea intreruperilor externe INT0,1,2 bitul IVSEL controleaza unde se plaseaza vectorii de intreruperi(0 - inceputul memoriei Flash, 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, INT0 combinatiile a cate doi biti stabilesc frontul(crescator sau descrescator) pe care se genereaza cererea de intrerupere. 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 - front descrescator, 1 front crescator)

Figura 5. Registrul MCUCSR

1.3. Lucrul cu ntreruperi n avr-gcc


avr-libc ofer interfaa din avr/interrupt.h pentru definirea rutinelor de tratare a ntreruperilor. Tabela de vectori specific fiecrui microcontroller (n cazul nostru pentru ATMega16) este declarat n header-ul de IO specific (ex: iom16.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

USART, RXC

USART_RXC_vect

Primirea unui octet pe seriala USART

Definirea rutinei de tratare se face cu macro-ul ISR:


#include <avr/interrupt.h> ISR(INT0_vect) { ... }

Pentru rutine exist i sintaxa cu SIGNAL(), care acum este deprecated!


#include <avr/interrupt.h> ISR(vector, flag) { ... }

Macro-ul ISR definete rutina de tratare pentru perifericul respectiv, salveaz SREG i apeleaz instruciunea reti la ieirea din rutin. Rutinele pot fi definite cu urmtoarele flag-uri:

ISR_BLOCK: comportamentul default, n care ntreruperile globale sunt dezactivate atunci cnd se intr ntr-o ntrerupere ISR_NOBLOCK: faciliteaz existena ntreruperilor imbricate (poate fi util dac se dorete ca o alt ntrerupere s fie ntrziat) ISR_NAKED: omite prologul i epilogul rutinei de tratare, adic salvarea SREG i apelul reti() ISR_ALIASOF: rutina este identic cu cea a altui vector de ntrerupere

#include <avr/interrupt.h> ISR(INT0_vect) { ... } ISR(INT1_vect, ISR_ALIASOF(INT0_vect))

Alte wrapper-e (n jurul unor instruciuni ale core-ului AVR) oferite de interfa sunt:

sei() - seteaz pe 1 bitul I din SREG, activnd ntreruperile globale. Apeleaz instruciunea assembler sei cli() - seteaz pe 0 bitul I din SREG, dezactivnd ntreruperile globale. Apeleaz instruciunea assembler cli reti() - ntoarcerea dintr-o rutin de tratare a intreruperii, activeaz ntreruperile globale. Ar trebui sa fie ultima instructiune apelata intr-o rutina care foloseste flag-ul ISR_NAKED.

ntreruperile ntlnite care nu au un rutin de tratare vor cauza o ntrerupere de reset!

2. Timer

2.1. 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. Un timer, odata initializat va functiona independent de unitatea centrala (core P). Acest lucru permite eliminarea buclelor de delay din programul principal. Principiul de functionare a unui Timer poate fi descris in linii mari de cele trei unitati: 1. Registrul numarator (Timer Counter, TCNT) care masoara efectiv intervalele de timp si care este incrementat automat cu o frecventa data. 2. Avand ceasul intern sau alt ceas conectat pentru a obtine diferite intervale folosim un Prescaler. Acesta are menirea de a diviza in functie de necesitatile aplicatiei frecventa de ceas si odata cu divizarea sa incrementeze registrul TCNT. 3. La fiecare incrementare a TCNT are loc o comparatie intre acest registru si o valoare stocata in registrul OCRn. Aceasta valoare poate fi incarcata prin software de utilizator. Daca are loc egalitatea se genereaza o intrerupere, in caz contrar incrementarea continua.

Figura 6. Componentele si functionarea unui timer pt atmega16 Timerele sunt prevazute cu mai multe canale astfel in paralel se pot desfasura diferite numaratori. ATmega16 este prevazut cu 3 unitati de timer: doua de opt biti si una de numarare pe saisprezece biti. Principalele caracteristici sunt:

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.Un n mic inlocuieste numarul timerului si un x mic inlocuieste unitatea de comparare de output. Atunci cand se foloseste registrul sau bitul definit intr-un program, trebuie folosit forma precis.

2.2. Moduri de functionare

Figura 7. Configuratie pentru moduri generatoare de unda Timer/Counter0 si Timer/Counter2 au patru moduri de functionare, ce se diferentiaza prin valorile pana la care se face incrementarea, si prin cand se face resetarea contorului.

2.3. Registre
Deoarece Timer/Counter 1 functioneaza pe 16 biti, el prezinta si registre pe 16 biti, a caror accesare este descrisa in sectiunea 2.5. 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, TCCR0, TCCR2)


registre de 8 biti si nu au restrictii de acces CPU. rolul lor este de a configura Timerul pentru un anumit mod de functionare. detalii despre combinatiile de biti pentru aceste registre sunt prezente in datasheet, in tabelele de la descrierea registrelor TCCR pentru fiecare timer.

TCNT0,1,2

contin valoarea contorului timerului. TCNT1 este pe 16 biti

OCR0,1,2 (Output Compare Register)


contin o valoare comparata cu valoarea din TCNT la fiecare incrementare a acesteia. operatia de comparare seteaza semnalul de potrivire-comparare (OCF1A/B) la generarea unei cereri de intrerupere de comparare output. 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,1,2 (Input Capture Register)


se scrie in el valoarea din TCNT de fiecare data cand apare un eveniment pe pinul ICP1. ICP1 este pe 16 biti

2.4. Definitii

BOTTOM = counterul ajunge la capat la valoarea 0x0000. 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.

Valoarea TOP poate fi desemnata astfel incat sa fie una din aceste valori fixe: 0x00FF, 0X01FF, 0X003FF sau valoarea memorata in registrele OCR1A sau ICR.

2.5. Accesarea registrelor pe 16 biti


TCNT1, OCR1A/B si ICR1 sunt registre de 16 biti care pot fi accesate de catre AVR CPU cu ajutorul bus- ului de date de 8 biti. Un registru de 16 biti poate sa sa fie accesat folosind doua operatii, fie de scriere, fie de citire pe 8 biti. Pentru a executa o scriere de 16 biti, byte-ul HIGH trebuie sa fie scris inaintea byte-ului LOW (bug de compilator, nu feature hardware).

2.6. Calculator

3. Pulse width modulation (PWM)


PWM (Pulse Width Modulation - modularea factorului de umplere al unui semnal) permite controlul circuitelor analogice din domeniul digital. Un controller PWM este in esenta un convertor digital-analog (DAC) pe un singur bit. Aceast modulaie vine n sprijinul multor aplicaii deoarece nseamn consum mic, eliminarea zgomotelor i aplicaii cu cost redus.

3.1. Principiul de functionare


Modularea foloseste variatia factorului de umplere a unei forme de unda dreptunghiulara pentru a genera la iesire o tensiune analogica. 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. Tipuri de PWM

Modulatie Delta Modulatie Delta-Sigma

Multe circuite digitale pot genera semnale PWM. Majoritatea microcontrollerelor dispun de aceasta facilitate. Pentru a implementa o asemenea facilitate ele se folosesc de un numrator care este incrementat periodic (conectat direct sau indirect la o unitate de ceas) si care este resetat la sfarsitul fiecrei perioade a PWM-ului. Cand valoarea numaratorului este mai mare decat valoarea de referinta, iesirea PWM (output-ul) trece din starea inalta in stare joasa (sau invers).

Porturile
13:01 C.C. No comments Trimitei prin e-mail Postai pe blog! Distribuii pe Twitter Distribuii pe Facebook

Porturile unui microcontroler sunt cele mai folosite dispozitive de schimb de date cu exteriorul.Avantajul cel mare este c ele sunt paralele, putndu-se astfel relaiza schimbul a mai multor bii de date simultan.n viziunea programatorului porturile nu sunt altceva dect niste regitrii prin care se pot scrie i citi date.Lungimea unui port este influenat de numrul de bii pe care procesorul i poate executa la un moment dat.n cazul nostru, microcontrolerul ATMega8 este pe 8 bii deci i dimensiunea regitrilor va fi tot de 8 bii.De obicei unui port sunt asociai 2 regitrii, unul care seteaz direcia pinilor iar altul care realizeaz schimbul de date ntre unitatea central a microcontrolerului i exterior. Microcontrolerului ATMega8 are asociat unui port 3 regitrii,DDR care seteaz direcia pinilor,PORT care seteaz datele de ieire ale portului la nivel de pin i PIN care memoreaz intrrile microcontrolerului la nivel de pin.Numrul porturilor este tot 3 i sunt numite B,C i D.Dac ne uitm pe schema general avem urmtoarea configuraie:

Pinii PB0-PB7 corespund portului B,PC0-P6 portului C iar PD0-PD7 portului D.Observm c portul C are doar 7 intrri.Ei bine ultimul bit din regitrii asociai portului nu este flosit.Pentru a v face o imagine mai bun asupra legturii dintre pinii microcontrolerului i regitri asociai portului urmrii
figura de mai jos:

Obse rvm c pinului 0 i corespunde locaiei 0 a portului, pinului 1 locaiei 1 i tot aa.n cazul de fa pinii sunt notai cu P, pentru portul B avem PB , pentru portul C avem PC iar pentru portul D avem PD. Pentru a exemplifica modul de configurare i de utilizare a porturilor din ATMega8 voi crea un exempu simplu n care vom avea setai primii 4 pini ai portului B ca pini de intrare iar primii 4 pini ai portului C ca pini de ieire.La pinii de intrare vor fi legate 4 butoane iar la pinii de ieire ai portului C vom lega 4 LED-uri.La apsarea butoanelor vom dori ca led-urile corespunztoare butoanelor apsate s se aprind. Programul i schema electric le putei downloada de la seciunea Download-Porturi-Aplicaie1. Schema electric n Proteus a aplicaiei este urmtoarea:

Programul din memoria microcontrolerului nu va face alceva dect s preia informaia de la portul B i s o transmit la portul C. Pentru scrierea programului n CodeVision AVR procedai exat cum v-am artat mai nainte la prezentarea general a programului ns la seciunea de setare mergei la Ports>Port C i setai primii 4 bii de direcie ca n figura de mai jos apoi dai din meniul File, Generate ,Save and exit:

Dup cum am mai spus, direcia pinilor se seteaz cu ajutorul registrului DDR(Data Direction Register).Dac vei urmri n seciunea de setare a programului la nceputul funciei main vei observa c DDRB =0x00,adic toi pinii sunt setai ca intrare, iar DDRC = 0x0F, adic doar primii 4 pini sunt setai ca ieiri, restul fiind setai ca intrri.Reprezentarea valorii 0x0F este o reprezentare n hexazecimal i este echivalent cu 0b00001111 n binar i cu 15 n

zecimal.Dac nu suntei familiarizai cu sistemul binar i hexazecimal putei afla cum se fac conversile aici:http://ro.wikipedia.org/wiki/Sistem_binar n bucla while,bucla de ciclare infinit, vom avea o singur linie care va transfera datele de la intrarea portului B la ieirea portului C adic vom transfera coninutul registrului PINB n registrul PORTC: PORTC = PINB; Programul este gata putnd fi deja compilat.Pentru ncrcarea programului n schema din Proteus dai dublu click pe micorocontroler.Ca rezultat vei deschide o fereastr cu titlul Edit Component.Mergei la cmpul Program File i adugai fiierul program.Acest fiier se gsete n locia n care ai salvat anterior proiectul din Code Vision AVR, n directorul Exe.Dac compilarea codului a decurs normal ar trebui s avei ca rezultat un fiier cu extensia *.hex.

Dac totul a decurs bine pn aici putei simula aplicaia fr nici o problem.La apsarea butoanelor ar trebui s se aprind LED-urile corespunztoare.Fizic aplicaia o putei vedea aici: Urmtoarea aplicaie este ceva mai complex, ea avnd rolul simulrii unei instalaii luminoase pentru pomii de crciun la care vom avea posibilitatea alegerii unui program de funcionare prin apsarea unor butoane.De data asta vom folosi tot portul B ca port de intrare la care vom lega la primii 4 pini, 4 butoane cu care vom alege modul de funcionare iar ca port de ieire vom folosi portul D la pinii cruia vom lega 8 LED-uri.Dac se apas primul buton, adic bitul 0 al registrului PINB este 1 logic, vom avea modul 1 de funcionare,dac se apas butonul 2, adic bitul 1 al registrului PINB este 1 logic,vom avea modul 2 de funcionare i tot aa pn la butonul 4.Dac nu este apsat nici un buton se vor activa pe rnd toate cele 4 moduri.Dac se apas dou sau mai multe butoane nu se va ntmpla nimic. Programul i schema electric le putei downloada de la seciunea Download-Porturi-Aplicaie 2. Schema elecrtric a aplicaiei n Proteus va fi urmtoarea:

Pentru scrierea codului procedai exact ca la primul exerciiu ns setai de data aceasta toi pinii portului D ca fiind pini de ieire. Pentru o lizibilitate mai buna a codului am ales s am cte o funcie pentru fiecare mod de funcionare,funcii care sunt plasate naintea funciei main.Pentru modul 1 codul este urmtorulul: void mod1(void) { PORTD = 0b00000001; while(PORTD) { delay_ms(100); PORTD = PORTD<<1; } } La nceput iniializm PORTD-ul cu valoarea 0b00000001 deoarece dorim ca primul led s fie aprins.Pentru ca al doilea LED s se aprind i s se sting primul trebuie s mutm 1-ul de pe prima poziie pe poziia a doua.Acest lucru se face prin codul PORTD = PORTD<<1 care reprezint iftare bitului 1.Dup execuia primului ciclu while noua valoare a PODRTD-ului va fi 0b00000010.Pentru a v face o idee cum funcioneaz funcia urmrii codul de mai jos: Iniializare :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 iei din ciclu while i totodat i din funcia mod1. Observm c aici apare o funcie pe care nu am avut ocazia s o folosesc mai nainte i anume delay_ms.Aceasta are rolul de a ntrzia programul cu n milisecunde, n cazul nostru 100 de milisecunde.Pentru a folosi aceast funcie trebuie s includei librria delay.h.Probabil c v ntrebai de ce este nevoie de aa ceva.Ei bine dac nu am avea un timp ntre schimbrile portului am vedea toate LED-urile aprinse datorit vitezei mari de comutare. Pentru modul 2 de funcionare codul este asemntor ns operaia de iftare se face de la

stnga la dreapta. void mod2(void) { PORTD = 0b10000000; while(PORTD) { delay_ms(100); PORTD = PORTD>>1; } } n modul 3 vom aprinde mai nti led-urile din mijloc (pinii 3 i 4), apoi vom stinge led-urile din mijloc aprinznd led-urile urmtoare( pinii 2 i 5) i tot aa pn la aprinderea led-urilor 1 i 8(pinii 0 i 7). void mod3(void) { PORTD = 0b00011000; delay_ms(100); PORTD = 0b00100100; delay_ms(100); PORTD = 0b01000010; delay_ms(100); PORTD = 0b10000001; delay_ms(100); } Modul 4 se va comporta exact invers modului 3,aprinznd ledurile din exterior spre interior. void mod4(void) { PORTD = 0b10000001; delay_ms(100); PORTD = 0b01000010; delay_ms(100); PORTD = 0b00100100; delay_ms(100); PORTD = 0b00011000; delay_ms(100); } n bucla de ciclare infinit vom face o selecie a acestor 4 moduri n funcie de butoanele pe care le-am apsat. while(1) { switch(PINB) { //se apasa primul buton si se seteaza modul 1 de functionare case 0b00000001: mod1(); break; //se apasa al doilea buton si se seteaza modul 2 de functionare case 0b00000010: mod2(); break; //se apasa al treilea buton si se seteaza modul 3 de functionare

case 0b00000100: mod3(); break; //se apasa al patrulea buton si se seteaza modul 4 de functionare case 0b00001000: mod4(); break; //daca nu s-a apasat nici un buton se vor parcurge toate cele 4 moduri case 0b00000000: mod1(); mod2(); mod3(); mod4(); //daca s-a apasat mai multe butoane nici un mod va fi activ default: PORTD = 0x00; } }; Pentru a vedea ce butoane au fost apsate trebuie s verificm pinii portului B.Aceast verificare se face prin swhitch care verific valorile registrului PINB.Dac s-a apsat butonul 1 vom avea valoarea 0b00000001 i se execut funcia mod1,dac s-a apsat butonul 2 vom avea valoarea 0b00000010 i se execut funcia mod2, i tot aa pn la butonul 4.Dac nu s-a apsat nici un buton ,adic PINB = 0b00000000 atunci se vor executa pe rnd cele 4 funcii,iar dac avem alt combinaie a registrului PINB valoarea lui PORTD va fi 0. Din pcate programul nostru are un neajuns i anume atunci cnd este apsat un buton nu se ruleaz rapid modul selectat ci trebuie s ateptm teminarea modului anterior.Acest lucru se poate rezolva prin ntreruperi dup cum vom vedea mai trziu.

Sistemul de ntreruperi
04:25 C.C. No comments Trimitei prin e-mail Postai pe blog! Distribuii pe Twitter Distribuii pe Facebook

ntreruperile ntr-un microcontroler sunt vzute ca nite evenimente speciale generate de elementele periferice.Aceste evenimente pot fi reprezentate de apsarea unui buton, atingerea unei valor a numrtorului,terminarea de citit a unei valori a convertorului analog digital,etc..Toate acestea sunt gestionate de un sistem intern numit sistem de ntreruperi , sistem care are rolul de a oferi procesorului informaii referitoare la natura ntreruperii i de a opri funcionarea ciclic tratnd ntreruperea ntr-o rutin special. Aceast rutin are o adres special de nceput.n cazul chip-ului ATMega8 adresele rutinelor de tratare corespunztoare ntreruperilor sunt urmtoarele:

Prioritatea de tratare a unei ntreruperi n cazul n care avem mai multe cereri de ntrerupere este marcat de prima coloana, astfel cea mai mare prioritate o are ntreruperea generat de semnalul RESET,apoi ntreruperea extern INT0 , ntreruperea extern INT1 i tot aa.Trebuie s precizez c aceste adrese sunt mascate n CodeVisionAVR dar totui e bine s tii cum funcioneaz modul intern de tratare al ntreruperilor. Momentan voi trata doar ntreruperile externe,INT0 i INT1, deoarece sunt cele mai simple de configurat. Pentru a putea folosi orce ntrerupere trebuie mai nti s informm microcontrolerul c ntreruperile sunt activate.Acest lucru se face prin comana sei, comand care n C se poate scrie astfel: #asm("sei") Aceast comand nu face altceva dect s seteze valoarea 1 n cel mai semnificativ bit,bitul I, din regist SREG,bit care permite folosirea sistemului de ntreruperi.

P entru dezactivarea ntreruperilor se folosete comanda cli,n C fiind #asm("cli"). Activarea ntreruperilor externe se face prin registrul GICR(General Interrupt Control Register) care are urmtoarea form:

Pentru a activa ntreruperea extern INT0 trebuie s setm valoarea 1 n locaia 6 din registru iar pentru activarea ntreruperii externe INT1 trebuie setat valoarea 1 n bitul 7.Primii doi bii ai

registrului, IVCE i IVSEL se folosesc atunci cnd n memoria microcontrolerului avem o seciune boot ns n acest tutorial nu o s folosim aa ceva.Restul biilor 2-5 nu sunt folosii,ei fiind rezervai. Dup ce am setat ce ntreruperi externe sunt folosite, va trebui s setm n ce moment s se activeze ntreruperea.Acest lucru se poate seta prin registrul MCUCR:

Din acest registru doar primii 4 bii(0-3) sunt atribuii ntreruperilor externe,primii doi bii(ISC00 i ISC01) fiind atribuii ntruperii INT0 iar biii 3 i 4(ISC10 i ISC11) sunt atribuii ntruperii INT1.Urmtoarea configuraie este valabil pentru ambele ntreruperi nct biii ISC11/ISC01 i ISC00/ISC10 pot lua urmtoarele valori: ISC11/ISC01 ISC00/ISC10 00- Nivelul de jos al semnalului va genera o cerere de ntrerupere. 01- Orce schimbare a formei semnalului va genera o cerere de ntrerupere. 10- Frontul descresctor al semnalului va genera o cerere de ntrerupere. 11- Frontul cresctor al semnalului va genera o cerere de ntrerupere.
Dac ntreruperea a fost generat ea va fi semnalat n registrul GIFR:

Dac pe parcursul rulrii 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,aceti bii avnd valoarea 1 atta timp ct nici o cerere nu a fost lansat.Acest registru se verific pentru a vedrea sursa ntreruperii.Ddup execuia rutinei de tratare, bitul corespunztor ntreruperii i va fi automat atribuit valoarea 1,lucru necesar pentru a se evita ciclarea la infinit a rutinei. n exemplul urmtor voi incrementa 2 variabile prin apsarea a 2 butoane legate la pinii corespunztori cererii de ntrerupere INT0 i INT1.Valorile variabilelor care contorizeaz de cte ori au fost apsate butoanele vor fi afiate pe un LCD.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 putei descrca de la seciunea Download-ntreruperi-Aplicaie 1.

Schema electric a aplicaiei este urmtoarea:

Dac ne uitm la schema chip-ului observm c pinii portului D,PD2 i PD3 sunt folosii i ca pini pentru ntreruperi acest lucru npingndu-ne s legm LCD-ul la portul B.LED-ul l vom lega la pinul 0 al portului D.nainte de generarea programului n CodeVision AVR, vom seta LCD-ul pe portul B ,pinul PD0 ca pin de ieire iar pentru setarea ntreruperilor externe vom merge la External IRQ.Vom selecta ambele ntreruperi iar n dreptul lor vom alege Rising Edge,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 regitrii de mai sus cu urmtoarele valori: GICR =0b11000000 se activeaz ambele ntreruperi INT0 i INT1; MCUCR = 0b00001111 - se vor semnala cereri de ntrerupere la trecerea semnalului din starea 0 n starea 1; Dup ce ai generat programul vei observa c dou noi funcii au fost generate: interrupt [EXT_INT0] void ext_int0_isr(void) i interrupt [EXT_INT1] void ext_int1_isr(void) funcii prin care vom trata apariia ntreruperilor.Codul din

interiorul funciilor care trateaz apsarea unui buton este urmtorul: interrupt [EXT_INT0] void ext_int0_isr(void) { int0++; //la apasare se incrementeaza variabila int0 itoa(int0,convert); //convertim valoarea lui int0 in sir de caractere strcpy(linie1,end); //atribuim sirului linie1 valoarea '\0' strcat(linie1,in1); //adaugam la sirul linie1 textul"INT0=" strcat(linie1,convert);//adaugam la sirul linie1 valoarea variabilei int0 lcd_gotoxy(0,0); //mutarea cursorului in LCD la linia 0 coloana 0 lcd_puts(linie1); //afisarea datelor pe LCD } interrupt [EXT_INT1] void ext_int1_isr(void) { int1++; //la apasare se incrementeaza variabila int1 itoa(int1,convert); //convertim valoarea lui int1 in sir de caractere strcpy(linie2,end); //atribuim sirului linie1 valoarea '\0' strcat(linie2,in2); //adaugam la sirul linie1 textul"INT1=" strcat(linie2,convert);//adaugam la sirul linie1 valoarea variabilei int1 lcd_gotoxy(0,1); //mutarea cursorului in LCD la linia 1 coloana 0 lcd_puts(linie2); //afisarea datelor pe LCD } In aceste funcii pe lng incrementare am convertit variabilele corespunztoare ntreruperilor, din short n sir de caractere, am concatenat irurile de caractere care conin sursele ntreruperilor i valorile variabilelor transformate n ir de caractere i apoi le-am afiat pe LCD.Variabilele cu care am lucrat n aceste funcii sunt declarate n partea de declarare a variabilelor globale: unsigned short int0=0,int1=0; char in1[6] = "INT0="; char in2[6] = "INT1="; char convert[4],end[1]=""; char linie1[16],linie2[16]; Este necesar declararea lungimii irurilor deoarece microcontrolerul nu poate aloca dinamic spaii de memorie n memoria program de tip flash. n bucla infinit while avem doar codul care va aprinde i va stinge LED-ul dup o secund: while (1) { PORTD = 0x00; delay_ms(1000); PORTD = 0x01; delay_ms(1000); }; Pentru a folosi funciile de concatenare i copiere (strcat i strcpy) a fost necesar includerea bibliotecii string.h.Pentru conversia din short n ir de caractere,funcia itoa, am inclus biblioteca stdlib.h. Poate c v ntrebai care e scopul folosirii ntreruperilor pentru aceast aplicaie cnd puteam s folosim doar citirea normal la nivel de port.Totui dac vei ncerca s dezvoltai aplicaia fr ntreruperi vei observa c sunt situaii n care apsai butoanele i variabilele nu se incrementeaz.Acest lucru se ntmpl deoarece exist situaia n care programul ateapt s treac o secund iar dac se apas butonul i se elibereaz n acest timp,apsarea nu este

contorizat.Folosind ntreruperile se elimin acest neajuns. Funcionarea fizic a aplicaiei o putei vedea mai jos:

Timer-ele - Timer 0
02:57 C.C. 1 comment Trimitei prin e-mail Postai pe blog! Distribuii pe Twitter Distribuii pe Facebook

Timer-ele sunt sisteme integrate n microcontroler care au ca scop msurarea unor intervale fixe de timp i de a genera ntreruperi la expirarea intervalului msurat.Tot cu ajutorul timer-elor se pot genera trenuri de impulsuri de o anumit frecven sau compararea a 2 intervale de timp.Timer-ele funcioneaz independent de unitatea central a micrcontrolerului astfel eliminndu-se momentele de timp n care microcontrolerul este blocat ntr-o bucl de ateptare. Timer-ele conin un numrtor liber central(NLC) care are rolul de a numra fiecare impuls de tact.Acest NLC este de fapt un registru de 8 sau 16 bii care la fiecare impuls este incrementat cu o unitate.Numrtorului i se poate da o valoare de start cuprins ntre 00h/0000h i FFh/FFFFh.Dac NLC-ul are valoarea FFh/FFFFh i primete un impuls el se reseteaz,noua valoare fiind 00h/0000h.Tot n momentul resetrii numrtorul trimite un semnal ctre sistemul de ntreruperi. Microcontrolerul ATMega8 ofer 3 timere:Timer 0,Timer 1 i Timer 2 ns momentan ne vom concentra asupra Timer-ului 0.

Timer/Counter 0
Timer-ul 0 este un timer de uz general pe 8 bii care are urmtoarea schem bloc:

n cazul de fa NLC-ul este reprezentat de registrul TCNT0 la care avem acces de citire i scriere.Observm din schem c o dat ce s-a atins valoarea 0xFF se trimite un semnal ctre logica de control care poate genera o cerere de ntrerupere.Sursa semnalului care incrementaz NLC-ul poate fi extern(T0) sau intern(semnalul de tact al microcontrolerului)

care poate fi prescalat.La fiecare tact clkT0 numrtorul TCNT0 este incrementat:

Registrul TCCR0 are rolul de a selecta i prescala susra semnalului de tact, el avnd forma:

D in acest registru vom folosi numai ultimii 3 bii (CS02, CS01, CS00) pentru setare.Valorile pe care le poate lua i seminificaiile lor sunt urmtoarele: 000 nu se selecteaz nici o surs de tact; 001 folosete ceasul intern fr prescalare; 010 folosete ceasul intern cu prescalarea 8 (clkT0/8); 011 folosete ceasul intern cu prescalarea 64 (clkT0/64); 100 folosete ceasul intern cu prescalarea 256 (clkT0/256); 101 folosete ceasul intern cu prescalarea 1024 (clkT0/1024); 110 folosete o surs extern de tact la pinul T0.Se ia n considerare frontul descresctor; 111 folosete o surs extern de tact la pinul T0.Se ia n considerare frontul cresctor; 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 executndu-se codul de la adresa 0x009. n majoritatea aplicaiilor cu timere se folosete prescalarea sursei de tact.Calcului prescalrii se face n felul urmtor: Mai nti calculm frecvena la care dorim s se genereze o ntrerupere.Frecvena va fi raportul dintre o secund i intervalul la care dorim s primim semnalul de la timer.

n funcie de aceast frecven vom alege frecvena extern sau vom prescala ceasul intern.Prescalarea ceasului intern se face n aa fel nct frecvena rezultant s fie egal sau mai mic cu frecvena dorit.

Dac prescalnd timerul nu obinem o

frecven egal cu cea dorit i obinem o frecven mai mic, atunci se calculeaz valoarea de start a NLC-ului.Aceast valoare va fi raportul dintre frecvena intern i prescalarea aleas la pasul anterior nmulit cu frecvena dorit:

Pentru a nelege mai bine cum se calculeaz frecvena 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.

Observm ca aceast frecven este mai mic dect frecvena pe care dorim s o scoat timerul(5Hz), n consecin vom calcula valoarea de pormire a lui TCNT0.

Din pcate n numrtor nu se pot reine date n virgul mobil aa c lui TCNT0 i se va atribui valoarea 195.Acest lucru va duce ns la o mic eroare de msurare a timpului care totui este insesizabil la o funcionare pe termen scurt. Pentru acest exempu configurarea regitrilor va fi urmtoarea: 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 putei downloada de la seciunea Download-Timer0-Aplicaie 1. Schema electric este una simplist:

Cnd creai proiectul n CodeVision AVR,la seciunea de setare a caracteristicilor, vei seta pinul PB0 ca pin de ieire iar pentru setarea parametrilor timer-ului vei merge la Timers-Timer 0 i vei alege la Clock Source: System Clock, la Clock Value:0.977Hz,selectai Owerflow Interrupt i la Time value trecei C3h(195 n decimal).Observm c frecvena aleas nu este cea calculat de noi ns aceat alegere va seta TCCR0=0x05, adic prescalarea cu 1024.

Observm c la generare avem urmtoarele setri: TCCR0=0x05; TCNT0=0xC3; TIMSK=0x01; n concsecin setrile sunt bine fcute.Ce a mai aprut nou n program este funcia de tratarea a ntreruperilor generate de timer,funcie n care vom iniializa 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 ai observat c acest program se putea face i fr timere de aceea urmtorul exemplu va fi unul mai complex i anume un ceas digital reglabil.Aplicaia 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

legate la pinii INT0 i INT1.Aplicaia o putei downloada de la seciunea Download- Timer 0Aplicaie 2. Schema electric este urmtoarea:

Urmtorul lucru pe care trebuie s l facem este s calculm frecvena timerului astfel nct s avem o ntrerupre la o secund.Pentru aceasta frecvena dorit este 1 MHz.Dac folosim ceasul intern i prescalm cu maximul adic cu 1024 observm c noua frecven obinut este de 3.81Hz, frecven care este mai mare dect frecvena pe care dorim s o folosim.Pentru a elimina acest neajuns vom folosi o variabil suplimentar n program care se incrementeaz la fiecare 0,1 secunde,adic la 10Hz.Cnd se ajunge la valoarea 10, variabila care reine secundele se incrementeaz iar valoarea variabilei suplimentare va deveni 0.Momentan vom calcula valorile regitrilor pentru frecvena dorit de 10Hz.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.Configurarea pentru generarea programului n CodeVision AVR se face la fel ca mai nainte ns la Timer Value trecei 62(98 n decimal).De asemenea nu uitai s configurai LCD-ul pe portul B i s activai ntreruperile externe. Programul va avea 3 funci de tratare a cererilor de ntrerupere,dou pentru tratarea butoanelor care modific ora i minutul i una pentru tratarea ntreruperii generate de timerul 0.Funcia care trateaz ntreruperea extern INT0 are rolul de a incrementa minutul iar funcia care trateaz ntreruperea extern INT1 are rolul de a incrementa ora.Dac minutul a ajuns la valoarea 60 sau ora la valoarea 24 , ele trebuiesc resetate.Funcia care trateaz timerul 0 are rolul de a incrementa o variabil suplimentar pn la valoarea 10 , adic echivalentul unei secunde,la aceast valoare ea resetndu-se i incrementnd variabila secund(sec) cu o unitate.n aceste funcii 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. n cele trei funcii se are grij ca dup fiecare modificare a variabilelor s se scrie noua stare a ceasului pe LCD.Acest lucru se face prin modificarea sirului de caractere linie1. Din pcate ceasul nostru nu este unul exact, existnd erori de msurare a timpului, erori care pot fi nlturate folosind un oscilator extern special pentru ceas. Aplicaia realizat fizic o putei vedea aici:

Timere-le Timer 1
07:11 C.C. No comments Trimitei prin e-mail Postai pe blog! Distribuii pe Twitter Distribuii pe Facebook

Timer-ul 1 funcioneaz exact ca timerul 0 singura diferen fiind c regitrii sunt pe 16 bii.Timerul 1 are mai multe faciliti, el putnd fi folosit ca i comparator la ieire i la intrare, generator de frecven,generator de semnale PWM i numrtor de evenimente externe. Momentan ne vom concentra asupra modului standard de folosire ca numrtor.Numrtorul liber central este reprezentat de registrul TCNT1:

Acest registru este mprit n doi regitrii de 8 bii,TCNT1H i TCNT1L.La scrierea acestui registru trebuie mai nti s scriem registrul TCNT1H apoi TCNT1L.Citirea se face exact invers citind mai nti registrul TCNT1L apoi registrul TCNT1H.Aceste reguli sunt utile pentru pstrarea ct mai mare a preciziei NLC-ului deoarece el se incrementeaz i n momentul operaiei de scriere sau citire.Folosind un compilator n C citirea i scrierea se face folosind o singur variabil ns procesorul va face aceste operaii n doi pai.Acest lucru este periculos atunci cnd o rutin de tratare a unei ntreruperi a fost lansat n timpul citirii sau scrierii acestui registru.Pentru a nltura aceast problem nainte de a efectua o operaie cu regitrii de 16 bii se blocheaz sistemul de ntreruperi.De exemplu n C codul necesar pentru o citire sigur arat cam aa:
unsigned char sreg; unsigned int i; //salveaza starea registrului SREG sreg = SREG; #asm cli; opreste sistemul de intreruperi #endasm // copiaza TCNT1 in variabila i i = TCNT1; //pornim sistemul de intreruperi SREG = sreg;

Un alt registru important pentru setarea caracteristicilor numrtorului este registrul de control TCCR1B:

Biii 7 i 6 sunt folosii pentru captura la intrare , bitul 5 este un bit rezervat iar biii 4 i 3 sunt folosii pentru comparatoare.Biii 2:0 sunt cei care ne intereseaz mai mult deoarece prin ei setm selecia sau prescalarea ceasului: CS12 CS11 CS10 Surs/Prescalare 000-timerul este oprit;

001-ceasul intern far prescalare; 010-ceasul intern prescalat cu 8; 011-ceasul intern prescalat cu 64; 100-ceasul intern prescalat cu 256; 101-ceasul intern prescalat cu 1024; 110-surs extern a tactului la pinul T1,incrementare pe frontul descresctor; 111-surs extern a tactului la pinul T1,incrementare pe frontul cresctor; Dac dorim s folosim i sistemul de ntreruperi va trebui s folosim registrul TIMSK:

Pentru ca timerul s genereze o ntrerupere la suprancrcarea registrului TCNT1 trebuie s se permit folosirea sistemului de ntreruperi i trebuie ca bitul 2 din registru, bitul TOIE, s fie 1.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.Dup ce este executat rutina de tratare a ntreruperii bitul se seteaz automat 1. n exemplu urmtor vom avea un LED conectat la microcontroler care i va schimba starea la intervalul de 5 secunde.LED-ul va fi conectat la pinul 0 al portului B.Programul l putei downloada de la seciunea Download- Timer1- Aplicaia1.Schema electric este una simpl:

Calculul frecvenei de numrare a NLC-ului se face ca la timer 1 ns se va lua n calcul c numrtorul este pe 16 bii:

n CodeVision AVR va trebui s avei urmtoarea setare a timerului 1 pe lng setarea pinului 0 al portului B:

Partea n care se ntmpl toat aciunea este reprezentat de rutina de tratare a ntreruperii generate de suprancrcarea NLC-ului:
interrupt [TIM1_OVF] void timer1_ovf_isr(void) { // setarea valorilor NLC-ului #asm cli #endasm TCNT1H=0x4C; TCNT1L=0x4B;

#asm sei #endasm //schimbarea starii portului PORTB.0 = ~PORTB.0; }

n aceast rutin nu facem altceva dect s initializm TCNT-ul i s schimbm valoarea portului B. Cam att despre timerul 1 momentan.

Generatorul de semnale PWM


08:04 C.C. No comments Trimitei prin e-mail Postai pe blog! Distribuii pe Twitter Distribuii pe Facebook

Generaliti Semnalele PWM sunt folosite n general pentru a controla viteza unui motor de curent continuu.Aceste motoare permit controlul vitezei prin modificarea tensiunii de alimentare ns viteza se modific neliniar.Pentru a controla aceast vitez liniar s-a recurs la metoda de control prin semnale PWM.Semnalele PWM au urmtoarea form:

n schema de mai sus observm c semnalul este de perioad T.Aceast perioad este compus din timpul n care semnalul este 1 logic(Tplin care se mai numete i factor de umplere) i timpul n care semnalul este 0 logic(Tgol). De obicei intervalul T este dat de 256 de tacte de ceas astfel TPlin sau TGol putnd modifica viteza motorului cu pasul de aproximativ 0.4% la fiecare modificare cu o unitate a registrului de control al factorului de umplere. Semnale PWM generate de microcontrolerul ATMega8 Microcontrolerul ATMega8 folosete pentru generarea semnalelor PWM Timer-ul 1 i 2 ns momentan ne vom concentra asupra timer-ului 1. PWM generat de Timer-ul 1 Regitrii care ne intereseaz pentru setarea generatorului sunt urmtorii: -Reginstrul TCNT1 care se incrementeaz la apariia fiecrui impuls de tact, prescalat sau nu,intern sau extern. -Rregitrii OCR1A i OCR1B care contrleaz factorul de umplere n felul urmtor:

Observm c timpul n care semnalul de ieire este 1 este dat de registrul OCR1x.Dac folosim de exemplu numai TCNT1L numrtorul va numra de la 0 la 255 i dac dorim ca factorul de umplere s fie 50%, atunci valoarea lui OCR1x va fi 128.n schem mai observm c numrarea se face n dou sesuri,cresctor i descresctor.Setarea modului PWM se face prin biii WGM13:0 dup cum vom vedea mai jos. -Registrul TCCR1A:

Biii 4,5,6 i 7 au urmtoarea semnificaie: COM1A1/COM1B1 COM1A0/COM1B0 0 0 - Comparatoarele sunt oprite 0 1 - Comparatoarele sunt active ns depind de biii WGM13:0 10 - TCNT1<=OCR1x-1 logic la ieire,TCNT1>OCR1x -0 logic la ieire; 11 - TCNT1<=OCR1x-0 logic la ieire,TCNT1>OCR1x -1 logic la ieire; Biii FOC1A, FOC1B sunt folosii pentru modul rapid aa c i vom seta 0. -Registrul TCCR1B:

Biii ICNC1 i ICES1 sunt folosii pentru captura la intrare iar bitul 5 este un bit rezervat.Prin biii 2:0 setm prescalarea, lucru pe care l-am mai discutat la prezentarea timerului 1. Biii WGM13 i WGM12 din TCCR1B mpreun cu biii WGM11 i WGM10 din TCCR1A sunt folosii pentru alegerea modului de funcionare a timerului:

Totui cele mai folosite moduri PWM sunt primele 3 care permit numrarea pe 8,9 sau 10 bii. Un lucru important pe care trebuie s l cunoatei cnd folosii generatoarele PWM sunt pinii de ieire PWM notai cu OC1A i OC1B n cazul microcontrolerului ATMega8.Atunci cnd sunt

folosii pentru acest scop ei trebuiesc setai ca pini de ieire ai portului.

n urmtorul exemplu vom dori ca la pinul OC1A s avem 50% din perioada T, 1 logic, iar la pinul OC1B dorim s avem doar 25% din interval 1 logic.Pentru uurin vom folosi modul pe 8 bii iar perioada T se va lua suficient de mare astfel nct s se poat observa comutarea.Codul programului l putei descrca de la seciunea Download -PWM -Aplicaie 1. Schema electric este urmtoarea:

Observm c la pinii OC1A i OC1B avem legate 2 LED-uri iar n paralel cu ele un ociloscop prin care vom vizualiza semnalele.Acest osciloscop se gsete n Poteus la seciunea de unelte(Virtual Instruments Mode) i are numele OSCILLOSCOPE.Pentru ca efectul s poat fi urmrit vizual vom prescala ceasul cu 1024.Vom alege ca semnalul s fie 1 logic cnd TCNT1<=OCR1x i 0 altfel iar modul de operare s fie primul, modul PWM pe 8 bii.Valoarea lui OCR1A este 50% din valoarea perioadei, adic 128 iar valoarea lui OCR1B este 25% adic 64. Configurarea regitrilor va fi urmtoarea: TCCR1A=0b10100001; TCCR1B=0b00000101; OCR1A =125; OCR1B =64;

Configurarea n Code Vision AVR a timerului este urmtoarea:

Foarte important este s nu uitai s setai pinii 1 i 2 ai portului B ca pini de ieire.Dup generare i compilare programul funcioneaz exact cum am dorit,perioada semnalului putnd fi urmrit pe ociloscopul simulrii:

PWM generat de Timer-ul 2 Timer-ul 2 este asemntor cu timer-ul 1 diferena major fiind c el este doar pe 8 bii i c avem doar un singur canal de comparare la ieire(OC2).Configurarea i funcionarea generatorului PWM este asemntoare cu cea din Timer-ul 1 regitrii avnd form i nume diferit.Regitrii pe care i vom folosi sunt urmtorii: -Registrul TCNT2 ,registrul care numr fiecare impuls de ceas i care joac rolul de numrtor liber central al timerului. -Registrul TCCR2 care are rolul de a controla modul de funcoinare a timerului 2:

Bitul 7 nu l vom folosi pentru setarea generatorului aa c l vom seta 0. Bitul 6 i 3 (WGM20 i WGM21) sunt folosii la setarea modului de funcionare a timerului: WGM21 WGM20 0 0 Funcionare normal; 0 1 Funcionare ca PWM,numrarea se face n dou sensuri; 1 0 Funcionare ca CTC; 1 1 Funcionare ca PWM rapid,TCNT2-ul numr ntr-un singur sens; Biii 5 i 4 seteaz modul de funcionare al comparatorului: COM21 COM20 Modul PWM 00-Comparatorul dezactivat; 0 1-Combinaie rezervat; 10-TCNT2<=OCR2-1 logic la ieire,TCNT2>OCR2 -0 logic la ieire; 11-TCNT2<=OCR2-0 logic la ieire,TCNT2>OCR2 -1 logic la ieire; Biii 2,1 i 0 sunt folosii la prescalare timerului: CS22 CS21 CS20 000-Timer oprit; 001-Frecvena ceasului intern; 010- Frecvena ceasului intern prescalat cu 8; 011- Frecvena ceasului intern prescalat cu 32; 100- Frecvena ceasului intern prescalat cu 64; 101- Frecvena ceasului intern prescalat cu 128; 110- Frecvena ceasului intern prescalat cu 256; 111- Frecvena ceasului intern prescalat cu 1024; -Registrul OCR2, este registrul prin care setm factorul de umplere al semnalului generat. Pinul prin care prelum semnalul PWM este plasat pe portul B la pinul 3:

Urmtorul exemplu are ca scop modificara factorului de umplere a semnalului n funcie de anumite semnale de intrare.Pentru reglare vom folosi 3 butoane legate la primi 3 pini ai portului C n felul acesta avnd 8 trepte de reglare a factorului de umplere.Valoarea maxim pe care o poate avea POTRC-ul este 7 iar dac mprim 256 la 7 obinem aproximativ 36 deci valoarea lui OCR2 va fi PORTC*36.Vom folosi al doilea mod, modul PWM de numrare n ambele sensuri ,vom prescala ceasul 1024 i vom alege urmtoarea regul : TCNT2<=OCR2- 1 logic la ieire,TCNT2>OCR2 -0 logic la ieire.Regitrii vor avea urmtoarele valori: TCCR2 = 0b01100111; OCR2 = 0; Codul programului i simularea o putei downloada de la seciunea Download -PWM -Aplicaie 2. Schema electric este urmtoarea:

Cnd configurai proiectul n Code Vision AVR trebuie s avei grij ca primii 3 pini ai PORTC-ului s fie configurai ca pini de intrare iar pinul 3 al PORTB-ului s fie configurat ca pin de ieire.Pe lng acestea trebuie s configurai i timerul 2 n felul urmtor:

Dac rulai simularea vei putea modifica factorul de umplere n funcie de combinaia celor 3 butoane. Dup informaiile prezentate mai sus observm c microcontrolerul ATMega 8 poate genera 3 canale PWM n felul acesta putnd controla vitezele n mod diferit a 3 motoare de curent continuu. Cam att momentan despre generatorul PWM.

Convertorul Analog-Digital(AD)
09:59 C.C. No comments

Trimitei prin e-mail Postai pe blog! Distribuii pe Twitter Distribuii pe Facebook

Convertorul Analog Digital,dup cum i spune i numele, are rolul de a converti valorile semnalelor analogice n valori numerice.Semnalele analogice care intr n convertor pot proveni de la diverse dispozitive ns n cele mai multe cazuri acestea provin de la diveri senzori(senzori de lumina, temperatura,etc.). Pentru a putea folosi un convertor mai nti trebuie setat pragul minim i maxim de tensiune la care el funcioneaz.Convertorul microcontrolerului ATMega8 permite mai multe moduri de alegere a referinei de tensiune cum ar fi o referina extern prin pinul AVCC,intern egal cu cu tensiunea de alimentare sau intern egal cu 2,56V.n momentul folosirii ,convertorul trebuie legat i la mas, acest lucru fcndu-se prin pinul AREF. Acest convertor stocheaz valoarea tensiunii numeric ntr-un registru de 10 bii.Convertorul acestui chip are 6 canale de intrare care se gsesc pe portul C i sunt notate cu ADC(ADC0-ADC5).La un moment dat se poate citi doar un singur canal.Rezultatatul citirii va fi depus n regitrii de 8 bii ADCH i ADCL.Timpul de citire poate fi i el prescalat iar numrul de tacte necesare pentru citire este 13. Selecia referinei i a canalului se face prin registrul ADMUX care are urmtoarea form:

Biii 7 i 8 (REFS1 i REFS0) folosesc la selecia referinei astfel: REFS1 REFS0 00- Referin extern la pinul AREF; 01- Referin intern VCC cu rezisten i condensator la pinul AREF(R=1K i C=14pF ); 10- Referin intern ca la combinaia 0 1 ns reversat; 11- Referin intern de 2.56V cu rezisten i condensator la pinul AREF(R=1K i C=14pF ); Biii 2-0 (MUX3-MUX0) au rolul de a selecta canalul de unde va fi citit semnalul: MUX3 MUX2 MUX1 MUX0 0000 ADC0 ,pinul PC0 0001 ADC1 ,pinul PC1 0010 ADC2 ,pinul PC2 0011 ADC3 ,pinul PC3 0100 ADC4 ,pinul PC4 1110 1.3V 1111 GND Pinul 5,ADLAR are rolul de a selecta modul de scriere a valorii citite n regitrii ADCL i ADCH.Aceti regitrii sunt de 8 bii ns rezutatul este pe 10 bii, astfel se folosesc ambii regitrii pentru memorare n felul urmror:

Dac bitul ADLAR = 0 avem primul mod de reinere n care primii doi cei mai semnificativi bii sunt reinui n ADCH iar restul de 8 bii sunt reinui n ADCL.Dac ADLAR = 1 atunci primii 8 cei mai semnificativi bii sunt reinui n ADCH iar restul de 2 bii sunt reinui n ADCL.Modul doi de reinere se poate folosi atunci cnd dorim ca rezultatul s fie returnat pe 8 bii, caz n care putem citi doar registrul ADCH. Controlul convertorului se face prin registrul ADCSRA care are urmtoarea form:

Cel mai seminiciativ bit,bitul ADEN are rolul de a permite folosirea convertorului astfel dac ADEN = 1 convertorul

poate fi folosit. Bitul 6,ADSC, este folosit pentru a porni convertorul.Dac dorim s citim valoarea unei tensiuni la un moment dat se seteaz bitul ADSC=1.Acest bit rmne setat pn cnd se realizeaz conversia, dup conversie valoarea lui va deveni 0. Prin bitul 5,ADRF, se seteaz modul de citire al tensiunii,astfel dac ADRF=1 convertorul citete repetat valoarea tensiunii iar dac ADRF = 0 citirea se face doar cnd ADSC = 1. Pentru generarea unui semnal de ntrerupere n momentul terminrii conversiei trebuie ca bitul ADIF s fie 1.Bitul ADIE are valoarea 1 atta timp ct nu a fost trimis nici un semnal de ntrerupere.Dac s-a trimis o cerere de ntrerupere el devine 0 pn cnd se execut rutina de tratare.La terminarea execuiei rutinei ADIE ia valoarea 1. Ultimii 3 bii,ADPS2-ADPS0 au rolul de a prescala timpul de citire a tensiunii astfel: ADPS2 ADPS1 ADPS0 Prescalarea frecvenei 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 urmtorul: n partea de setare a programului se seteaz registri ADMUX,setnd referina,modul de citire i canalul i apoi se seteaz ADCSRA ,registru n care trebuie s avem mare grij ca cel mai semnificativ bit s fie setat. n partea de ciclare infinit trebuie s vedem cum am configurat citirea, periodic sau nu.Dac citirea se face periodic atunci nu ne rmne dect s citim valoarea

convertorului.Dac nu, citirea se face conform pailor: -pornim citirea:ADCSRA =ADCSRA | 0x40; -ateptm s se termine citirea: while(ADCSRA | 0x40 == 1); -citim valoarea convertorului; Valoarea returnat va fi un numr cuprins ntre 0 i 1024 dac citirea se face pe 10 bii sau ntre 0 i 256 dac citirea se face pe 8 bii.Precizia citirii se calculeaz n felul urmtor:

Unde P este precizia i Vref este tensiunea de referin care se poate mpri la 1024 sau 256 n funcie de numrul de bii ai registrului de stocare. Calcularea tensiunii efective se face dup urmtoarea formul:

Unde Tens reprezint tensiunea efetiv,Vcit reprezint valoarea returnat de convertor iar Vref tensiune de referin. n exemplul urmtor vom citi valoarea unei tensiuni i o vom afia pe un LCD.Schema electric este urmtoarea:

Progamul l putei downloada de la seciunea Download -Convertorul A/D -Aplicaie 1. nainte de scrierea programului , la partea de setarea a generrii codului vom avea

urmtoarea setare:

Important aici este s nu uitai partea de setarea a LCD-ului pe portul D. Dup generare, setrile dinaintea prii de ciclare vor fi urmtoarele: ADMUX=0x00; Adic referina va fi extern la pinu AREF,se citesc 10 bi din partea stng a registrului ADCH i se selecteaz canalul 1. ADCSRA=0x89; Adic se permite folosirea convertorului,se activeaz permisia trimiterii cererii de ntreruperea la terminarea citirii i se prescaleaz ceasul cu 2. Codul din bucla infinit este urmtorul:
ADCSRA |= 0x40; //pornim conversia while(ADCSRA&0x40); //astempam ca citirea sa se finalizeze adc_data = (adc_data*5*100)/1023; //calculam valoarea tensiunii //transformam valoarea obtinuta in sir valoare[0] = adc_data/100+48; valoare[1] = '.'; valoare[2] = (adc_data/10)%10+48; valoare[3] = adc_data%10+48; valoare[4] = '\0'; sprintf(linie1,"V=%s",valoare); //copiem valoarea in sirul linie1 //afisam rezultatul pe LCD lcd_clear(); lcd_gotoxy(0,0); lcd_puts(linie1); delay_ms(200); //asteptam 2 milisecunde

Aici microcontrolerul ncepe cu citirea tensiunii apoi se calculeaz valoarea efectiv a

tensiunii.Dup aceste operaii se transform valoarea din long n ir de caractere dup care se afieaz pe ecran rezultatul.

Afiajul LCD
15:20 C.C. 1 comment Trimitei prin e-mail Postai pe blog! Distribuii pe Twitter Distribuii pe Facebook

Pn acum ieirile microcontrolerului reprezentau nite LED-uri care puteau lua dou valori, 1 sau 0.Acest mod de afiare a informaiilor de ieire ale unui microcontroler nu este ntotdeauna mulumitor deoarece exist cazuri n care dorim s afim un numr sau un text.Acest lucru se poate realiza cu ajutorul unui afiaj LCD.Dimensiunea LCD-ului pe care l vom folosi n acest tutorial este de 2 linii i 16 coloane i se numete LM016L.Acesta se alimenteaz cu 5 voli i permite scrierea caracterelor alfanumerice principale. Transferul de date ntre microcontroler i LCD se poate face pe 4 sau 8 bii printr-un bus de date.Pe lng linile de date vom avea nevoie i de 3 linii de control: -E(Enable) care permite sau nu transmiterea de date i comenzi.Setnd acest linie 1 poate ncepe schimbul de date i comenzi ntre LCD i microcontroler. -R/W (Read/Write) are rolul de a stabili direcia datetelor,0 fiind pentru scrierea datelor iar 1 fiind pentru citirea datelor din LCD. -RS(Register Selec) folosete la selectarea regitrilor interni ai LCD-ului.Dac ia valoarea 0 nseamn c trimitem LCD-ului o instruciune iar dac scriem valoarea 1 nseam c trimitem date. De exemplu pentru scrierea unor date n LCD trebuie ca: E=1,R/W=0,RS=1. Toate aceste lucruri sunt mascate n CodeVision AVR singurul lucru pe care trebuie s i facem este s setm la nceputul proiectului portul prin care realizm conexiunea LCD-ului cu microcontrolerul i s includem biblioteca lcd.h.Se folosete trasferul de date pe 4 bii deoarece aceast metod salveaz 4 pini ai microcontrolerului.Legarea pinilor unui port cu pinii LCD-ului se face n felul urmtor: 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 Funciile cele mai utilizate pentru controlul i scrierea LCD-ului sunt urmtoarele: unsigned char lcd_init(unsigned char lcd_columns) realizeaz iniializarea LCD-ului, lcd_columns reprezentnd numrul de coloane ale LCD-ului, n cazul nostru 16; void _lcd_ready(void) ateapt pn cnd lcd-ul este gata s primeasc date.Avem nevoie de aceast funcie deoarece LCD-ului i trebuie un timp de iniializare dup ce a fost pus n funciune; void lcd_clear(void) terge tot ce este scris pe LCD i duce cursorul la linia i coloana 0; void lcd_gotoxy(unsigned char x, unsigned char y) seteaz cursorul la poziia x,y.Aienie, x reprezint coloana iar y reprezint linia; void lcd_putchar(char c) afieaz un caracter la poziia x,y curent.Dac avem mai multe

comenzi de acest gen nu nsemn c va scrie caracterul unul peste altul i va scrie pe coloana sau linia urmtoare. void lcd_puts(char *str) - afieaz un ir de caractere ncepnd de la poziia x,y curent; 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.Codul i schema aplicaiei o putei downloada de la seciunea Download-LCD-Aplicaie 1.Schema electric este urmtoarea:

n cazul de fa folosim portul D pentru transmisia de date i comenzi.La crearea proiectului n CodeVision AVR ,la partea de setare din wizard trebuie s mergem la panoul LCD , s alegem portul D i s selectm numrul de coloane al LCD-ului precum n figura de mai jos:

program nu vom face altceva dec s afim nite caractere nainte de intrarea n bucla infinit while: lcd_init(16); //initializam LCD-il _lcd_ready(); //asteptam ca lcd-ul sa poata primi date lcd_gotoxy(1,4); //megem la coloana a 2-a pozitia 5 lcd_puts(mesaj1); //afisam primul mesaj

delay_ms(2000); //asteptam 2 secunde lcd_clear(); //stergem caracterele de pe lcd lcd_puts(mesaj2); //afisam mesajul 2 pe linia si coloana 1 delay_ms(1000); //asteptam o secunda lcd_clear(); //stergem caracterele de pe lcd lcd_puts(mesaj3); //afisam mesajul 3 lcd_putchar('x'); //afisam caracterul x lcd_putchar('y'); //afisam caracterul y lcd_putchar(80); //afisam caracterul cu codul 80(P) Putei observa c pentru afiarea unor iruri de caractere am folosit o variabil de ir, mesaj, deoarece compilatorul nu ne las s scriem direct n funcie sirul.Declararea irurilor de caractere se poate face n program ,la nceputul funciei main sau n exterior ca variabile globale.n programul nostru avem: unsigned char* mesaj1 = "Test LCD"; unsigned char* mesaj2 = "LCD curatat"; unsigned char* mesaj3 = "Afisarea a 3 caractere:"; Funcionarea fizic a aplicaiei o putei vedea aici:

USART
11:13 C.C. No comments Trimitei prin e-mail Postai pe blog! Distribuii pe Twitter Distribuii 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.Acesta se poate folosi pentru comunicare n conjunce cu standardele RS-232,RS-422 sau RS-485 ns n aplicaiile noastre vom folosi doar standardul RS-232 pentru comunicarea cu PC-ul.Comunicarea serial presupune folosirea unei singure legturi dac ea este unidirecional, adic exist un trasmitor i un receptor sau invers.Dac este bidirecional avem nevoie de dou legturi , pe o legtur realizndu-se transmisia iar pe alta recepia.Dac se folosete modul sincron pe lng[ legturile de transmisie a datelor se mai folosete o legtur prin care se stabilete acela semnal de tact ntre dispozitive.Schema de principiu este urmtoarea:

Dispozitivu l care transmite date se numete master iar cel care primete se numete slave.De obicei masterul stabilete formatul cuvntului i frecvena ceasului iar datele furnizate se vor obine la pinul TX.Slave-ul va trebui configurat astfel nct s primeasc cuvinte care au acela format cu cele generate de master i s funcioneze la aceeai frecven.Pinul prin care un dispozitiv primete date este pinul RX. Viteza de transmisie a datelor se msoar in BAUD , unitate care reprezint numrul de bii transmii ntr-o secund.Aceast vitez trebuie s fie egal ntre dispozitivele care comunic

serial.La transmisia asincron pot aprea diverse erori deoarece frecvenele de tact pot fi puin diferite chiar dac ele sunt setate aparent egal.Acest neajuns este nlturat la transmisia sincron deoarece semnalul de tact generat de master este transmis slave-ului prin legtura XCK. Momentan ne vom concentra pe transmisia asincron deoarece ea este cea mai folosit la comunicarea ntre dispozitivele periferice i PC,avnd doar dou legturi. Transmisia asincron Dup cum am vzut mai sus pentru ca aceast transmisie s fie bidirecional trebuie s folosim dou conexiuni, una prin care trimitem i una prin care primim datele. Cuvntul care este trimis este format din dou pri , o parte care reprezint datele iar alt parte care reprezint codul de
verificare:

Orce cuvnt ncepe cu un bit de start care trebuie s fie 0.Urmtorii bii sunt biii de date care pot avea o lungime ntre 5 i 8 bii iar la sfrit avem un bit de stop care ntodeauna trebuie s fie 1. Microcontrolerul ATMega8 poate trimite urmtorul format de cuvnt:

Pri mul bit St reprezint bitul de start.Lungimea cuvntului de date poate fi cuprins ntre 5 i 9 bii.Pentru o mai bun securitate n transmisie se poate seta la sfritul cuvntului de date un bit de paritate care verific paritatea biilor de date.Sfritul cuvntului poate fi reprezentat de unul sau doi bii care trebuie s aib valoarea 1.Transmitorul sau receptorul sunt libere doar atunci cnd s-au transmis biii de stop i sunt n stare Idle, stare care este reprezentat de 1 logic pe linile de conexiune. La configurarea a dou dispozitive care vor comunica serial asicron trebuie s avem grij ca viteza de transfer s fie egal la transmisie i recepie i s avem aceeai lungime a cuvntului de date.De asemenea trebuie totui s stabilim dac folosim verificarea paritii i dac folosim unul sau doi bii de stop. Principala surs de eroare poate aprea atunci cnd configurarea ntre dispozitive nu este fcut corect, aceasta fiind o problem de incompatibilitate n comunicare.Alte erori pot fi generate pe linile de transmisie, ele putnd fi detectate prin bitul de paritate sau prin biii de stop. La transmiterea sau recepia a mai multor cuvinte consecutive trebuie verificat dac USART-ul a realizat operaia complet de trimitere sau citire, altfel poate aprea o alt eroare de transmisie generat de data asta de partea soft. Schimbul de date se face prin doi regitrii, unul n care se nscriu datele i unul de iftare prin care se transmite cuvntul.n ATMega8 datele se scriu sau se citesc din registrul UDR.De exemplu pentru transmiterea unui caracter char pe 8 bii trebuie s scriem caracterul n UDR.USART-ul va trece automat coninutul lui UDR n registrul serial apoi l va transmite pe linia de legtur celuilalt dispozitiv care va prelua datele tot n registrul serial al crui coninut va fi transmis registrului UDR.Registrul serial,dac dispozitivul este configurat ca transmitor, va pune pe lng date i bitul de start , bitul de paritate i bitul/biii de final.Dac dispozitivul este configurat ca receptor, registrul serial va verifica dac transmisia este corect i dac da datele

cuvntului vor fi copiate n UDR. Regitrii folosii n ATMega8 pentru comunicarea serial sunt urmtorii:
-Registrul UDR care are rolul de a stoca datele necesare pentru transmisie sau recepie:

Dac se realizeaz transmisia, datele sunt stocate n TXB iar dac se realizeaz recepia datele se gsesc n RXB. -Registrul UCSRA:

Bit ul 7 RXC- indic starea registrului de recepiei.Dac nc se mai primesc date valoarea lui este 1 iar dac recepia a fost efectuat complet valoarea lui este 0. Bitul 6 TXC- indic starea registrului de transmisiei.Dac nc se mai transmit date valoarea lui este 1 iar dac transmisia a fost efectuat complet valoarea lui este 0. Bitul 5 UDRE indic dac UDR poate fi citit sau scris.Dac este 1 UDR poate fi scris, dac este 0 nu se pot efectua operaii cu acest registru. Aceti 3 bii pot genera ntreruperi care pot fi tratate n rutine speciale . Bitul 4 FE Detecteaz dac exist erori la transmiterea cuvntului verificnd bitul/biii de final.Dac acest/aceti bii au o valoare diferit de 1 atunci bitul FF ia valoarea 1.Dac totul este n regul atunci valoarea lui FE va fi 0. Bitul 3 DOR - Detecteaz dac exist erori de suprascrierea USAR-tului.De exemplu la recepie poate aprea o astfel de eroare dac UDR i registrul serial este plin i alt caracter este pe cale de a fi primit.FE este 1 dac s-a semnalat o astfel de eroare i 0 dac nu avem o eroare de acest fel. Bitul 2 PE are rolul de a detecta eroarea de paritate.Dac s-a detectat o astfel de eroare ia valoarea 1 iar dac nu valoarea lui va fi 0. Bitul 1 U2X Acest bit este 1 dac dorim s dublm viteza de transmisie n modul asicron i 0 dac se folosete viteza normal.Acest bit trebuie s aib ntotdeauna valoarea 0 dac este folosit modul sincron. Bitul 0 U2X- Se seteaz 1 dac se folosete comunicarea multiprocesor i 0 dac se folosete comunicarea uniprocesor.In exemplele ce vor urma l vom seta ca 0. -Registrul UCSRB:

Bitul 7-RXCIE 1 seteaz generarea unei ntreruperi la terminarea recepiei,0 ntreruperea nu

este flosit. -Bitul 6-RXCIE 1 seteaz generarea unei ntreruperi la terminarea transmisiei,0 ntreruperea nu este flosit. -Bitul 5-RXCIE 1 seteaz generarea unei ntreruperi atunci cnd registrul UDRIE poate fi folosit,0 ntreruperea nu este folosit. -Bitul 4- RXEN 1 seteaz USART-ul ca receptor. -Bitul 3- TXEN 1 seteaz USART-ul ca Transmitor. -Bitul 2- UCSZ2 se folosete mpreun cu o parte din biii registrului UCSRC dup cum vom vedea mai jos. -Bitul 1 RXB8 este al 9-lea bit din schimbul de date pe 9 bii i se folosete la recepie. -Bitul 0 TXB8 este al 9-lea bit din schimbul de date pe 9 bii i se folosete la transmisie. -Registrul UCSRC:

-Bitul

7 URSEL- se folosete pentru selecia regitrilor astfel:1 dac se lucreaz cu registrul UCSRC i 0 dac se lucreaz cu registrul UBBRH. -Bitul 6 UMSEL-Prin acest bit se seteaz modul de funcionare al USART-ului:1 dac funcioneaz n modul sincron i 0 dac funcioneaz n modul sincron. -Bitul 5 i 4 UPM1 i UPM0 Se folosesc pentru selecia paritii: UPM1 UPM0 00 - Nu se folosete bitul de paritate. 01 - Combinaie rezervat. 10 - Se folosete bitul de paritete ca bit par. 11 - Se folosete bitul de paritete ca bit impar. -Bitul 3 USBS- se folosete pentru a seta numrul biilor care reprezint sfritul cuvntului: 1se seteaz doi bii de stop,0-se seteaz un singur bit de stop. -Biii 2 i 1 UCSZ1 i UCSZ0- se folosesc mpreun cu UCSZ2 din UCSRB pentru a seta lungimea cunvntului de date: UCSZ2 UCSZ1 UCSZ0 Lungimea Cuvntului 000 5 bii; 001 6 bii; 010 7 bii; 011 8 bii; 100 Combinaie rezervat; 101 Combinaie rezervat; 110 Combinaie rezervat; 111 9 bii; -Bitul 0 UCPOL-Se folosete pentru modul sincron i seteaz ce front al semnalului de pe linia XCK va fi folosit n transmisie.n modul asincron acesta se seteaz 0.Valorile pe care le poate lua sunt urmtoarele:0 se folosete frontul cresctor, 1 se folosete frontul descresctor.

-Registrul UBRR Acest registru se folosete pentru a seta viteza de transmisie a datelor.

-Bitul 15 URSEL trebuie s fie 0 atunci cnd se efectueaz operaii cu acest registru. -Biii 12,13,12 sunt nite bii rezervai nefolosii n acest microcontroler. -Biii 11:0 sunt folosii pentru a seta viteza de transmisie a datelor.Totui setarea se face doar cu biii cei mai semnificativi, 11:8.Viteza de transmisie a datelor se calculeaz dup formula:

Unde BAUD reprezint viteza de transmisie msurat n Baud,f_int reprezit frecvena intern a procesorului iar UBBR este valoarea setat n registru. Eroarea la transmisie se calculeaz dup formula:

n tabelul de mai jos putem urmri ce influen are frecvena asupra erorii la transmisie:

Urmtorul exemplu are ca scop schimbul de date ntre microcontrolerul ATMega8 i PC.Citirea i trimiterea de date de la PC la microcontroler o putei face cu un program ca HiperTerminal.Datele pe care le va primi microcontrolerul le vom afia pe un LCD.Transmisia de date se va face asincron ,lungimea cuvntului de date va fi de 8 bii , vom folosi un singur bit de stop iar viteza de transmisie va fi de 4800 baud. Programul l putei downloada de la seciunea Download -USART -Aplicaie 1. nainte de a ncepe transmisia toate aceste setri vor fi fcute n regitrii USART-ului dup cum urmeaz: UCSRA=0x00; UCSRB=0x98; UCSRC=0x86; UBRRH=0x00; UBRRL=0x0C;
Schema electric a aplicaiei este urmtoarea:

Pentru a simula PC-ul am folosit o unealt oferit de Proteus numit Virtual Terminal.Aceasta mpreun cu ociloscopul se gsesc n partea dreapt a ferestrei la butonul Virtual Instruments Mode. La seciunea de generare a codului trebuie s setai LCD-ul pe portul D, pinul 0 al portului D ca pin de intrare, pinul 1 al portului D ca ieire i USART-ul dup cum urmeaz:

Pentru recepie am folosit ntreruperea deoarece dorim s afim caracterul pe LCD imediat ce el a fost primit. n partea de ciclare infinit a programului vom trimite date PC-ului: while(1) { //trimitem toate caracterele ASCII catre computer caracter ++; printf("%c",13); printf("%c",caracter); delay_ms(150); }; Observm c trimiterea de date se face foarte simplu cu ajutorul funciei printf().Afiarea

caracterelor pe LCD se face n rutina de tratare a ntreruperii generate de recepia datelor dup cum urmeaz: nr_caractere++; lcd_putchar(data); if(nr_caractere > 15) { lcd_clear(); nr_caractere = 0; } Afiarea se face pe o singur linie.Dac s-a ajuns s se scrie 16 caractere pe LCD , adic s se completeze prima linie, LCD-ul este curat.Dac simularea funcioneaz cum trebuie ar trebui s v afieze cam aa:

Pentru a trimite date microcontrolerului trebuie s dai click pe Virtual Terminal i s tastai caractere. Fizic , pentru a se putea realiza conexiunea este nevoie de un integrat MAX232 care face legtura ntre microcontroler i cablu serial astfel:

Momentan cam att despre USART.

Structura unui program scris pentru un microcontroler


12:09 C.C. No comments

Trimitei prin e-mail Postai pe blog! Distribuii pe Twitter Distribuii pe Facebook Structura unui program scris pentru un microcontroler este puin diferit de structura programelor scrise pentru un calculator de uz general.Primele linii dintr-un program vor reprezenta bibliotecile pe care le utilizm n cadrul aplicaiei.Urmtoarea seciune va fi reprezentat de declararea variabilelor globale i de declararea/definirea funciilor program.Apoi urmeaz funcia main, funcia principal din program, cea care este prima executat la rularea programului.n aceast funcie mai nti se declar variabilele locale, dac este nevoie ,apoi se fac setrile diferitelor funcii ale microcontrolerului.n ultima parte a funciei main se va crea o bucl infinit lucru care n mod normal nu ar fi dorit n programele scrise pentru calculatoarele personale.n aceast bucl are loc ntreaga parte de prelucrare a datelor, restul fiind partea de setare.Atenie mare, funciile microcontrolerului nu nsemn acela lucru cu funciile programului.De exempu pentru chipul ATMega8 programul ar trebui s urmeze modelul: //partea de includere a bibliotecilor utilizate #include mega8.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 } } Cnd microcontrolerul este pornit mai nti se va realiza setrile funciilor chip-ului prin regitrii de setare apoi el va cicla codul din bucla while pn cnd apare un eveniment neateptat cum ar fi oprirea sursei de alimentare sau apariia unei ntreruperi. Avatajul folosirii wizardului din CodeVision AVR este c el genereaz cod pentru structura de mai sus ,setrile micorcontrolerului putnd fi fcute vizual.De asemenea wizardul ofer i explicaii referitoare la setrile pe care le-a realizat.

ncrcarea programului n microcontroler


11:30 C.C. No comments Trimitei prin e-mail Postai pe blog! Distribuii pe Twitter Distribuii pe Facebook

Copierea programului n memoria flash a microcontrolerului se face cu ajutorul programului PonyProg , program pe care putei s l descrcai de la seciunea Download.nainte de a deschide programul i de a alimenta placa se vor face conexiunile ntre pinii microcontrolerului

i pinii programatorului dup schema urmtoare:

Pinii microcontrolerului la care va trebui s legai pinii programatorului i vei putea gsi n schema de mai jos:

Dup cum vedem pinul PC6 trebuie legat la RESET,PB5 la SCK,PB4 la MISO,PB3 la MOSI, +5V la tensiunea de alimentare iar GND la mas. Dup ce ai fcut toate conexiunile urmeaz s conectm placa la portul serial.Acest lucru se face printr-un cablu de legtur serial.Portul COM1 l gsii n spatele calculatorului el artnd cam aa:

Acum cnd toate conexiunile sunt fcute putei alimenta placa i porni programul PonyProg.

Dup ce ai deschis programul va trebui s l configurai pentru a putea face legtura serial cu placa.Pentru configurare megei n meniu la Setup>Interface Setup.Aici selectai modul Serial i COM1(sau COM2 , depinde pe care dorii s l folosii).

Acum c setrile sunt fcute urmeaz s copiem programul nostru in memoria microcontrolerului.Mai nti va trebui s ncrcm codul n PonyProg apsnd File>Open Program Flash File selectnd extensia *.hex i aleagnd fiierul din directorul Exe corespunztor.Aici am folosit numele directorului Exe deoarece am presupus c programul a fost compilat cu Code Vision AVR , el genernd codul ntr-un astfel de director.

Urmtorul pas este selectarea chip-ului pe care vom ncrca programul.Aceast setare se face din bara plasat sub meniu.

n prima caset selectai AVR micro iar n a doua Atmega8.nainte de ncrcare mergei n meniu la Command > Erase pentru a terge toate datele din memoria microcontrolerului. Operaia de ncrcare propriuzis pe chip se face tot din meiniu prin alegerea Command >Write All.Dac totul a decurs cum trebuie vei primi un mesaj cum c totul este ok.

Realizarea fizic a aplicaiei


08:34 C.C. No comments Trimitei prin e-mail Postai pe blog! Distribuii pe Twitter Distribuii pe Facebook

Pentru simularea fizic a aplicaiilor putei alege dou ci, una uoar i mai scump i una grea i puin mai ieftin.Prima ar fi s achiziionai de la o firm de componente electronice o plac de dezvoltare gata fcut pe care s putei monta un microcontroler ATMega8.Totui unele diferene vor exista ntre posibilitile pe care le ofer placa pe care sunt simulate aplicaiile n acest tutorial i plcile achiziionate din magazin, ns nu foarte mari, fiecare plac putnd fi adaptat pentru diferite sarcini.A doua posibilitate ar fi s v creai propria plac de dezvoltare asemntoare cu placa pe care se testeaz aplicaiile din acest tutorial.Dac dorii s creai o plac identic cu placa mea putei ncerca s o creai dup detalile pe care vi le voi prezenta mai jos. Prima dat avei nevoie de schema de imprimare i o plac de plastic care are una sau dou pelicule( fa verso sau doar fa) de cupru.Mai avei nevoie i de o bucat de smirghel fin cu care s smirgheluii placa foarte bine.Dup aceast operaie ea trebuie curat cu spirt industrial.Toate aceste operaii sunt necesare deoarece pe plac vom imprima un circuit.La final placa ar trebui s arate cam aa:

Schema pe care o vei imprima o putei descrca de la sectiunea Download -Tutoriale AVR -Schem Plac. Trebuie s precizez c aceast schem NU trebuie imprimat n oglid,ea fiind plasat direct aa cum e pe plac, fiind deja n oglind.Acest lucru este important s l spunei dac mergei la o firm de imprimeuri. Imprimarea este o operaie dificil dac dorii s o facei acas.Se poate face cu o imprimant, o folie special care va fi plasat pe plac si un fier de clcat care v ajut la trecerea imprimeului dup folie pe pelicula de curpru.Totui aceast operaiune este destul de delicat, n consecin v-a recomanda s mergei la o firm care realizeaz imprimeuri.

Dup ce ai realizat imprimarea schemei pe plac va trebui s crem circuitul fizic prin corodare cuprului nefolositor.Avei nevoie de Clorur Feric, soluie pe care o putei gsi tot ntr-un magazin de componente electronice, i de un recipient n care s turnai o parte din soluie amestecat cu ap cald.Putei s punei i ap rece ns temperatura apei va spori procesul de corodare.Recipientul pe care l vei folosi ar fi bine s nu fie din metal pentru a se evita distrugerea lui.

inei placa n aceast soluie 10-20 de minute pn cnd se ndeprteaz ntreaga pelicul de cupru nefolositoare rmnnd astfel doar circuitul.Dup ce terminai operaia v-a sftui s nu aruncai soluia n sistemul de conducte al bii deoarece ea este extrem de coroziv i v poate ataca evile.Cel mai bine ar fi sa o punei ntr-o sticl i s o aruncai la un co de gunoi din exterior.Dac pn aici toate sunt bune i frumoase urmeaz s dai guri plcii.Gurile se pot da cu o bormain mic dar nainte s le dai ar fi bine s tanai locurile n care vei plasa burghiul pentru o mai mare precizie n momentul cnd gurii placa.

Dac circuitul imprimat este mai mic dect placa v recomand s decupai prile nefolositoare cu un bomfaier sau un flex. Din pcate nu dispun de schema electric ntr-un program CAD, ns v voi pune la dispoziie schema electric de imprimare cu componentele electronice pe ea .Pentru a mri poza dai click

pe ea:

Componentele de care vei avea nevoie pentru montaj sunt urmtoarele: un microcontroler ATMega8+slot,un integrat MAX232 pentru conexiunea serial +slot,9 LED-uri(20mA),un L7805 stabilizator de tensiune de 5 voli,4 poteniometre de 10K, 4 butoan fr reinere i 4 cu reinere,8 rezistene de 10 ohmi,13 rezistene de 1K,8 rezistene de 470 ohmi,2 rezistene de 10K,2 rezistene de 4,7K, o rezisten de 15K,o diod 1N4148, 2 diode zener de 5V, un tranzistor BC549, 2 condensatori electrolitici de 1 microfarad i unul de 0.1 microfarazi, 2 conectori pentru portul serial cu pinii n jos, un conector de alimentare cu 2 intrri i mai multe iruri de pini (aprox. 120 de pini) pe care le vei tia n funcie de numrul de guri de la ieirea integratelor. Sfatul meu ar fi s dai n linie dreapta gurile unde vor fi montate irurule de pini, deoarece v va fi mai uor s montai pinii.V-a mai sftui s avei mare grij la montarea elementelor cu polaritate astfel plusul s fie la plus i minusul la minus,aici m refer la LED-uri i la condensatori. Pentru lipirea pieselor pe circuit avei nevoie de un pistol de lipit,nite fludor i nite sacz.Cnd facei lipiturile trebuie s avei grij s nu lipii dou componente de circuit care nu au legatur pe schem, altfel putei s legai plusul de minus i circuitul s se nchid fr ca el s aib consumator, n felul acesta riscnd s ardei stabilizatorul de tensiune. Pentru a v face idee cum trebuie s arate piesele montate pe plac avei aici dou fotografi cu ambele pri ale plcii,partea de lipituri i partea de componente:

Dac ai terminat de fcut toate lipiturile ar fi bine s verificai circuitul ca nu cumva s avei lipituri incorecte.nainte s punei circuitul sub tensiune se vetific mai nti la bornele stabilizatorului dac rezistena este diferit de 0 apoi se verific din punct n punct ntre elemente dac au sau nu rezistena 0.Dac rezistena este 0 nseamn c avem o lipitura incorect i ea trebuie nlturat.Dup ce toate conexiunile greite au fost nlturare putei alimenta placa.Sursa de tensiune poate fi o surs de calculator.Mufa principal de alimentare a unei surse model ATX arat cam aa:

Pentru a porni sursa trebuie s legai pinul PS_ON# la COM(mas).Pentru a porni placa trebuie s legai la plusul stabilizatorului de teinsiune de pe placa creat anterior ieirea sursei 12VDC(firul galben) iar minusul la ieirea COM (firul negru).Dac toate sunt n regul ar trebui s se aprind LED-ul de lng stabilizatorul de 5V.Ar fi bine s urmrii stabilizatorul s vedei dac se nclzete iar dac da deconectai repede circuitul de la alimentare deoarece avei o problem pe care nu ai rezolvat-o. Conexiunile ntre pini se pot face cu fire subiri.La capetele acestor fire vor fi legai cu fludor nite papuci de conexiune.Pentru protecie ,aceste legturi ntre papuci i fir vor trebui izolate cu tub termocontractant sau band izolir.Firele le putei face rost cumprnd un metru de cablu de alarm pe care l vei desface.Papucii i putei gsi tot n magazinele de componente electronice ns cnd i cumprai trebuie s avei grij s se potriveasc cu pinii irurilor de pini. Prezentarea plcii o putei urmri aici: Cam attea ar fi despre placa de dezvoltare.O soluie pe care am uitat s o precizez ar fi folosirea unui breadboard pe care s montai circuitul n funcie de aplicaie. Breadboard arat cam aa:

Linile din mijloc i coloanele + i sunt legate n serie.n felul acesta putei crea un circuit destul de simplu avnd la dispoziie componentele electronice i nite fire cu care s le concetai.

Unelte Software
06:51 C.C. No comments Trimitei prin e-mail Postai pe blog! Distribuii pe Twitter Distribuii pe Facebook

Uneltele software pe care le vom folosi n dezvoltarea aplicaiilor pot fi download-ate de la seciunea Download-Software.n continuare ele vor fi prezentate pe rnd: CodeVision AVR CodeVision AVR este IDE-ul cu care vom scrie codul surs al programelor care vor rula pe microcontrolerul ATMega8.Modul de lucru este prezentat mai jos: Dup ce pornii programul CodeVision AVR ar trebui s avei urmtoarea fereastr:

Bun, dac arat ca aici nseamn c totul este n regul.n continuare vom vedea cum se creaz un proiect si cum se genereaz automat codul. Pentru crearea unui nou proiect megei la File-New Project, alegei Project i apsai OK.

Dup ce apsai OK v va ntreba dac dorii s folosii CodeWizardAVR, apsai Yes.Urmtoarea etap va fi de setare a funciilor microcontrolerului:

Alegei la Chip ATmega8 i setai frecvena de 1MHz.Dup aceea mergei n meniu la File i apsai Generate,Save and Exit, apoi vei alege locaia i vei da nume fiierelor proiectului.Dac pn aici totul este bine ar trebui s avei un cod asemntor:

Pentru compilare va trebui s mergei n meniu i s setai Project> Build All.Ca rezultat al compilrii vom gsi n directorul n care ai salvat proiectul un director care se numete Exe.n director vei gsi un fiier cu extensia *.hex.Acest fiier reprezint codul care va fi ncrcat n microcontroler. Bun, dac ai fcut toate acestea nseamn c ai realizat primul dumneavoastr proiect n CodeVision AVR. ISIS Proteus Pentru a simula orce aplicaie din acest tutorial deschidei ISIS Proteus.La nceput s-ar putea s v ntrebe dac dorii s ncrcai un exemplu, n acest caz alegei nu.Observm c n dreapta avem plana de lucru,n stnga o list de unelte iar sus meniul:

Pentru a exemplifica modul de funcionare al programului voi crea o schem simpl i anume un led care va fi aprins prin apsarea unui buton.Pentru acest proiect avem nevoie de un buton ,de un led, de o surs de tensiune i de o rezisten pentru a limita curentul prin circuit.Mai nti vom aduce aceste piese din librrie n partea stng, n lista DEVICES.Pentru a aduce elementele n list megei n meniu la Library i selectai Pick Device/Symbol sau apsai butonul P de lng DEVICES.Va aprea o fereastr n care va trebui s selectai componentele.Mergei n stnga sus la cmpul Keywords i scriei button.Ca rezultat vom avea 2 dispozitive ca n figura de mai jos:

Dai dubluclick pe BUTTON pentru a fi adugat n lista din dreapta de dispozitive.

Procedai asemntor i pentru alegerea rezistorului i a LED-ului.Pentru rezistor cutai la Keywords cuvntul resistor iar pentru LED cutai LED-BIBY.Dup ce ai ales componentele nchidei fereastra pentru c urmeaz s alegem sursa de tensiune.Pentru acest lucru mergei n stnga i selectai butonul Generator Mode.

Din lista de generatoare selectai DC adic sursa de tensiune continu,apoi plasai aceast surs n plaa de lucru.Totui pentru circuitul nostru avem nevoie i de conexiunea la mas(GROUND).Aceasta o putei obine tot din stnga de la butonul Terminal Mode.

Selectai ground i plasai-l n fereastra de lucru.Pn acum avem sursa de tensiune continu i masa.

Tensiune de lucru a microcontrolerului ATMega 8 este de 5 voli, deci pentru uurin vom seta i tensiunea sursei pentru aplicaia curent tot 5 voli,urmnd ca la majoritatea aplicaiilor 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.

Bun, circuitul nostru mai are nevoie de LED i rezistena de limitare a curentului n circuit.n lipsa rezistenei curentul ar crete i ar distruge sursa chiar dac simularea funcioneaz i fr ea.Valoarea rezistenei va fi 1K, astfel vom avea un curent de 5 miliamperi. Pentru plasarea rezistenei i a LED-ului vom alege din dreapta butonul Component Mode:

Vom plasa butonul,rezitena i LED-ul ntre surs i mas.Componentele se vot roti prin click dreapta-Rotate iar legturile ntre elemente se fac prin ducerea creionului n dreptul elementului i trasarea liniei pn la elementul urmtor.Setarea rezistenei se face prin apsarea dublului click pe ea i nscrierea valorii dorite n cmpul Resistence.Schema final ar trebui s arate cam

aa :

Totui dac dorii o intensitate mai mare a LED-ului putei scdea valoarea rezistenei ns acest lucru va duce la un consum mai ridicat. Pentru a simula schema creat apsai butonul Play din stnga paginii jos.

Dac totul este n regul vei putea vedea led-ul aprins la apsarea butoului:

Cam acestea sunt bazele mediului Proteus, asemntor putnd crea simulri pentru fiecare aplicaie pe care o vom dezvolta pe parcursul tutorialului.

You might also like