Lab5.MP.Cuhai.D

12
Ministerul Educatiei al Republicii Moldova Universitatea Tehnica a Moldovei Facultatea Microelectronica si Ingineria Biomedicala Raport Lucrare de laborator Nr.5 Disciplina :Microprocesoare Tema: Initierea in programarea MCU in C. A efectuat : st.gr.MN-111, Cuhai Daria

Transcript of Lab5.MP.Cuhai.D

Page 1: Lab5.MP.Cuhai.D

Ministerul Educatiei al Republicii MoldovaUniversitatea Tehnica a Moldovei

Facultatea Microelectronica si Ingineria Biomedicala

Raport

Lucrare de laborator Nr.5

Disciplina :Microprocesoare

Tema: Initierea in programarea MCU in C.

A efectuat : st.gr.MN-111, Cuhai Daria

A verificat : lect.super., Bragarenco Andrei

Chisinau 2013

Page 2: Lab5.MP.Cuhai.D

Scopul lucrarii: Initierea in programarea microcontrolerelor in limbajul C. Programe cu intrerupere in limbajul C. Mixare cod ASM cu cod C.

Sarcina lucrarii: Sa se realizeze un program in C pentru MCU, care ar permite citirea unei taste introduce de la o tastatura telefonica si afisarea caracterului la un afisor cu 7 segmente. Detectarea tastei se va face cu intreruperea INT0. Transcodificarea codului tastei se va realiza cu o subrutina definite in ASM si apelata din cadrul realizarii in cod C.

Consideratii teoretice:Limbajul C este un limbaj de programare structural, care permite scrierea de programme, prin

identificatori, cuvinte cheie, numere, operatori, care se organizeaza intr-un program urmind anumitenreguli de sintaxa.

Limbajul C, deși este un limbaj de nivel înalt, păstrează contactul cu partea hardware a unui microcontroller. Printre facilitățile pe care le oferă limbajul C putem enumera : facilitate pentru manipularea biților, a câmpurilor de biți, manipularea funcțiilor cu pointeri la funcții precum și adresarea directă a memorie.

Structurile de date pot fi : Locale – sunt vizibile doar in cadrul blocului in care sunt definite; Globale – sunt vazute din orisicare punct al programului;

Resursele globale se vor localiza in memoria de programme, sau in memoria operative. Structurile locale se localizeaza in zona stivei si durata lor de viata este limitata de durata executiei blocului in care sunt definite.

Vor exista 8 tipuri predefinite ale variabilei. O variabila este un obiect, care presupune ca-si schimba valoarea sau poate fi modificata pe parcursul executiei programului. Pentru limbajul C variabila va avea urmatoarele proprietati:

Nume (identificatorul obiectului); Adresa (locatia la care a fost rezervata memoria); Tip (volumul de memorie rezervat si modul de lucru cu variabila);Tipurile de variabile de baza (predefinite): Char (1 byte) -128….127 Unsigned char (1 byte) 0…255 (ASCII) Int (2 bytes) -32768….32767 Unsigned int (2 bytes) 0…65535 Short int (2 bytes) jumatate de cuvint masina Long int (4 bytes) cuvint masina dublu Float (4 bytes) ±1,76E-38….±3,40E+38 Double float (8 bytes) 1,7E-308….1,7E+308Specificatori in limbajul C:

Extern (declaratia definita in exterior si permite referirea catre aceasta) Auto (ceva automat, global) Static (variabile locale) Register (variabila de tip registru, int-2 reg., char-1 reg.) Const (variabile constant in memoria de program) Volatile (se schimba repede, poate fi folosita de mai multe functii in paralel)

Pentru AVR , există multe compilatoare C, insa noi vom utiliza WinAVR CCG - compilator de optimizare puternic . Opensorts complete , cross-platform , în general , toate bucuriile vieții . Cu toate acestea, este perfect integrat în AVR Studio permite de a depana chiar acolo.

În primul rând , vom adăuga bibliotecile și antetele necesare cu definițiile . Deoarece C este un limbaj universal , și trebui e să explice exact ceea ca avem de lucru cu AVR , așa că inscriem biblioteca

# include <avr/io.h>#include<avr/interrupt.h>//pentru lucrul cu intreruperile Acest fișier este în WinAVR și conține o descriere a tuturor registrelor și porturile

microcontrolerului.

