Sunteți pe pagina 1din 7

MINISTERUL EDUCATIEI AL REPUBLICII MOLDOVA

UNIVERSITATEA TEHNICA A MOLDOVEI


CATEDRA DE MICROELECTRONICA SI INGINERIE BIOMEDICALA

Raport
Lucrare de laborator Nr.5

La disciplina Microprocesoare

Tema : Intreruperea externa.Mixare cod C si ASM

A efectuat : st. gr. MN 131,Ignat Ion


A verificat: lector asistent,Lazari Eugeniu

Chisinau 2015
Scopul lucrarii: Transcrierea codului din ASM in C

Obiective:
O1 Transferul parametrilor catre subrutina ASM;
O2 Chemarea subrutinei ASM din C;

Definiia problemei:
S se realizeze o aplicaie pe MCU care va calcula i va afia suma elementelor unui tablou de 10
elemente a cte 8bii. Calculul sumei i afiarea rezultatului se va realiza la fiecare a 11-a apsare
a butonului, iar primele zece apsri vor introduce pe rnd n tablou numrul citit de pe un PORTx
al microcontroller ului completnd astfel tot tabloul cu elemente noi de fiecare dat.
Codul trebuie sa fie mixat intre limbajele de programare C si Assembler. In Assembler trebuie
sa fie scris subrutina pentru adunare a elementelor, care va fi apelat din cadrul functiei de
prelucrare a ntreruperii externe care, la rndul su, va realiza completarea tabloului cu un element
nou la fiecare apsare nou a butonului, dar i apelul subrutinei de sumare atunci cnd tabloul este
completat.

Date teoretice:
-Vizibilitatea functiilor
Pentru ca functiile scrise in C sa fie vizibile in Assembler trebuie sa fie declarate extern:
.extern my_C_function
Pentru ca o subrutina din assambler sa fie vazuta in C trebuie sa fie declarata global:
.global my_assembly_fct
In fisierul C trebuie sa fie functia prototip a subrutinei scrisa in assamler:
extern unsigned char my_assembly_fct (unsigned char, unsigned int);
-Utilizarea registrilor:
R0 Linbajul de programare C utilizeaza acest registru ca un registru temporar. De aceea este
nevoie de al salva daca il utilizam in assembler.
R1 Limbajul de programare C utilizeaza acest registru ca un registru cu valoarea 0. De aceea
este nevoie de al curata dupa utilizarea in Assembler.
R2-R17, R28, R29 sun utilizare de catre C, deci ele trebuie salvate si restabilite la utilizarea in
assambler
R18-R27, R30, R31 Nu trebuie salvate la utilizarea in C

Figura1 interfata registrilor intre C si Assembler


Modul de lucru:
1) Formarea schema bloc de functionare a programului.

Start Port_init INT0_init

Port_init(); DDRA = 0x00; MCUCR |= <<ISC01);


INT0_init(); PORTA = 0xff; GICR |= (1<<INT0);
sei(); DDRB = 0xff; GIFR |= 1<<INTF0);
PORTB = 0x00;
DDRC = 0xFF;
PORTD |= (1<<PD7); PORTC = 0x00;
delay_ms(100); DDRD = 0b10000000; return
PORTD &= (1<<PD7); PORTD =0b01111111;
_delay_ms(100);

return
return

ISR(INT0_vect
)

Fals TAB_SIZE>count
Adevar
er

counter = 0;
result = SumTab(tab,TAB_SIZE);
PORTB = result;
PORTC = result >> 8;

return

Figura 2: Functiile programului


2) Proiectam schema electrica pentru simulare in PROTEUS

Figura 2 Shema electrica simulata in proteus


3) Scriem codul programului

Codul Programului:
#include <avr/io.h> //bibliotecile
#include <avr/interrupt.h>
#include <util/delay.h>

#define TAB_SIZE 10 //Declaratia fariabilelor


unsigned char counter = 0;
unsigned char tab[TAB_SIZE];
extern char SumTab(int, int); //Functia de sumare a elementelor scrisa in assambler
ISR(INT0_vect) //Functia vectorului de intrerupere
{
if(TAB_SIZE>counter) //Daca TAB_SIZE>counter
{
tab[counter]=PINA;
counter++;
}
else
{
int result;
counter = 0;
result = SumTab(tab,TAB_SIZE);//Functia prototip SumTab
PORTB = result; //Initierea portului B cu partea low a rezultatului
PORTC = result >> 8; //Initierea portului B cu partea high a rezultatului
}
}
void Port_init()
{
DDRA = 0x00; //Initierea porturilor
PORTA = 0xff;
DDRB = 0xff;
PORTB = 0x00;
DDRC = 0xFF;
PORTC = 0x00;
DDRD = 0b10000000;
PORTD = 0b01111111;
}
void INT0_init() //Funtia pentru setare a intreruperii INT0
{
MCUCR |= (1<<ISC01);
GICR |= (1<<INT0);
GIFR |= (1<<INTF0);
}
void main(void)
{
Port_init();//chemarea functiei Port_init
INT0_init();//chemarea functiei INT0_init

sei();//activarea intreruperilor

while(1)
{
PORTD |= (1<<PD7); // activarea si dezactivarea ledului
_delay_ms(100);
PORTD &= (1<<PD7);
_delay_ms(100);
}
}
Rezultate obtinute :

Concluzie:In urma efectuarii lucrarii de laborator am cum se mixiaza doua


coduri din C si din Assembler. Am nsuit cum se scrie codul in C am vazut
diferenta dintre C si Assembler.
Am initializat un tablou de 10 elemente si l-am incarcat cu valori. Dupa care am
scos toate elementele si leam sumat, apoi i-am scos cu ajutorul a doua porturi pe 4
BCD-uri.
Functia de sumare a elementelor scrisa in assembler:
#define _SFR_ASM_COMPAT 1
#define __SFR_OFFSET 0
.global SumTab

SumTab:
mov r28, r24 // Inscriem in Y adresa primei valori al tabloului
mov r29, r25
clr r25 //Curatare r19
clr r24 //Curatare r20
clr r21 //Curatare r21
mov r18,r22 // incarcarea in r18 numarul elementelor in tablou
L3:
ld r17,Y+ //Selectarea datelor din tablou
add r24,r17 //Adunarea elementului la suma totala (baitul low)
adc r25,r21 //Adunarea elementului la suma totala (baitul high)
dec r18 //Decrementarea counterului(r18)
brne L3 //Daca counterul este 0, atunci salt la L1
ret

Schema bloc:

SUM_ELE
M

R28 = r29, r29=r25


R25,r24,r21=0
R18 = r22

L3:
r17=Y+
r24=r24+r17
r25=r25+r21+carry
r18--
Fals Adevar
R18!=0

ret

S-ar putea să vă placă și