Page 3: Lab5.MP.Cuhai.D

Funcția principală .Programul este scris în C este format din toate funcțiile . Ele pot fi imbricate și pot fi invocate unele

de altele , în orice ordine și cu diferite metode . Fiecare funcție are trei parametrii necesari :1. Valoarea retur , de exemplu , sin ( x ) returneazăsinusul X. 2. Parametrii de transfer , în același X.3. Corpul funcției .Toate valorile sunt transmise și returnate trebuie să fie de orice tip , în funcție de datele .Fiecare

program C trebuie să aibă o funcție main ca un punct de intrare principal în Programul principal. Deci, noi definim :

int main ( void){return 0 ;}Limbajul “C” este cel mai folosit HLL (High Level Language) pentru microcontrolere. Deoarece

majoritatea arhitecturilor de microcontrolere sunt proiectate pentru a fi programate în limbaj de asamblare, susţinerea pentru instrucţiunile de “C” este deficitară. ATMEL a dorit dezvoltarea unei arhitecturi care să fie eficientă atât pentru limbajul “C”, cât şi pentru asamblare. Cooptarea în echipă a mai multor experţi de “C” a făcut posibilă realizarea unui cod foarte eficient pentru microcontrolerele de 8 biţi cu suport de 16 biţi.

În programarea în “C”, o regulă importantă este aceea de a folosi variabile definite într-o rutină (local), în locul folosirii variabilelor globale declarate pentru întregul program. Variabilele locale vor aloca memorie RAM doar atunci când se execută o rutină specifică în timp ce variabilele globale ocupă memoria RAM în permanenţă. Pentru a utiliza variabilele locale rapid şi eficient sunt necesare o mulţime de registre de uz general. AVR-ul are 32 registre de uz general, toate legate la ALU (Aritmetic Logic Unit), permiţând instrucţiuni într-un singur ciclu. Figura 2 arată cât de eficiente pot fi mai multe registre în comparaţie cu arhitecturile tradiţionale CISC cu un singur acumulator.

Figura 2.

Trei perechi ale celor 32 de registre pot fi folosite ca pointere pe 16 biţi permiţând salturi şi apelări indirecte asemănător cu multe moduri de adresare a memoriei de date în “C”. În plus, stiva pentru adresa de “return” este disponibilă prin instrucţiune. Cele mai multe arhitecturi de microcontrolere deţin doar 1 ÷ 2 acumulatoare şi 1 ÷ 2 pointere.

Din moment ce pointerele sunt foarte frecvent folosite în “C”, operaţiunile cu pointere sunt foarte importante din punct de vedere al vitezei şi dimensiunii de cod. AVR-ul are moduri de adresare care pre-incrementează şi post-decrementează în mod direct pointere când se accesează memoria de date.

Figura 3

Page 4: Lab5.MP.Cuhai.D

În plus, operaţiunile tabelare şi de acces stivă pot fi realizate eficient folosind deplasamente (raportate la valoarea curentă a pointerului) după cum se arată în figura 3. Deplasamentele variază între 0 ÷ 64 octeţi; analize detaliate arată că variaţia este suficientă pentru majoritatea operaţiilor în structuri şi tabele. Şi în plus aceste instrucţiuni au un singur cuvânt şi se execută într-un singur tact!

Pentru a schimba pointerele altfel decât prin pre-decrementare şi post-incrementare sunt implementate operaţiuni de adunare şi scădere între un pointer de 16 biţi şi o constantă. Acestea au un singur cuvânt şi se execută într-un singur tact. Cele trei pointere pot fi de asemenea utilizate ca 8 registre de uz general pe 8 biţi sau ca trei registre de uz general pe 16 biţi.

În general, este important să se folosească numere de 8 biţi într-un MCU de 8 biţi din moment ce toate memoriile de date sunt pe 8 biţi. Totuşi, când se utilizează limbajul “C”, numere mari din tipurile “integer” (16 biţi), “long” (32 biţi), “float” (32 biţi) sunt frecvent folosite. De regulă procesarea cu asemenea numere generează dimensiuni de cod foarte mari, dar din moment ce AVR-ul este proiectat pentru a-i face faţă, codul AVR generat este foarte eficient.

Mersul lucrarii:

1.) Realizam schema electrica in Proteus ISIS pentru problema stipulata in lucrarea de laborator data. Utilizam pentru aceasta:

Display cu 7 segmente pentru redarea tastei apasate Microcontrolerul ATMega16 16 butoane pentru taste organizate in 4 linii si 4 coloane 4 diode pentru colectarea căderilor de potenţial către un singur semnal de la cele 4 linii (surse

de intreruperi) Susrsa de alimentare pentru display cu 7 segmente

Page 5: Lab5.MP.Cuhai.D

2.) Efectuam schema bloc a programului, care va fi realizat pentru satisfacerea conditiei problemei.

Partea de iniţializare: Subrutina de prelucrare a întreruperii: Subrutina de transformare a codului de la tastăîn cod pentru afişorulde 7 segmente:

Init.porturi

Nu Da

Init.configur. MCU

Nu DaNu Da

Bucla infinita

Subrutina de prelucrare a întreruperii: ....

functie pentru detectarea codului tastei

Nu Da

functie pentru transformarea codului tasteiin cod pe 7 segmente

Atribuirea valorii la port

START

Init_Ports:PORTC=0xF0;DDRC=0x0F;PORTB=0x00;DDRB=0xFF;

sei

While(1)

INT0_ISR

key=get_key();

ch=key_to_7seg(key);

PORTB=ch;PORTC=0xF0;

EXIT

Get_key(void)

Int i,m,n,key;m=0x00;

i=0; i<4; i++

m=(1<<i);PORTC=~m;key=PINC;

n=(key|0x0F);

return key;

n<0xFF

PIND2<-0x00DDRD<-PIND2PIND2<-0xFF

PORTD<-PIND2MCUCR<-(1<<ISC01)|

(0<<ISC00)GICR<-(1<<INT0)

key=0;return key;

EXIT

Key_to_7seg(void)

R16=0xE7

R24=0xF9

R16=0xD7

R24=0x99

R16=0x7E

R24=0xA1

ret

Page 6: Lab5.MP.Cuhai.D

3.) Scriem listingul programului pentru microcontroller in limbajul AsamblerListingul programului:

#include <avr/io.h> //biblioteca pentru microcontrolerul // AVR(constante,registri)

#include <avr/interrupt.h>//biblioteca pentru prelucrarea intreruperilorextern int key_to_7seg (int key);//functie externa in assembler pentru

// transformarea codului tastei in cod // pe 7 segmente

int get_key(void);//functie pentru detectarea codului tasteiint main(void) //functia principala de initiere main

{//initierea porturilor utilizate PORTC=0xF0; DDRC=0x0F; PORTB=0x00;DDRB=0xFF;//initierea pinului pentru intrerupereDDRD&=~(1<<PD2);

PORTD|=(1<<PD2);//configurarea registrilor pentru intrerupereMCUCR=(1<<ISC01)|(0<<ISC00);GICR=(1<<INT0);sei();//activarea intreruperii//bucla infinita la care nu se ajungewhile (1)

{}return 0;}

//functia pentru detectarea codului tasteiint get_key(void)

{int i,m,n; //variabile utilizate in functie pentru

// operatiile urmateint key; //variabila ce detine cheia (codul tastei)m=0x00; //initierea variabilei m cu 0,raspunzatoare de

// detectia tasteifor(i=0;i<4;i++)

{m=(1<<i);//atribuirea lui m a valorii obtinute

// in urma deplasarii 1 pe pozitia iPORTC=~m;//inversarea valorii m(de fapt

// deplasarea lui 0 in pozitia i) si // atribuirea la port C

key=PINC; //atribuirea lui key a valorii din // PINC (codul tastei)

n=(key|0x0F); //atribuirea lui n codului obtinut // in urma operatiei

if (n<0xFF)return key;//returnarea codului tastei daca

// conditia se indeplineste}key=0;//atribuirea lui key a valorii 0, dupa

// sfirsitul cicluluireturn key;//returnarea din functie a acestei valori

}//functia pentru intreruperea externa ISR(INT0_vect) {

char ch,key;//generarea a 2 variabilekey=get_key();//atribuirea lui key a codului tasteich=key_to_7seg(key);//atribuirea lui ch codului pe 7

// segmente in dependenta de codul

Page 7: Lab5.MP.Cuhai.D

// tasteiPORTB=ch;//atribuirea lui PORTB codului din chPORTC=0xF0;//plasarea PORTC in valoarea initiala

}//functia descrisa in ASM#define_SFR_ASM_COMPAT 1#define_SFR_OFSET 0#include<avr/io.h> //biblioteca pentru MCU AVR.global key_to_7seg //subrutina globala key_to_7seg: push R16 //plasarea R16 in stiva

L0: ldi R16,0xE7; //incarcarea in R16 a codului tastei apasate cpse R24,R16 //compararea a celor 2 registri cu codurile tastei

// si salt peste o instructiune in caz de egalitate rjmp L1 //salt la L1 in caz de neegalitate a celor 2 registri ldi R24,0xF9; //incarcarea in R24 a codului pentru display-ul cu

//7 segmente rjmp END //salt la sfirsitul subrutineiL1:ldi R16,0xD7; cpse R24,R16 rjmp L2 ldi R24,0x99; rjmp END

L2:ldi R16,0xB7; cpse R24,R16 rjmp L3 ldi R24,0xF8; rjmp ENDL3:ldi R16,0x77; cpse R24,R16 rjmp L4 ldi R24,0xFE; rjmp ENDL4:ldi R16,0xEB; cpse R24,R16 rjmp L5 ldi R24,0xA4; rjmp END

L5:ldi R16,0xDB; cpse R24,R16 rjmp L6 ldi R24,0x92; rjmp END

L6:ldi R16,0xBB; cpse R24,R16 rjmp L7 ldi R24,0x80; rjmp ENDL7:ldi R16,0x7B; cpse R24,R16 rjmp L8 ldi R24,0xC0; rjmp ENDL8:ldi R16,0xED; cpse R24,R16 rjmp L9 ldi R24,0xB0; rjmp ENDL9:ldi R16,0xDD; cpse R24,R16

Page 8: Lab5.MP.Cuhai.D

rjmp L10 ldi R24,0x82; rjmp END

L10:ldi R16,0xBD; cpse R24,R16

rjmp L11 ldi R24,0x90; rjmp END

L11:ldi R16,0x7D; cpse R24,R16

rjmp L12 ldi R24,0x89; rjmp END

L12:ldi R16,0xEE; cpse R24,R16

rjmp L13 ldi R24,0x88; rjmp END

L13:ldi R16,0xDE; cpse R24,R16

rjmp L14 ldi R24,0x83; rjmp END

L14:ldi R16,0xBE; cpse R24,R16

rjmp L15 ldi R24,0xC6; rjmp END

L15:ldi R16,0x7E; cpse R24,R16

rjmp END ldi R24,0xA1;

END:pop R16 ret

Comenzile utilizate in programul dat:comanda explicatia operanzii flagurileldi Incarcarea constantei Rd,k Nonepush Plasarea registrului in stack Rr Nonerjmp Salt relative la k k Nonepop Scoate registru din stiva Rd Noneret Returnare din subrutina Nonesei Setarea intreruperii I

4.) Simularea programului si schemei in Proteus, cercetind lucrul programei realizata in limbajul C mixat cu ASM, urmarind intreruperile, sarcina pentru detectarea si vizualizarea butonului apasat.Butonul 5:

Page 9: Lab5.MP.Cuhai.D

Butonul A:

Butonul #:

Concluzie:In lucrarea de laborator data am realizat un cod in limbajul C mixat cu ASM, functia realizata in

ASM fiind pentru marirea vitezei de lucru a microcontrolerului, viteza lui de prelucrare a codului ASM fiind mai mare, o detectare mai usoara. Pentru realizarea sarcinilor teoretice, am montat in Proteus o tastatura pentru telefon cu 16 caractere, astfel la apasarea butonului am vizualizat acesta la display-ul cu 7 segmente. Astfel am asimilat modul de programare in Limbajul C si introducerea in acest cod , a codului din assembler, observind avantajele limbajului C pentru scrierea unui cod mai complex.

Bibliografie:http://www.gaw.ru/html.cgi/txt/ic/Atmel/micros/avr/atmega16.htmAtmel AVR ATMega16 Datasheet

http://www.mcu-labs.com/2013/02/problema-l5-keypad-4x4.htmlhttp://www.tehnorama.ro/introducere-in-limbajul-de-asamblare-al-microcontrolerelor-atmega/http://easyelectronics.ru/avr-uchebnyj-kurs-programmirovanie-na-si-chast-1.htmlhttp://www.electronica-azi.ro/print.php?id=774