Documente Academic
Documente Profesional
Documente Cultură
PETREUȘ
ENIKŐ
SZILÁGYI
RADU
ETZ
TOMA
PĂTĂRĂU
MICROCONTROLERE –
APLICAȚII
Cuprins
1
Mediul Keil uVision
STOP
2
Mediul Keil uVision
3
Mediul Keil uVision
4
Mediul Keil uVision
5
Mediul Keil uVision
6
Mediul Keil uVision
7
Mediul Keil uVision
nop
nop
sjmp palier_n
end
3. Analizați programul și explicați cum funcționează.
4. Convertiți programul în cod mașină folosind meniul Help!
Observație: Conversia se face unu la unu, adică fiecare linie din
program se transformă într-o instrucțiune în binar.
Tab. 1-1 Program
Cod ASM Cod mașină Locație de memorie
mov a, #55h
mov P2,a
nop
nop
add a, #55h
mov P2, a
nop
nop
sjmp palier_n
*) Să se verifice fișierul c:\Keil_v5\C51\ASM\ reg51.inc
5. Rulați secvența de cod pas cu pas (Debug/F11/Step) și:
- verificați conținutul acumulatorului în fereastra Registers (Fig. 1.12)
- verificați codul mașină în fereastra Disassembly (Fig. 1.13)
- verificați fereastra de memorie de cod (Fig. 1.14)
8
Mediul Keil uVision
9
Mediul Keil uVision
10
Mediul Keil uVision
11
Simulator de sistem Proteus
12
Simulator de sistem Proteus
Pentru a adăuga componentele pasive sau active care urmează să fie folosite
există trei posibilități:
1. butonul Pick Component (P)
2. meniu Library-Pick Device/Symbol
3. click dreapta pe pagina de lucru: Place-Components-From Libraries
13
Simulator de sistem Proteus
14
Simulator de sistem Proteus
15
Simulator de sistem Proteus
16
Simulator de sistem Proteus
17
Simulator de sistem Proteus
F10
18
Simulator de sistem Proteus
Se poate vedea și rula pas cu pas codul sursă în asamblare dacă în meniul
Source/Add Remove Source Files este adăugat fișierul *.a51:
Atenție: schema din Proteus trebuie să fie în directorul în care este salvat
proiectul din Keil.
3.6. Depanarea în Proteus programelor scrise în C
Pentru depanarea programelor scrise în C utilizând mediul Keil se urmează
pașii necesari realizării unui proiect C în Keil urmând să se genereze fișierul
*.hex asemenea proiectelor în asamblare. În urma compilării și link editării o
să genereze un fișier OMF (absolute object module). Acest fișier de ieșire al
link editorului conține informațiile necesare pentru realizarea debugului. În
mod implicit acest fișier este salvat în subdirectorul „Objects” din directorul
proiectului cu aceeași denumire cu cea a proiectului doar că nu are nici o
extensie. Pentru a putea folosi acest fișier în Proteus este nevoie să îi fie
atribuită extensia *.omf. Odată atribuită această extensie, în Proteus se poate
utiliza ca fișier sursă pentru proiect în loc de fișierul *.hex acest fișier *.omf.
19
Simulator de sistem Proteus
Fișier *.omf:
20
Simulator de sistem Proteus
Atenție: schema din Proteus trebuie să fie în directorul în care este salvat
proiectul din Keil.
3.7. Interconectarea programelor KEIL și PROTEUS
Folosind această metodă codul sursă în ASM sau C se rulează și depanează
în programul Keil, dar între timp se poate vizualiza comportarea circuitului
simulat în programul Proteus. Ca să se realizeze interconectarea acestor două
programe următorii pași trebuie efectuați:
− Dacă Keil C51 și Proteus sunt instalate corespunzător în directorul
C:\Program Files atunci fișierul VDM51.dll din directorul C:\
Program Files\ Labcenter Electronics\ Proteus N Professional\
MODELS\ VDM51.dll se copiază în directorul C:\Keil_v5\C51\BIN\.
unde N reprezintă versiunea instalată a programului Proteus.
− Se deschide fișierul TOOLS.INI din directorul C:\Program
Files\keil_v5\TOOLS.INI și la secțiunea [C51] se adăugă linia
următoare: TDRVX = BIN\VDM51.DLL ("Proteus VSM Monitor-
51 Driver") Unde X în TDRVX reprezintă situația actuală, nu se vor
duplica TDRV-urile existente
21
Simulator de sistem Proteus
În caseta de dialog care apare în meniul derulant, coloana din dreapta sus,
selectați „Proteus VSM Monitor-51 Driver” și activați opțiunea „Use”. Apoi
faceți clic pe butonul „Settings” pentru a seta interfața de comunicare:
22
Simulator de sistem Proteus
4 Modul de lucru
• Se deschide Keil uVision și se generează fișierul *.hex.
• Se deschide programul Proteus.
• Vă veți familiariza cu meniurile existente.
• Se va depana programul în Proteus.
• Se va simula programul în Proteus.
5 Aplicații
1. Testarea exemplului prezentat în capitolul 3.5. Depanarea programelor
scrise în asamblare în Proteus.
2. Să se scrie și să se testeze programul următor în Keil uVision.
DEL EQU 05H
REPET EQU 01H
MAIN:
MOV A,#REPET
ACALL INTARZIERE
CPL P3.4
SJMP MAIN
INTARZIERE:
MOV R0,#DEL
DELAY:
NOP
NOP
23
Simulator de sistem Proteus
NOP
NOP
DJNZ R0, DELAY
DJNZ ACC, INTARZIERE
RET
HERE: SJMP HERE
END
a. Verificați folosind meniul Help instrucțiunile:
acall intarziere
ret
cpl Px.pin
djnz acc, intarziere
b. Cum funcționează problema prezentată?
c. Cât este perioada semnalului generat?
d. Modificați valoarea ‚del’ astfel încât să aveți un semnal
dreptunghiular cu o perioadă de 1 ms și factorul de umplere 50
% (Ton = Toff = 0.5 ms).
e. Modificați valoarea ‚repet’ astfel încât să aveți un semnal
dreptunghiular cu o perioadă de 100 ms și factorul de umplere
50 % (Ton = Toff = 50 ms).
f. Modificați programul astfel încât să aveți un semnal
dreptunghiular cu o perioadă de 1s și factorul de umplere 50 %
(Ton = Toff = 0.5 s)
3. Pregătiți schema următoare și testați în Proteus programul scris:
24
Simulator de sistem Proteus
25
Testarea memoriei RAM externă
FFFF FFFF
FF FF
IDATA
Regiștri cu (nu este
funcții disponibilă la
speciale toate
dispozitivele)
80 80
7F
Memorie de cod Memorie Memoria Externă
(CODE) RAM de uz (XDATA)
general
2F
Memorie
adresabilă
la nivel de
bit
1F
Bancuri de
regiștri
0000 00
Memorie de date(DATA) 0000
Fig. 3.1 Organizarea memoriei la microcontrolerul 8051
26
Testarea memoriei RAM externă
27
Testarea memoriei RAM externă
28
Testarea memoriei RAM externă
P0 Date
Latch Adrese
ALE
A8-A15
P2 Adrese
RD Enable Date
WR WR
29
Testarea memoriei RAM externă
DA
30
Testarea memoriei RAM externă
write:
mov a, #pattern ;pune în acumulator 55h
movx @dptr,a ;scrie conținutul lui a în memoria RAM externã
;începând cu 0000h
inc dptr ;incrementeazã dptr pentru a scrie la
;urmãtoarea locație de memorie
mov a,#ram_stphi ;mutã în acumulator adresa de stop
cjne a,dpl,write ;scrie în RAM pânã la adresa de stop
31
Testarea memoriei RAM externă
fail:
6). ;6 & 7 - în caz de eroare scoate la
7). ;porturile P1 și P2 valorile lui DPH și DPL
there:
sjmp there ;de ce s-au utilizat două
;JUMP-uri(bucle infinite)?
end
4 Modul de lucru
• Se completează codul.
• Se va rula programul pas cu pas utilizând depanatorul de program
inclus în Keil uVision:
32
Testarea memoriei RAM externă
K - Codul ASCII
33
Testarea memoriei RAM externă
DPTR = 0010h
5 Aplicații
1. Să se scrie un program care:
a). Scrie valoarea AAh în memoria RAM externă începând cu adresa
0002h până la adresa 2112h
b). Verificați dacă valorile au fost scrise corect în memoria RAM
externă. În caz de eroare adresa eronată se va afișa pe P1 și P2.
2. Se va scrie un program care scrie în memoria RAM externă valoarea
AAh pornind de la adresa 0003h până la adresa 0105h, iar apoi se citesc
aceste valori și se verifică dacă au fost scrise corect (folosind fereastra
de memorie). Adresa eronată va fi scrisă pe porturile P1 și P2.
3. Se va scrie un program care scrie alternativ valorile AAh si 55h în
memoria RAM externă începând de la adresa 0249h până la adresa
0251h .
34
Testarea memoriei RAM externă
35
Rutină de întârziere soft
START
Date inițiale
Decrementare A
DA
DA A=0 NU
36
Rutină de întârziere soft
Exemplu:
În meniul Help găsim informații despre numărul de cicluri necesare pentru
executarea unei instrucțiuni. În Fig. 4.2 este prezentată instrucțiunea MOV
A,#55h, care are nevoie de un ciclu mașină pentru execuție. De aceea, timpul
exact pentru executarea ei este 1.085 us.
uVision Help:
MOV A,#55h
CM=
37
Rutină de întârziere soft
onemil:
mov r7,#delay ;inițializează r7; 1 ciclu mașină = 1.085us
timer:
nop ;1 ciclu = 1.085 us
nop ;2 cicluri = 1.085 us + 1.085 us = 2.17 us
nop ;3 cicluri = 2.17 us + 1.085 us = 3.255 us
nop ;4 cicluri = 3.255 us + 1.085 us = 4.34 us
djnz r7,timer ;se decrementeazã r7 ;djnz se execută în
;2 cicluri = 2.17 us, deci avem o întârziere
;totalã de 6 cicluri (6*1.085us = 6.51 us)
;6.51 us x 153 = 996.03 us
nop
ret ; + cicluri suplimentare de la onemil: ≈ 1ms
38
Rutină de întârziere soft
org 0000
setb P3.4
main:
acall onemil ;apelul subrutinei
cpl P3.4 ;complementare bit
sjmp main ;bucla infinită
39
Rutină de întârziere soft
softime:
push 07 ;este salvat registrul r7 pe stivă
push acc ;salveazã A în stivă ca să nu îi
;pierdem valoarea
;A este folosit pentru testul A = A ORL B
orl a,b ;în cazul în care A și B sunt 0 rezultatul
;lui SAU va fi 0
1). ;programul face salt la eticheta ‘ok’ dacă
;rezultatul testului este diferit de 0
pop acc ;se extrage valoarea acumulatorului din vârful
;stivei
pop 07 ;preluarea valorii registrului r7 din stivă
ret ;se iese din rutina softime
ok:
pop acc ;se extrage valoarea acumulatorului din vârful
;stivei
;dacă LSB = 0 care este pasul următor?
decLSB:
acall onemil ;apelul subrutinei onemil
2). ;decrementeazã acc, în cazul în care A(LSB)
;nu este 0 se face salt la decLSB
cjne a,b,decMSB ;în cazul în care conținutul lui b(MSB)
;este diferit de 0 (în acest moment LSB=A=0)
;se decrementează (decMSB) și se sare la decLSB
40
Rutină de întârziere soft
pop 07
ret ;se iese din subrutina softime
decMSB:
3). ;se dercrementează B și se sare la decLSB
sjmp decLSB
41
Rutină de întârziere soft
sjmp main
500 ms
42
Rutină de întârziere soft
setb P3.4
main:
acall onemil ;apelul subrutinei
cpl P3.4 ;complementare bit
sjmp main ;bucla infinită
onemil:
2).
delaymic:
mov r7,#delay
timer:
nop
nop
nop
nop
djnz r7,timer
nop
3).
ret
end
* Observație: ca să aveți întârzierea de bază de 1 ms, bucla delaymic trebuie
repetată de ‘?’ ori.
98.47 us
~1 ms
43
Rutină de întârziere soft
Alimentarea plăcii:
LED: P3.4
CABLU
SERIAL:
Conectat la
PC
Osciloscop digital:
1+ -> P3.4
1- -> GND
44
Rutină de întârziere soft
PASUL 2:
PASUL 1:
PASUL 3:
PASUL 4
45
Rutină de întârziere soft
46
Stocarea datelor în memoria ROM
FFFF FFFF
FF FF
IDATA
Regiștri cu (nu este
funcții disponibila la
speciale toate
dispozitivele)
80 80
7F
Memorie de cod Memorie Memoria Externă
(CODE) RAM de uz (XDATA)
general
2F
Memorie
adresabilă
la nivel de
bit (BIT)
1F
Bancuri de
regiștri
0000 00
Memorie de date(DATA) 0000
47
Stocarea datelor în memoria ROM
48
Stocarea datelor în memoria ROM
START
Citește din acumulator pătratul
numărului: MOVC A,@A+PC
Încarcă numărul în acumulator:
MOV
Afișează pătratul pe P0
Ajustarea conținutului A
- număr de octeți inserați între MOVC
și tabel - Stop
49
Stocarea datelor în memoria ROM
50
Stocarea datelor în memoria ROM
Meniu Help
Fereastra de memorie
Fig. 5.5 Verificarea codului mașină și valorii PC
51
Stocarea datelor în memoria ROM
Rezultate:
P2
0
1
1
0
0
1
0
0
Fig. 5.9 Fereastra Logic: Bus (DIO 0 - DIO 7), Programul WaveForms
52
Stocarea datelor în memoria ROM
Stop
53
Stocarea datelor în memoria ROM
De notat că aici nu avem salt peste tabele, aici ambele sunt plasate la
sfârșitul programului. Conținutul lui A nu necesită nici o ajustare pentru că
adresarea se face utilizând registrul DPTR a cărui valoare poate fi scrisă direct
de utilizator. Astfel poate fi introdusă direct adresa de început a tabelului:
MOV DPTR,#sir
...
sir:
DB 00, 01h, 02h
org 0000h
dplook:
mov a, #5ah ;se calculează pătratul lui 5Ah
mov r1,a ;reține A pentru a fi utilizat mai târziu
mov dptr, #lowbyte ;setează DPTR la adresa de bază a LSB
movc a,@a+dptr ;mută în A conținutul locației de memorie
;(a+dptr) - LSB
mov r0,a ;stochează LSB în r0 (A4h)
mov a,r1
mov dptr,#hibyte ;setează DPTR la adresa de bază a MSB
movc a,@a+dptr ;mută în a partea MSB
mov r1,a ;stochează MSB în r1
here:
sjmp here
org lowbyte+5ah
db 0a4h ;5A^2 = 1FA4h
54
Stocarea datelor în memoria ROM
;LSB este A4
;restul tabelului de căutare ...
org hibyte+5ah
db 1fh ;5A^2 = 1FA4h
;MSB este 1F
;restul tabelului de căutare ...
4 Modul de lucru
• Se vor rula programele pas cu pas utilizând depanatorul de program
inclus în Keil uVision.
• Se vor verifica formele de undă generate.
• Se vor testa programele pe placa de dezvoltare.
5 Aplicații
1. Folosind depanatorul de program și meniul Help se corectează
programul PCLook astfel încât să afișeze:
i. pătratul lui 0
ii. pătratul lui 5
2. Să se modifice programul astfel încât să afișeze pătratele numerelor
pe portul P2 de la 0 până la 15 - repetat la infinit (din memoria de
cod cu A si PC).
Rezultate:
...
55
Stocarea datelor în memoria ROM
255 255
196 196
169 169
144 144
121 121
100 100
81 81
64 64
49 49
25 36 25 36
0 1 4 9 16 0 1 4 9 16
56
Programare modulară
6 Programare modulară
1 Scopul lucrării
• Înțelegerea folosirii tehnicilor segmentelor și a modulelor
• Scrierea și testarea unor programe folosind segmente și module.
2 Aparatura necesară
• Stații de lucru care au instalat Keil uVision.
3 Considerații teoretice
Programarea modulară este o paradigmă de programare care are la bază
utilizarea modulelor. În acest stil de programare unitățile de cod ce oferă
funcționalitate specifică sunt grupate în module separate.
Avantajele programării modulare:
• Permite reutilizarea modulelor. Modulele odată create pot fi incluse
în alte aplicații.
• Ușurează lucrul în echipă. Module diferite pot fi scrise/testate de
persoane diferite.
• Permite o mai bună organizare și structurare a codului sursă.
Un segment este o unitate de cod care poate fi relocabil sau absolut.
Segmentele absolute sunt atribuite în mod specific de către programator la
scrierea codului sursă și sunt amplasate la adrese fixe. Segmentele relocabile
sunt amplasate la adrese stabilite ulterior, la editarea legăturilor.
Un modul este un fișier care deține o colecție de unul sau mai multe
segmente și numele lui este dat de programator.
O bibliotecă este un fișier care conține unul sau mai multe module. În
general, modulele pot fi împărțite în module de obiecte transferabile de
compilator sau asamblor care vor fi combinate cu celelalte module la
momentul link editării. Link editorul selectează dintr-o bibliotecă numai
modulele la care se referă alte module.
Directive de segmentare
Declararea unui segment relocabil se face sub forma:
<nume> SEGMENT <clasa>
Unde:
- <nume> - este numele asociat segmentului
57
Programare modulară
FFFF FFFF
FF FF
IDATA
Regiștrii cu (nu este
funcții disponibila la
speciale toate
dispozitivele)
80 80
7F
Memorie de cod Memorie Memoria Externă
(CODE) RAM de uz (XDATA)
general
2F
Memorie
adresabilă
la nivel de
bit (BIT)
1F
Bancuri de
regiștri
0000 00
Memorie de date(DATA) 0000
Exemplu:
• MainProg SEGMENT CODE
• Data_Segment SEGMENT DATA
58
Programare modulară
59
Programare modulară
PUBLIC data_variable
PUBLIC code_entry
;------------------------------------------------------------------
; You may include more than one symbol in a PUBLIC statement.
;------------------------------------------------------------------
; Put segment and variable declarations here.
;------------------------------------------------------------------
data_seg_name SEGMENT DATA ; segment for DATA RAM.
RSEG data_seg_name ; switch to this data segment
data_variable: DS 1 ; reserve 1 Bytes for data_variable
data_variable1: DS 2 ; reserve 2 Bytes for data_variable1
;------------------------------------------------------------------
; Provide an LJMP to start at the reset address (address 0) in the
main module.
; You may use this style for interrupt service routines.
;------------------------------------------------------------------
CSEG AT 0 ; absolute Segment at Address 0
LJMP start ; reset location (jump to start)
segment_name SEGMENT CODE
RSEG segment_name ; switch to this code segment
start:
;------------------------------------------------------------------
; Insert your assembly program here.
;------------------------------------------------------------------
Exemplul 1:
Verificați sintaxa programului, tipul segmentelor utilizate și valorile mya,
myb, flag și tabel în fereastra de memorie.
Descrierea programului:
;------------------------------------------------------------------
; Module name (optional)
;------------------------------------------------------------------
NAME TESTPROGRAM
;------------------------------------------------------------------
; Put segment and variable declarations here.
;------------------------------------------------------------------
data_seg SEGMENT DATA ;segment de date
RSEG data_seg ;selectarea segmentului data_seg
mya: DS 2 ;rezervă 2 octeți pentru mya
myb: DS 2 ;rezervă 2 octeți pentru myb
60
Programare modulară
CSEG at 50h
table: db 'Hello', 00h
;------------------------------------------------------------------
; Provide an LJMP to start at the reset address (address 0) in the
main module.
; You may use this style for interrupt service routines.
;------------------------------------------------------------------
CSEG AT 0 ; absolute Segment at Address 0
LJMP start ; reset location (jump to start)
MainProg SEGMENT CODE
RSEG MainProg
start:
mov mya,#20h ;mya – primul octet
mov mya+1,#30h ;mya – al doilea octet
mov mya+2,#40h ;mya+2 = myb – primul octet
mov myb+1,#50h ;myb – al doilea octet
61
Programare modulară
Exemplul 2:
În memoria de cod la adresa 100h este mesajul “HELLO WORLD”. Să se
scrie un program care citește mesajul și afișează literele pe portul P3 la infinit
(reg A + DPTR).
62
Programare modulară
Descrierea programului:
Programul are două module: modulul main și modulul extern Printport.
Programul main citește caractere din tabelul ‘text’ și apelează modulul extern
Printport pentru afișarea caracterelor pe P3.
Tab. 6-1 Exemplu 2
Main.asm: Printport.asm:
4 Modul de lucru
• Se vor rula exemplele/programele pas cu pas utilizând depanatorul
de program inclus în Keil uVision.
63
Programare modulară
64
Programare modulară
65
Programare în C
7 Programare în C
1 Scopul lucrării
• Scrierea și testarea unor programe în C
2 Aparatura necesară
• Stații de lucru care au instalat Keil uVision.
3 Considerații teoretice
Un limbaj de programare este de nivel "înalt" atunci când, înainte de a putea
fi executat codul, acesta trebuie mai întâi să treacă prin unul sau chiar mai
multe filtre de interpretare (compilatoare, medii de rulare).
Niveluri ale limbajelor de programare:
• Nivel Scăzut: asamblare - interacționează aproape direct cu procesorul
• Nivel Mediu: C/C++, Pascal - sursele sunt transformate de compilator
în cod mașină
• Nivel Înalt: de exemplu Java - pe lângă procesul de compilare, necesită
JRE - Java SE Runtime Environment (la fel ca Visual C# și .Net
Framework)
Cu cât crește nivelul limbajului (gradul de abstractizare), cu atât acesta este
mai ușor de înțeles de către programator, iar cu cât scade nivelul limbajului,
cu atât acesta este mai ușor de "înțeles" pentru calculator. Pentru eficientizare
în codul C/C++, Visual C/C++, Basic, Pascal, etc. pot fi integrate și porțiuni
de cod de asamblare, obținându-se astfel un cod hibrid.
Codul scris în limbaj de asamblare se traduce direct în codul mașină care
va fi executat de microcontroler, fără cod suplimentar adăugat de compilator
sau de mediu. Deși compilatoarele C/C++ performante pot uneori să producă
un cod mașină foarte eficient din punct de vedere al vitezei sau al necesarului
de memorie, programarea în limbaj de asamblare conferă programatorului
controlul absolut asupra codului binar rezultat. De cele mai multe ori codul în
asamblare are mai puține linii de cod, este mai rapid, mai previzibil din punct
de vedere al necesarului de memorie și de timp și este mai ușor de depanat.
Utilizarea limbajului C pentru programarea microcontrolerelor devine
foarte comună. De cele mai multe ori realizarea aplicației în asamblare nu este
ușoară, dar în schimb se poate face cu ușurință în C. Deoarece va fi folosit
compilatorul Keil C51, în cele ce urmează 8051 C va fi denumit Keil C. Cea
66
Programare în C
67
Programare în C
68
Programare în C
3.3. Funcții
Formatul funcțiilor definit în Keil C este:
[tip_rezultat] <nume_functie> ([argumente])[…][interrupt n][using n]{
[declaratii locale]
[instructiuni]
[return]
}
• tip_rezultat:
o tipul de date returnat de funcție. Tipurile de date predefinite
în Keil C sunt următoarele: char (signed char, unsigned
char), int (signed short, signed int, unsigned int,
signed long, unsigned long), double, enum, struct,
float, bit, sbit, sfr, sfr16
69
Programare în C
void main()
{
//inițializare
while (1) {
//while(1) – bucla infinită
70
Programare în C
Conținut fișier:
Exemplul 1:
Verificați sintaxa programului, tipul variabilelor utilizate și valorile
myByte, myBit și aByte în fereastra de memorie.
Descrierea programului:
#include <REG51.H>
void main()
{
while (1)
{
myByte = 0x55;
myBit = !myBit;
myByte = 0xAA;
}
}
71
Programare în C
Iterația 1: myByte
aByte
Iterația 2:
Exemplul 2:
Să se scrie un program care generează un semnalul dreptunghiular cu o
perioadă de 4 ms și un factor de umplere de 50 %.
#include <REG51.H>
sbit LED = P3^4;
//pinul 4 de la portul 3
void delay(int);
//prototip funcția delay cu 1 parametru de intrare
void main()
{
while (1) //bucla infinită
{
delay(2); //întârziere 2 ms
LED = ~LED; //complement pin
}
}
72
Programare în C
Ton = Toff = 2 ms
T = 4 ms
Exemplul 3:
Să se scrie un program care afișează pătratele numerelor pe portul P2 de la
0 până la 15 - repetat la infinit.
#include <REG51.H>
#define Byte unsigned char
Byte* patrat(Byte);
void main()
{
unsigned int i;
while (1) //bucla infinită
{
for (i=0;i<16;i++)
P2 = patrat(i);
}
}
Byte* patrat(Byte c)
{
return c*c;
}
73
Programare în C
...
255 255
196 196
169 169
144 144
121 121
100 100
81 81
64 64
49 49
25 36 25 36
0 1 4 9 16 0 1 4 9 16
Exemplul 4:
Să se scrie un program care afișează mesajul ’HELLO’ pe portul P2.
Mesajul este stocat în memoria externă.
#include <REG51.H>
#define Byte unsigned char
Byte xdata sir[] = "Hello"; //declarăm șirul în memoria externă
void main()
{
unsigned int i;
P2 = 0xFF;
while (P2>0)
74
Programare în C
{
P2 = sir[i++];
}
while(1); // bucla infinită
}
4 Modul de lucru
• Se vor rula exemplele pas cu pas utilizând depanatorul de program
inclus în Keil uVision.
• Se verifică fereastra de memorie pentru valorile folosite în exemple.
• Se vor testa exemplele 2 și 3 pe placa de dezvoltare Aduc841.
5 Aplicații
1. Să se scrie un program care să afișeze mesajul ’HELLO’ pe
portul P2. Mesajul este stocat în memoria de cod (ROM
internă).
2. Să se scrie un program care să afișeze mesajul ’HELLO
WORLD’ pe portul P2 cu o întârziere de 1s între litere. Mesajul
este stocat în memoria de cod (ROM internă).
3. Să se scrie un program care generează un semnal ca cel din
figura de mai jos utilizând șirul de valori pentru pătratele
numerelor.
75
Programare în C
76
Porturile de intrare – ieșire
VCC
XTAL1
Port 0
XTAL2
Reset circuit RESET Port 1 Porturi
+5V EA
Port 2
Semnale de
control
PSEN Port 3
ALE
GND
77
Porturile de intrare – ieșire
atunci pinul EA se conectează la “1” logic și celelalte două PSEN și ALE sunt
neconectate. Condensatorul de decuplare de 0.1µF, conectat între Vcc și masă
cât mai aproape de pinul de alimentare al microcontrolerului, este folosit
pentru a evita zgomotul de înaltă frecvență de pe linia de alimentare. XTAL1
și XTAL2 sunt destinate intrărilor de ceas ale sistemului.
Pinii portului 0 și portului 2 servesc fie ca dispozitive I/O (intrări/ieșiri) fie
ca magistrală de adrese sau de date pentru lucrul cu memoria externă. Pinii
portului P1 nu au funcții duale: sunt utilizați doar ca și pini I/O. Portul 3 este
un port de intrare – ieșire similar portului 1, dar are și funcții de intrare – ieșire
care pot fi programate controlând bistabilele portului P3 sau regiștrii SFR
specifici.
Descrierea pinilor unui microcontroler din familia 8051 este prezentată în
figura următoare:
P1.0 1 40 Vcc
P1.1 2 39 P0.0 (AD0)
P1.2 3 38 P0.1 (AD1)
P2.3 4 37 P0.2 (AD2)
P1.4 5 36 P0.3 (AD3)
P1.5 6 35 P0.4 (AD4)
P1.6 7 34 P0.5 (AD5)
8 33
P1.7
RST 9 8051 32
P0.6 (AD6)
P0.7 (AD7)
(RXD) P3.0 10 31 EA
(TXD) P3.1 11 30 ALE
(INT0) P3.2 12 29 PSEN
(INT1) P3.3 13 28 P2.7 (AD15)
(T0) P3.4 14 27 P2.6 (AD14)
(T1) P3.5 15 26 P2.5 (AD13)
(WR) P3.6 16 25 P2.4 (AD12)
(RD) P3.7 17 24 P2.3 (AD11)
XTAL2 18 23 P2.2 (AD10)
XTAL1 19 22 P2.1 (AD9)
GND 20 21 P2.0 (AD8)
Schema unui pin al portului 1 este prezentată în figura Fig. 8.3. Cum a fost
menționat și mai sus, portul 1 nu are funcții duale. De aceea bistabilul de ieșire
este conectat direct la grila tranzistorului FET. Dacă folosim portul ca intrare
trebuie să înscriem un unu logic în bistabil blocându-se astfel tranzistorul FET.
Pinul şi intrarea buffer-ului sunt menținute în stare „high” de către rezistența
de pull-up internă (această rezistență este implementată tot cu tranzistoare
FET). Un circuit extern poate aduce acest pin în stare ”0” sau să îl lase în stare
”1”.
78
Porturile de intrare – ieșire
Citire Pin
Fig. 8.3 Schema unui pin de la portul 1
79
Porturile de intrare – ieșire
Vcc Vcc
R1 Switch
Pull-Up
MCU MCU
R1
Switch
Pull-Down
GND GND
Exemplul 1:
org 0000h ;începutul programului
mov A,#55H ;în registrul A avem numărul 55h
back:
mov P2, A
acall delay ;salt la eticheta “delay”
cpl A ;ce face instrucțiunea CPL?
sjmp back
end
Atenție, în exemplul prezentat subrutina ‘delay’, care generează întârzieri
de 1ms, nu este implementată. Se va adăuga o subrutină de întârziere pentru
ca programul să funcționeze corect.
80
Porturile de intrare – ieșire
170d = AAh
85d
P2 =
55h
P2
= 0x55
P2_7
P2_6
P2_5
P2_4
P2_3
P2_2
P2_1
P2_0
P2 = 0 1 0 1 0 1 0 1 = 55h P2 = 1 0 1 0 1 0 1 0 = AAh
81
Porturile de intrare – ieșire
82
Porturile de intrare – ieșire
Exemplul 2:
Programul preia date de la portul P1 și le trimite la P2.
org 0000h
mov P1, #0FFh ;P1 setat ca port de intrare; P1 = 1111 1111b
back: mov A, P1 ;citire port P1
mov P2, A ;transfer data către P2
sjmp back
end
Latch intern
Pini externi
P1:
port de intrare
P2:
port de
ieșire
83
Porturile de intrare – ieșire
Exemplul 3:
Programul scrie în portul P1 valorile 55h și AAh continuu folosind o
instrucțiune de tip read-modify-write.
org 0000h
mov P1, #0FFh ;P1 = 1111 1111b
start: mov P1,#55h ;P1 = 01010101b
again: xrl P1,#0FFh ;P1 <- P1 ^ FFh
acall delay
sjmp again
end
xrl P1,#0FFh
mov P1, #0FFh mov P1,#55h ;P1 <- P1 ^ FFh
;AAh = 55H ^ FFh
84
Porturile de intrare – ieșire
Exemplul 4:
Programul scrie valoarea AAh în memoria RAM externă începând cu
adresa 0010h până la adresa 0300h și apoi verifică dacă valorile au fost scrise
corect.
org 0000h
ram_start equ ___
ram_stphi equ ___
pattern equ ___
good equ ___
mov DPTR,#ram_start
check:
85
Porturile de intrare – ieșire
86
Porturile de intrare – ieșire
Fig. 8.15 Rezultate intermediare - Rularea programului pas cu pas - tasta F11
4 Modul de lucru
• Se vor rula programele de mai sus pas cu pas utilizând depanatorul de
program inclus în Keil uVision.
• Se vor face simulări în Proteus.
• Se vor testa programele pe placa de dezvoltare.
5 Aplicații
1. Să se scrie un program care citește un singur pin al portului P1.
2. Să se scrie un program care modifică portul P2 continuu.
3. Să se scrie un program care monitorizează bitul P1.5. Dacă este high
trimite 55h la P0, altfel trimite AAh la P2.
4. Să se scrie un program care generează un semnal dreptunghiular
folosind un delay format din 2 NOP-uri:
a. Folosind instrucțiunile SETB și CLR.
Cât este factorul de umplere al semnalului generat?
b. Modificați programul astfel încât să aveți un factor de umplere
de 50%.
5. Să se scrie un program ASM care realizează următoarele:
a. Monitorizați bitul 4 al portului P3 până când acesta trece în
stare “HIGH”.
b. Când acesta devine “HIGH” să se scrie valoarea 45h la portul
P0.
c. Apoi, să se scrie impulsul H-to-L în P2.3.
d. Să se scrie programul și în C
Generați fișierul *.hex și testați programul în Proteus și pe placa de
dezvoltare Aduc841.
6. Să se scrie un program care primește un octet de date de pe P1. Dacă
este mai mic decât 100, trimiteți-l la P2, altfel, trimiteți-l la P3.
7. La pinul P3.2 este conectat un buton. Să se scrie un program care la
apăsarea butonului aprinde un led conectat la P3.4. C+ASM
87
Porturile de intrare – ieșire
88
Instrucțiuni aritmetico-logice
9 Instrucțiuni aritmetico-logice
1 Scopul lucrării
• Înțelegerea și utilizarea instrucțiunilor logice
• Scrierea și testarea programelor simple folosind instrucțiuni logice
2 Aparatura necesară
• Stații de lucru care au instalat Keil uVision.
3 Considerații teoretice
Este evident că în cazul programării microcontrolerelor un rol deosebit de
important îl joacă setul de instrucțiuni al microcontrolerului. Trebuie
menționat că în setul de acțiuni se disting câteva clase de instrucțiuni, și
anume: instrucțiuni de transfer de date, instrucțiuni aritmetico-logice și
instrucțiuni de salt (pot fi instrucțiuni de salt absolut sau relativ, condiționat
sau nu). Acest capitol se concentrează mai ales pe instrucțiunile aritmetico-
logice: ADD, ADDC, SUBB, ORL, MUL, DIV, ANL, ORL, XRL, RL, RR,
RLC, SWAP etc.
3.1.Operații aritmetice
Deoarece 8051 are o arhitectură cu acumulator, operațiile aritmetice, în
afară de increment și decrement, trebuie să folosească acumulatorul. Se pot
utiliza toate modurile de adresare pentru sursă: imediată, cu registru, directă
și indirectă. Mai departe, indicatorii de stare/condiție (flag-urile) din PSW sunt
foarte importanți în operațiile aritmetice (Exemplul 1).
De exemplu instrucțiunea ADD A, 020h va adăuga valoarea din locația de
memorie internă RAM 0x20 în acumulator folosind adresare directă.
Mnemonicele:
INC dest ;Adună 1 la destinație
DEC dest ;Scade 1 din destinație
ADD A, sursă ;Adună acumulatorul cu sursă
ADDC A, sursă ;Adună acumulatorul cu sursă şi cu C
SUBB A, sursă ;Scade sursa din acumulator
MUL AB ;Înmulțește A şi B
DIV AB ;Împarte registrul A la B
DA A ;Ajustare zecimală
89
Instrucțiuni aritmetico-logice
Exemplul 2:
Presupunem că locațiile de memorie RAM intern 40-44h conține valorile
următoare:
90
Instrucțiuni aritmetico-logice
CLR C ;CY=0 CY = 1
MOV A, #0E7H ;A=E7H
ADD A, #8DH ;A = E7H + 8DH = 74H
MOV R6, A ;salvare LSB
MOV A, #30H ;A = 30H
ADDC A, #39H ;A = CY(=1) + 30H + 39H = 6AH
MOV R7, A ;salvare MSB
CLR C
MOV A,#60H ;A = 60H 60H – 87H - 0 = D9H; CY = 1
SUBB A,#87H ; 60H-87H = D9H; CY = 1
MOV R7,A ;salvare rezultat
91
Instrucțiuni aritmetico-logice
Instrucțiunea DA - Exemplul 6:
Dacă numerele sunt reprezentate în cod BCD rezultatele operațiilor de
adunare pot fi eronate. Instrucțiunea “DA A” corectează conținutul
acumulatorului, când acesta conține rezultatul adunării a două numere
împachetate în format BCD.
92
Instrucțiuni aritmetico-logice
3.2.Operații logice
Cu ajutorul instrucțiunilor logice se pot realiza teste la nivel de bit, ceea
ce permite un răspuns prompt al aplicației la schimbări și o dimensiune redusă
a codului utilizatorului.
Există zone din memorie și regiștri din SFR care pot fi adresate la nivel de
bit. Adresabilitatea pe biți conferă o serie de avantaje în aplicațiile industriale,
unde de cele mai multe ori este nevoie de memorarea stării unor comutatoare
sau alte periferice cu stări binare. În locul grupării variabilelor de tip bit
aferente mai multor periferice într-un singur octet apoi manipularea acelui
octet, se preferă stocarea variabilelor independent, în zona adresabilă pe biți.
Astfel, manipularea acestui tip de date devine mult mai rapidă.
Operațiile logice sunt aplicabile la nivel de bit sau octet.
Operații logice la nivel de octet:
ANL A,#15h ;A ȘI 15h
ORL 15h, #88h ;conținutul adresei 15h SAU numărul 88h
XRL A, R0 ;R0 SAU EXCLUSIV acumulator
CLR A ;ŞTERGE fiecare bit din acumulator; A devine 00h;
CPL A ;COMPLEMENTEAZĂ fiecare bit din A
;1 devine 0 şi 0 devine 1
Exemple:
Instrucțiunea ANL dest, source realizează operația ŞI logic între dest şi
source, rezultatul este salvat în dest.
Se foloseşte la operaţia
de "mascare (șterge
anumiți biți)
Instrucțiunea ORL dest, source realizează operația SAU logic între dest
şi source, rezultatul este salvat în dest.
Se foloseşte pentru a
seta diferiţi biţi
93
Instrucțiuni aritmetico-logice
Se foloseşte pentru a
anula sau seta diferiţi
biţi.
Unde:
- dest poate fi acumulatorul sau o adresă în memoria RAM internă
- source este o valoare imediată, conținutul unei adrese, conținutul
registrului Rn sau conținutul adresei din registrul Rn
Observații:
• Operațiile logice la nivel de octet utilizează toate cele 4 moduri de
adresare a operatorului sursă.
• Dacă adresa directă destinație este cea a unui port, se utilizează
întotdeauna pentru operația logică bistabilul asociat portului şi nu
informația prezentă la pinii acestuia.
• Prin operațiile logice menționate nu este afectat nici un indicator de
condiție (FLAG) (excepție face cazul când adresa directă este cea a
registrului PSW).
• Numai memoria RAM internă și SFR suportă operații logice.
Lista operațiilor logice la nivel de bit:
ANL C, bit ;ŞI logic între bitul adresabil şi Carry
;rezultatul în C
ORL C, bit ;SAU logic între bitul adresabil şi Carry
;rezultatul în C
CLR bit ;șterge bitul adresabil ‘bit’
CLR C ;șterge indicatorul C
SETB bit/C ;setează bitul adresabil ‘bit’/indicatorul C
CPL bit ;complementează bitul adresabil ‘bit’
CPL C ;complementează indicatorul C
JB bit, label ;salt relativ dacă bit este 1
JNB bit, label ;salt relativ dacă bit este 0
JC bit, label ;salt relativ dacă Carry este 1
JNC bit, label ;salt relativ dacă Carry este 0
MOV C, bit ;copiază bitul adresabil ‘bit’ în C
MOV bit, C ;copiază C în bitul adresabil ‘bit’
94
Instrucțiuni aritmetico-logice
Instrucțiuni de rotire
Instrucțiunile de rotire sunt aplicabile doar la nivel de octet. Instrucțiunea
RL A rotește un octet la stânga. Cel mai semnificativ bit (MSB) devine cel mai
puțin semnificativ bit (LSB) și nici un indicator de stare nu este afectat.
Carry Flag
95
Instrucțiuni aritmetico-logice
7 6 5 4 3 2 1 0
MSB LSB Înainte: 1001 1100
După: 1100 1001
Exemplul 7:
Programul numără biții de 1 dintr-un număr salvat în acumulator folosind
instrucțiunea RLC A. Pune în Carry (pe rând) biții și verifică dacă ei sunt
egali cu 0 sau nu. Dacă Carry este 0, urmează bitul următor, altfel se
incrementează rezultatul și apoi este verificat bitul următor. Rezultatul este
salvat în R1.
ORG 0000
MOV R1, #0H
MOV R7,#08H ;contor
MOV A,#97H
CLR C C 7 6 5 4 3 2 1 0
AGAIN:
RLC A Carry Flag
JNC NEXT
INC R1 ;daca CY == 1 -> increment rezultat
NEXT: ;salt la bitul urmator
DJNZ R7,AGAIN
END
96
Instrucțiuni aritmetico-logice
Exemplul 8:
Programul salvează în stivă numerele de la 1 până la 5. După salvarea
numerelor programul le preia de pe stivă și le afișează pe P2.
org 0000H
main:
mov a,#01h
stiva:
push acc ;adăugarea elementului salvat în acumulator
;la vârful stivei
inc a ;increment acumulator
cjne a,#06h,stiva ;programul se oprește daca numărul 5 a fost
;salvat în stivă
display:
pop acc ;extragerea datei din stivă și salvarea ei
;în acumulator
mov P2,a
cjne a,#01h,display
sjmp $
end
97
Instrucțiuni aritmetico-logice
SP = 08H
Cum a fost menționat și mai sus, când lucrăm cu stiva trebuie să avem grijă
să nu suprascriem date din memorie, stiva putând creşte peste o zonă de
memorie utilizată pentru alte scopuri. În exemplu următor pentru a evita
această problemă valoarea SP este inițializată cu 30h:
mov SP,#30h.
SP = 31H
4 Modul de lucru
• Se deschide Keil uVision și folosind meniul Help se verifică sintaxele
posibile pentru instrucțiunile aritmetico-logice.
• Se vor testa programele folosind depanatorul de program inclus în Keil
uVision.
• Se va simula în Proteus.
• Se vor testa programele pe placa de dezvoltare.
5 Aplicații
1. Verificați următoarele secvențe de program:
a).
MOV A,#23H
ANL A,#F0H ;A = ?
b).
MOV A,#23H
98
Instrucțiuni aritmetico-logice
ORL A,#0FH ;A = ?
c).
MOV P1,#0FFH
START:
MOV A,#0FH
XRL P1, A ; P1 = ?; A = ?
SJMP START
d).
MOV A,#54H
SWAP A ;A=?
Ce valoare se găsește în acumulator? În absența unei instrucțiuni SWAP,
cum ați schimba nibble-urile? Scrieți un program simplu pentru
exemplificare.
2. Scrieți un program care adună patru numere salvate în memoria externă
începând de la adresa 50h:
10010001b = 91h
a). b).
5. Scrieți un program care calculează pătratul lui 69h și stochează partea LOW
în R5 și partea HIGH în R4:
99
Instrucțiuni aritmetico-logice
7. Să se scrie două subrutine care transferă o valoarea pe 8 biți bit cu bit prin
P3.1:
a). Primul bit transferat e bitul LSB.
b). Primul bit transferat e bitul MSB.
Să se pună două valori HIGH la începutul și la sfârșitul transferului. Să fie
transferate valorile: 14h, 54h, 91h și 82h folosind subrutinele
implementate.
100
Instrucțiuni aritmetico-logice
101
Instrucțiuni aritmetico-logice
10. Se presupune că cei trei pini superiori ai P3 (P3.7, P3.6 și P3.5) sunt
conectați la 3 comutatoare. Să se scrie un program pentru a trimite
următoarele caractere ASCII la P1 pe baza stării comutatoarelor:
000 → ‘0’
001 → ‘1’
010 → ‘2’
011 → ‘3’
100 → ‘4’
101 → ‘5’
110 → ‘6’
111 → ‘7’
Fig. 9.27 Problema 9 – Rezultate Keil
102
Timer-ele și numărătoarele
10 Timer-ele și numărătoarele
1 Scopul lucrării
• Studiul metodelor de realizare a rutinelor de întârziere hard
(utilizând metoda interogării);
• Studiul funcționării numărătoarelor;
2 Aparatura necesară
• Stații de lucru care au instalat Keil uVision.
• Placa de dezvoltare Aduc841 și osciloscopul digital Analog
Discovery.
3 Considerații teoretice
Multe aplicații cu microcontrolere presupun contorizarea unor evenimente:
✓ numărarea impulsurilor externe (când timer-ul îndeplinește funcția
de numărător) sau
✓ realizarea unor întârzieri precise.
Pentru a adresa punctele menționate anterior microcontrolerele din familia
8051 au periferice interne Timer/Counter.
Timer-ele sunt divizate (fiecare) în 2 regiștri de câte 8 biți: octetul inferior
(TL0, TL1) și octetul superior (TH0, TH1).
Toate acțiunile timere-lor sunt controlate de starea biților din registrul de
mod TMOD și cel de control TCON.
MSB LSB
GATE C/T M1 M0 GATE C/T M1 M0
TIMER 1 TIMER 0
GATE - Setat, porneşte timerul 1/0 dacă bitul TR1/0 = 1 şi INT1/0 = 1 (Control hardware)
Şters, validează timerul dacă TR1/0 = 1 (Control software)
C/T - Setat, numără impulsurile externe de la pinii P3.5(T1) sau P3.4 (T0)
Şters determină funcţionarea ca timer
M1 M0 Modul de funcţionare
0 0 Mod 0
0 1 Mod 1
1 0 Mod 2
1 1 Mod 3
Fig. 10.1 Registrul TMOD
103
Timer-ele și numărătoarele
3.1. Modul 0
Registrul THx este setat ca numărător pe 5 biţi iar TLx este setat ca
numărător pe 8 biţi, în acest fel frecvența de intrare este divizată la 32 de
primul numărător şi cu 384 în total.
104
Timer-ele și numărătoarele
Exemplul 1:
Să se genereze un semnal dreptunghiular cu un factor de umplere de 50%
la pinul P3.4. Întârzierea necesară este generată de TIMER-ul 0, modul 1.
Programul va fi scris în asamblare.
Rezolvare:
Pentru a genera o întârziere utilizând TIMER-ul în modul 1 trebuie parcurși
următorii pași:
1. Se încărcă registrul TMOD cu o valoare corespunzătoare prin care se
alege modul de funcționare.
2. Se încărcă regiștrii TH, respectiv TL cu valoarea inițială.
3. Se pornește timer-ul: setb TRx sau setb TCON.6 (Timer 1)/ setb TCON.4
(Timer 0)
4. Se monitorizează flag-ul de depășire TF cu o instrucțiune de tipul JNB
TFx, label
5. Se oprește timer-ul: clr TRx
6. Se șterge flag-ul de depășire: clr TFx;
7. Se merge înapoi la pasul 2 şi se reîncărcă regiştrii TLx şi THx cu valoarea
corespunzătoare.
ORG 0000H
LED equ P3.4
CONFIG:
ORL TMOD,#01 ;este selectat modul 1 pentru timer-ul 0
START:
MOV TL0, #67h ;se încarcă valoarea inițială în registrul TL0
MOV TH0, #0A2h ;se încarcă valoarea inițială în registrul TH0
CPL LED ;se complementează bitul P3.4
ACALL DELAY
SJMP START
DELAY:
SETB TR0 ;se pornește timer-ul 0; SETB TCON.4
AGAIN: JNB TF0, AGAIN ;se monitorizează flag-ul de depășire
CLR TF0 ;se șterge flag-ul; CLR TCON.5
CLR TR0 ;oprire timer; CLR TCON.4
RET
END
105
Timer-ele și numărătoarele
...
Valoare
de start: A267 A268 FFFF 0000
A267h TFx = 0 TFx = 0 TFx = 0 TFx = 1
Fig. 10.5 Rularea codului pas cu pas - Fereastra Timer (Meniu Peripherals/Timer)
TH0 = A2h
TL0 = 67h
106
Timer-ele și numărătoarele
Exemplul 2:
Să se modifice portul P2 continuu cu o întârziere de 1 ms. Utilizați Timer-
ul 0, modul 1 pentru a genera întârzierea. Programul va fi scris în C. Fclk =
11.0592 MHz, uC8051.
Calculul valorii ce trebuie încărcată în timer (MODUL 1) pentru a realiza
o anumită întârziere (frecvența de tact având valoarea 11.0592 MHz):
1. Se divide întârzierea dorită: n = delay_dorit/TCM (TCM = 1.085 us)
2. Se calculează valoarea 65536-n, unde n este valoarea calculată în pasul 1.
Se transformă valoarea obținută în hexa.
3. Se încărcă regiştrii TL respectiv TH cu valoarea astfel obținută
#include <reg51.h>
void T0Delay(void);
void main(void)
{
while (1)
{
P2=0x55;
T0Delay();
P2=0xAA;
T0Delay();
}
}
void T0Delay(){
TMOD=TMOD | 0x01;
TL0=0x67;
TH0=0xFC;
TR0=1;
while (TF0==0);
TR0=0;
TF0=0;
}
107
Timer-ele și numărătoarele
Exemplul 3:
Se folosește microcontrolerul Aduc841 în loc de uC 8051.
Dacă întârzierea dorită este 1 ms:
1. 1000 us/0.095 us = 11049
2. 65536 – 11049 = (54487)dec = (D4D7)hex → TH0 =D4h; TL0 = D7h
108
Timer-ele și numărătoarele
TLx este setat să lucreze ca un timer pe 8 biți. THx este utilizat să mențină
valoarea care este reîncărcată în TLx de fiecare dată când TLx trece de la
valoarea FFh la 00h. Flag-ul TFx este de asemenea setat când TLx trece din
FFh în 00h.
Exemplul 4:
Să se genereze un semnal dreptunghiular cu un factor de umplere de 50%
la pinul portului P3.4. Întârzierea necesară este generată de timer-ul 1, modul
2 în ASM
Rezolvare:
Pentru programarea timer-ului în modul 2 se parcurg următorii pași:
1. Se încărcă registrul TMOD cu o valoare corespunzătoare;
2. Se încărcă regiștrii TL și TH cu valoarea inițială;
3. Se pornește timer-ul;
4. Se monitorizează flag-ul TF;
5. Se șterge flag-ul TF;
6. Se merge înapoi la pasul 4.
109
Timer-ele și numărătoarele
ORG 0000h
ORL TMOD, #20h ;pas1: este selectat modul 2 pentru timer-ul 1
MOV TH1, #5 ;pas2: se încarcă valoarea inițială în TH0
MOV TL1, TH1 ;255 + 1 - 5 = 251 x 1.085usec = 272.3
SETB TR1 ;pas3: se pornește timer-ul 0;
TIMER:
DO: JNB TF1, DO ;pas4: se monitorizează flag-ul de depășire;
CLR TF1 ;pas5: se șterge flag-ul TF;
CPL P3.4
SJMP TIMER ;pas6: se merge înapoi la pasul 4
END
Exemplul 5 (8051):
Să se genereze un semnal dreptunghiular cu o frecvență de 10 kHz și factor
de umplere 50% la pinul P2.7. Întârzierea necesară este generată de timer-ul 1
în modul 2. Fclk = 11.0592MHz. Programul se va scrie în C.
110
Timer-ele și numărătoarele
Dacă frecvența dorită este 10 kHz perioada semnalului este egală cu 100
µs. Ton = Toff este 50 us.
1. CM = 12/11.0592 MHz = 1.085 µs
2. n = Ton/CM = 50 µs /1.085 µs = 46
3. FF + 1 = 256 – n = 210 = D2h
4. THX = D2h sau THX = -n = -46d
#include <reg51.h>
void T1M2Delay(void);
sbit mybit=P2^7;
void main(void){
TMOD= TMOD | 0x20;
H1=-46;
TL1 = TH1;
TR1=1;
while (1) {
mybit=~mybit;
T1M2Delay();
111
Timer-ele și numărătoarele
}
}
void T1M2Delay(void){
while (TF1==0);
TF1=0;
}
3.4. Modul 3
Timer-ul 0 va funcționa ca 2 numărătoare independente de 8 biți.
Timer-ele 0 şi 1 pot fi programate în modul 0, 1 şi 2 să lucreze independent,
lucru ce nu se mai întâmplă pentru modul 3.
Dacă se alege modul 3 pentru timer-ul 0, timer-ele nu mai pot funcționa
independent. Punând timer-ul 1 în modul 3, acesta va înceta să numere. Bitul
de control TR1 şi flag-ul TF1 vor fi utilizați de timer-ul 0.
3.5. Numărătoare
Ne amintim că bitul C/T din registru TMOD decide dacă timer-ul numără
impulsurile interne sau impulsurile externe. Dacă C/T= 0, timer-ul primește
impulsurile de la oscilatorul intern, în caz contrar sunt numărate impulsurile
externe (pinul T0 – P3.3, respectiv T1 – P3.4).
Fiecare front descrescător (tranziție 1-0) va incrementa numărătorul.
Fiecare stare „high” sau „low” va trebui menținută stabilă pentru cel puțin un
ciclu mașină.
Exemplul 6:
Se presupune că impulsurile vin la pinul T1.
• Numărătorul 1 este programat în modul 1;
• Starea registrului TL1 este livrată la pinii portului P1;
112
Timer-ele și numărătoarele
Cod ASM:
ORG 0000H
CONFIG:
ORL TMOD,#01010000b ;este selecționat modul 1 pentru counter-ul 1;
SETB T1 ;T1 pin de intrare (p3.5)
START:
MOV TL1, #00h ;se încarcă valoarea inițială în registrul TL0;
MOV TH1, #00h ;se încarcă valoarea inițială în registrul TH0;
SETB TR1 ;se pornește timer-ul 0; SETB TCON.4
COUNTER:
MOV P1,TL1
MOV P2,TH1
JNB TF1, COUNTER ;se monitorizează flag-ul de depășire
;TF0=TCON.5
CLR TF1 ;CLR TCON.5
JMP START
RET
Rezultat: 0003
T1 Pin
Cod C:
#include <reg51.h>
void main(void){
TMOD=0x50;
TH1 = 0;
TL1 = 0;
TR1 = 1;
while (1) {
do {
P1 = TL1;
113
Timer-ele și numărătoarele
P2 = TH1;
}
while (TF1==0);
TF1=0;
}
}
4 Modul de lucru
• Se vor rula programele de mai sus pas cu pas utilizând depanatorul de
program inclus în Keil uVision.
• Se vor face simulări în Proteus.
• Se vor testa programele pe placa de dezvoltare.
5 Aplicații
1. Indicați care timer și în ce mod a fost programat pentru fiecare din
instrucțiunile următoare:
a. MOV TMOD,#01h
b. MOV TMOD,#20h
c. MOV TMOD,#12h
114
Timer-ele și numărătoarele
Numărătoare
115
Portul Serial
11 Portul Serial
1 Scopul lucrării
• Studiul rutinelor de transmisie și recepție serială folosind metoda
interogării
2 Aparatura necesară
• Stații de lucru care au instalat Keil uVision.
• Placa de dezvoltare Aduc841 și osciloscopul digital Analog
Discovery
3 Considerații teoretice
Un calculator trebuie să fie capabil să comunice cu alte calculatoare în
sistemele multiprocesor. O modalitate de comunicare este portul serial. 8051
are un periferic dedicat de comunicație serială (UART full duplex) ce
utilizează registrul SBUF pentru stocarea datelor. Pentru SBUF există doi
regiștri care se găsesc la aceeași adresă. Modul în care este utilizat registrul
depinde de ce operație se efectuează:
• Scriere - este inițiată o transmisie;
• Citire - se preiau datele recepționate.
Registrul SCON controlează comunicația serială în timp ce PCON
controlează rata de comunicație alături de timer-ul 1.
MSB LSB
SM0 SM1 SM2 REN TB8 RB8 TI RI
116
Portul Serial
2SMOD Fclk
fbaud = ec. 3
32 256 − TH1
117
Portul Serial
20 11.0592 106
TH1 = 256 − = 256 − 36 = 220 = DCh ec. 4
32 9600
3.2. Transmisia datelor
Transmisia serială începe ori de câte ori un octet este înscris în SBUF. TI
este setat în “1” când octetul este transmis și SBUF este gol, astfel un alt octet
poate fi transmis.
Exemplul 1:
Scrieți un program care să transmită în continuu litera “A” pe portul serial
cu 4800 baud, 8N1 (8-biți de date, fără paritate, 1 bit de stop).
Rezolvare:
Pentru trimiterea caracterelor pe portul serial se parcurg următorii pași:
1) Timer-ul 1 este oprit prin intermediul bitului TR1=0.
2) În registrul TMOD este încărcată valoarea 20H, pentru a utiliza
T1&M2 timer-ul 1 în modul 2 (8-bit auto-reload).
3) În regiștrii TL1 și TH1 este încărcată valoarea corespunzătoare
pentru baud rate-ul dorit.
4) În registrul SCON este încărcată valoarea 40H, pentru modul 1
(al portului serial), 8 biți de date și câte un bit de start și stop.
5) Bitul TR1 ia valoarea “1” pentru pornirea timer-ului 1.
6) Octetul ce reprezintă caracterul transferat folosind portul serial
este încărcat în registrul SBUF.
7) Flag-ul TI este monitorizat folosind instrucțiunea JNB TI,xx
pentru a ști când a fost transmis întregul caracter.
8) Flag-ul TI este trecut înapoi în “0” folosind instrucțiunea CLR
TI.
9) Pentru a transfera următorul byte trecem iar la pasul 6.
Obs: Transmisia serială poate fi realizată și fără a interoga bitul TI, dacă
programatorul ține cont de durata de timp necesară pentru transmiterea
datelor, scriind o nouă valoare în SBUF după trecerea acestui interval de timp.
Test 8051:
Cod ASM:
ORG 0000H
118
Portul Serial
CLR TR1
MOV TMOD,#20H ;T1M2 -> Baud Rate
MOV TH1,#-6 ;BR = 4800
MOV TL1,TH1
MOV SCON,#40H ;SM0 = 0; SM1 = 1
SETB TR1 ;pornire timer
TRANS:
MOV SBUF,#"A" ;caracterul 'A' este încărcat în registrul SBUF
HERE: JNB TI, HERE ;monitorizare flag de transmisie
CLR TI ;dacă transferul a fost terminat se șterge TI
SJMP TRANS
Cod C:
#include <reg51.h>
void Tx(unsigned char x);
void main(void)
{
SCON = 0x40;
119
Portul Serial
TR1 = 0;
TMOD = 0x20;
TH1 = -6; //BR=4800; 8051
TL1 = TH1;
TR1 = 1;
TI = 0;
while(1){
Tx('A');
}
}
void Tx(unsigned char x)
{
SBUF = x;
while(TI == 0);
TI = 0;
}
Test Aduc841:
Pentru a avea baudrate-ul dorit de 4800 biți/s, trebuie recalculată valoarea
încărcată în TH1 folosind ec. 3.
Pasul 1: Se testează codul în programul Keil uVision. Se pregătește fișierul
*.hex.
120
Portul Serial
RESET
121
Portul Serial
Exemplul 2:
Scrieți un program care să recepționeze date pe portul serial (câte un octet)
și să le trimită la P2, baud rate 4800, 8N1.
Rezolvare:
Pentru recepționarea caracterelor pe portul serial se parcurg următorii pași:
1) În registrul TMOD este încărcată valoarea 20H, pentru a utiliza
T1&M2 timer-ul 1 în modul 2 (8-bit auto-reload) pentru a seta baud rate-
ul.
2) În registrul TH1 este încărcată valoarea corespunzătoare pentru
baud rate-ul dorit.
3) În registrul SCON este încărcată valoarea 50H, pentru modul 1
(al portului serial), 8 biți de date și câte un bit de start și stop.
4) Bitul TR1 ia valoarea 1 pentru pornirea timer-ului 1.
5) Flag-ul RI este trecut în 0 folosind instrucțiunea CLR RI.
6) Flag-ul RI este monitorizat folosind instrucțiunea JNB RI, xx
pentru a ști dacă a fost recepționat caracterul.
7) Atunci când flag-ul RI are valoarea 1, registrul SBUF conține
datele, iar acestea pot fi prelucrate.
8) Pentru recepționarea următorului byte se reiau pașii începând cu
pasul 5.
Test 8051:
Cod ASM:
ORG 0000H
MOV TMOD,#20H ;T1M2 -> Baud Rate
MOV TH1,#0FAH ;BR=4800, 8051
MOV SCON,#50H ;SM0 = 0; SM1 = 1; REN = 1
SETB TR1 ;pornire timer
RECEPTIE:
CLR RI
HERE: JNB RI, HERE ;monitorizare flag de recepție
MOV P2, SBUF ;caracterul recepționat în SBUF este afișat pe P2
122
Portul Serial
Cod C:
#include <reg51.h>
while(1){
P2 = Rx();
}
}
123
Portul Serial
{
unsigned char received;
while(RI == 0);
received = SBUF;
RI = 0;
return received;
}
Test Aduc841:
Pentru a avea baudrate-ul dorit de 4800 biți/s, trebuie recalculată valoarea
încărcată în TH1 folosind ec.3.
Se repetă pașii prezentați la Exemplu 1 (Transmisie serială). Pentru
verificarea conținutului P2 se folosește programul Waveforms.
124
Portul Serial
transmisiei și stocat în RB8 pe durata recepției. Atât biții de start cât și biții de
stop sunt pierduți.
Rata de transfer se calculează cu formula:
2SMOD
fbaud = x Fclk ec. 5
64
Modul 3
Modul 3 este identic cu modul 2 cu excepția faptului că rata de transfer este
determinată exact ca în modul 1 utilizându-se timer-ul 1 pentru a genera
frecvența de comunicație.
Comunicația multiprocesor
Modurile 2 şi 3 au fost create pentru realizarea comunicației seriale
multiprocesor. În general într-o configurație multiprocesor unul dintre
procesoare este master, iar celelalte slave. O caracteristică particulară a unei
conexiuni master –slave constă în aceea că o dată este transmisă de la master
la slave. Intenția este ca la un moment dat un singur procesor slave să
recepționeze data transmisă de master. Există mai multe posibilități prin care
se poate rezolva problema adresării. Dacă se utilizează modul 1, fiecare mesaj
sosit de la master începe cu adresa procesorului slave care urmează să
primească mesajul. Când mesajul este primit, toate procesoarele slave îl
recepționează dar reacționează doar acela căruia îi era adresat. Dacă mesajele
sunt transmise frecvent, procesoarele slave vor pierde foarte mult timp cu
procesarea mesajelor care nu le sunt adresate. Din acest motiv, pentru
comunicația multiprocesor se utilizează modurile 2 şi 3.
După cum s-a văzut în aceste moduri sunt recepționați 9 biți de date, cel
de-al 9-lea bit fiind transferat în RB8 din SCON.
Portul serial al unui microcontroler din familia 8051 poate fi programat
astfel ca data să fie recepționată numai dacă RB8 = 1. Această facilitate se
stabilește prin intermediul bitului SM2 din SCON. Pentru a ilustra
funcționarea în regim multiprocesor se consideră schema din figura următoare,
în care procesorul MASTER comunică cu procesoarele SLAVE prin
intermediul interfeței seriale. Deoarece liniile RxD şi TxD nu sunt linii “three-
state”, procesoarele SLAVE transmit informația către procesorul MASTER
prin intermediul unei porți “ŞI”. Dacă procesorul MASTER dorește să
transmită un bloc de date unui procesor Slave mai întâi transmite un octet de
tip adresă de identificare. Un octet de adresă diferă de unul de date prin aceea
că cel de-al 9-lea bit este “1” pentru date fiind “0”.
125
Portul Serial
RxD
Master
TxD
RxD
Slave 1
TxD
.
.
.
RxD
Slave n
TxD
126
Portul Serial
ORG 0000H
MOV TMOD,____ ;T1M2
MOV TH1,_____ ;BR = 9600 biți/s
MOV SCON,____
_____________ ;start timer
START:
MOV DPTR,____ ;Inițializează DPTR
AGAIN:
CLR A
_____________ ;mută în A conținutul locației de memorie
;(a+dptr) – instrucțiunea movc
JZ START
MOV SBUF,______ ;salvează în SBUF caracterul
HERE: JNB ____, HERE ;monitorizare flag de transmisie
CLR ___
INC DPTR
SJMP AGAIN
ORG 100H
TABLE: DB "YES ",00H
127
Portul Serial
128
Întreruperile
12 Întreruperile
1 Scopul lucrării
• Studiul subrutinelor pentru generarea întreruperilor
2 Aparatura necesară
• Stații de lucru care au instalat Keil uVision.
• Placa de dezvoltare Aduc841 și osciloscopul digital Analog
Discovery
3 Considerații teoretice
Un procesor are doar două metode pentru a determina condițiile/stările
circuitelor interne și externe:
• Polling: metoda care utilizează instrucțiunile software pentru a
interoga starea anumitor flag-uri sau a pinilor porturilor care pot
provoca salturi în funcție de valorile citite: TFx, RI, TI,...
Exemplu: Back: jnb RI, Back
• Întreruperi: presupune reacția la anumite semnale, numite
întreruperi, care forțează procesorul să efectueze un salt la o adresă
aflată în tabelul vectorilor de întreruperi
129
Întreruperile
130
Întreruperile
mov ie,#96h
;varianta 3 - cu setb
setb ie.7
setb ie.4
setb ie.2
setb ie.1
;dezactivarea tuturor întreruperilor
clr ie.7
Cod ASM:
ORG 0000
LJMP MAIN
ORG 000Bh ;adresa fixă pentru întrerupere timer 0
CPL P2.1
RETI
ORG 30H
MAIN:
131
Întreruperile
MOV P1,#0FFh
MOV IE,#10000010b ;este activată întrerupere timer 0
MOV TMOD,#02H
MOV TH0,#-92
SETB TR0 ;start timer
BACK:
MOV A, P0 ;timer-ul numără de la A4H până la FFh
MOV P1, A ;când trece din starea FFh în 00h flag-ul
;TF0 este setat în 1
SJMP BACK
END
B2h A1h
LJMP MAIN
Subrutina Main
132
Întreruperile
T = 200 us
Rezolvare în C:
Pentru tratarea întreruperilor în C se folosește tabelul următor:
Tab. 12-2 Întreruperile - C
133
Întreruperile
void main ()
{
P1 = 0xFF; //port de intrare
IE = 0x82;
TMOD = 0x02;
TH0 = -92;
TR0 = 1;
while(1)
P1=P0;
}
Starea întreruperilor se poate verifica și folosind fereastra “Interrupt
System”:
134
Întreruperile
Exemplul 2:
Să se scrie un program care generează un semnal dreptunghiular cu
porțiune HIGH egală cu 1085 us și LOW 15 us. Între timp programul preia
date de la portul P0 și le trimite la P1. Se va folosi Timer-ul 1, cu întreruperi,
frecventa Fclk = 11.0592MHz.
Rezolvare:
Pentru rezolvarea acestei cerințe se inițializează timer-ul 1 astfel încât să
genereze întârzieri de 1085 us: 1085/1,085 = 1000. 65536 – 1000 = FC18h.
TH1 = FCh, TL1 = 18h. Se pornește timer-ul. Între timp programul preia date
de la portul P0 și le trimite la P1. În momentul când TF1 devine 1
microcontrolerul o să execute subrutina de tratare a întreruperii care generează
o întârziere de 15 us. Întârzierea soft trebuie să conțină și oprirea timer-ului 1,
reinițializarea și pornirea lui. În Fig. 12.7 este prezentată organigrama
programului.
START
ORG 0000H
LJMP MAIN
ORG 001BH ;adresa vectorului întreruperii corespunzătoare
LJMP ISR_T1 ;salt la ISR
;--PROGRAMUL MAIN
ORG 0030H ;după vectorul întreruperii
MAIN: MOV TMOD,#10H ;Timer 1, mod 1
MOV P0,#0FFH ;P0 – port de intrare
MOV TL1,#018H ;TL1=18
MOV TH1,#0FCH ;TH1=FC
MOV IE,#88H ;10001000 – întrerupere Timer 1 activat
SETB TR1 ;start Timer 1
135
Întreruperile
Ton = 1085 us
Toff = 15 us
136
Întreruperile
Exemplul 3:
Pe pinul INT1 (P3.3) este conectat un buton care în starea “idle” este
„high”. La apăsarea tastei un LED trebuie să se aprindă pentru o fracțiune de
secundă. LED-ul este conectat pe P1.2 și este normal stins. Cât timp butonul
e apăsat LED-ul trebuie să fie aprins.
INT1
Buton P1.3
LED
Rezolvare:
LED EQU P1.3
ORG 0000H
LJMP MAIN
ORG 0013H ;INT1 ISR
SETB LED ;aprinde LED-ul
MOV R3,#255
BACK: DJNZ R3,BACK ;ține LED-ul aprins
CLR LED ;stinge LED-ul
RETI ;se revine din întrerupere
;--PROGRAMUL MAIN
ORG 30H
MAIN: MOV IE,#10000100B ;întreruperea INT1 este activată
CLR LED
HERE: SJMP HERE ;așteaptă până când întreruperea devine
;activă
;până când INT1 devine 0
END
137
Întreruperile
P3.3
P3.3
Buton apăsat
Buton neapăsat LED: ON
LED: OFF
ZOOM – LED:
Exemplul 4:
Modificați exemplul 3 astfel încât LEDul să fie aprins doar în momentul
apăsării butonului pentru o fracțiune de timp. După acest interval de timp
LEDul se stinge, chiar dacă butonul este încă apăsat.
Rezolvare:
Trebuie adăugată linia de cod care activează întreruperea INT 1 în momentul
când apare o tranziție din „high” în „low” (în loc de nivelul 0 logic):
SETB TCON.2
Cod ASM:
LED EQU P1.3
ORG 0000H
LJMP MAIN
ORG 0013H ;INT1 ISR
SETB LED ;aprinde LED-ul
MOV R3,#255
BACK: DJNZ R3,BACK ;tine LED-ul aprins
CLR LED ;stinge LED-ul
RETI ;se revine din întrerupere
;--PROGRAMUL MAIN
ORG 30H
MAIN: MOV IE,#10000100B ;întreruperea INT1 e activată
CLR LED
SETB TCON.2
HERE: SJMP HERE ;așteaptă până la întrerupere:
;până când INT1 devine 0
END
138
Întreruperile
Tranziție din
high în low
LED aprins
pentru o
fracțiune de
secundă
LED
Button
EXEMPLUL 4
LED
Button
EXEMPLUL 3
139
Întreruperile
ORG 0000H
LJMP MAIN
ORG 23H
LJMP SERIAL ;sare la etichetă serial
ORG 30H
MAIN: MOV P1,#0FFH ;P1 – port de intrare
MOV TMOD,#20H ;timer 1, modul 2
MOV TH1,#0FDH ;9600 baud rate
MOV SCON,#50H ;8-bit,1 stop, Ren enabled
MOV IE,#10010000B ;întreruperea portului serial este activată
SETB TR1 ;pornire timer 1
MOV A,P1 ;citește datele pe P1
MOV SBUF, A ;le copiază în SBUF
MOV P2,A ;trimite la P2
BACK: SJMP BACK ;bucla infinită
;-----------------SERIAL PORT ISR
ORG 100H
SERIAL:
JB TI, TRANS ;dacă TI == 0 programul sare la eticheta
;TRANS
MOV A, SBUF ;altfel copiază în acumulator conținutul
;registrului SBUF
CLR RI ;șterge flag-ul
RETI ;revine din întrerupere
TRANS:
CLR TI ;șterge flag-ul
RETI ;revine din întrerupere
END
Varianta în C:
#include <reg51.h>
140
Întreruperile
void main() {
unsigned char x;
P1=0xFF;
TMOD=0x20;
TH1=0xF6;
SCON=0x50;
IE=0x90;
TR1=1;
x=P1;
P2=x;
SBUF=x;
while(1);
}
P2
Port Serial
4 Modul de lucru
• Se vor rula programele de mai sus pas cu pas utilizând depanatorul de
program inclus în Keil uVision.
• Se vor testa programele pe placa de dezvoltare.
5 Aplicații
1. Modificați exemplul 5 astfel încât programul să funcționeze în mod
continuu la infinit:
141
Întreruperile
142
Bibliografie
Bibliografie
1. D. Petreuş, Note de Curs Microcontrolere, Anul 3, Electronică Aplicată,
Facultatea de Electronică și Telecomunicații, Universitatea Tehnică din
Cluj-Napoca
2. D. Petreuş, G. Munteanu, Z. Juhos, N. Palaghiţă, Aplicaţii cu
microcontrolere din familia 8051, Editura Mediamira, Cluj-Napoca, 2005
3. Ș. Lungu, D. Petreuş, S. Pleşa, Microcontrolere. Familia Intel 8051,
Editura Comprex, Cluj-Napoca, 1993;
4. S. Ghosal, 8051 Microcontroller: Internals, Instructions, Programming
and Interfacing, Editura Pearson - 2nd edition, 2014
5. David Calcutt, Frederick Cowan, Hassan Parchizadeh, 8051
Microcontroller: An Applications Based Introduction, Editura Newnes,
2004.
6. Thomas Schultz, C and the 8051, Inc. PageFree Publishing, 3rd edition,
2004
7. Thomas Schultz, Vol.I: Hardware, Modular Programming & Multitasking
(2nd Edition, Inc. Prentice Hall; 2nd edition, 1997
8. M. A. Mazidi, J. Gillispie, The 8051 Microcontroller and Embedded
Systems, Prentice Hall, Inc. SUA, 2000;
9. T. V. Sickle, Programming microcontrollers in C, LLH Technology
Publishing - Second Edition, 2000;
10. *** – Microcontrollers DataBook, Atmel Corporation, 2000;
11. *** – AT89C2051 - DataSheet, Atmel Corporation, 2000:
https://datasheetspdf.com/pdf-file/1308338/ATMEL/AT89C51/1
12. *** – ADuC841/ADuC842/ADuC843 - DataSheet, Analog Devices,
https://www.analog.com/media/en/technical-documentation/data-
sheets/ADUC841_842_843.pdf
13. *** – Analog Devices ADUC841 User Manual, Analog Devices, One
Technology Way, https://www.analog.com/en/products/processors-
microcontrollers/microcontrollers.html
14. *** – A Keil µVision4 Getting Started Guide for 8051 pdf,
https://www.keil.com/product/brochures/uv4.pdf
15. *** – Keil Embedded C Tutorial:
https://www.8051projects.net/wiki/Keil_Embedded_C_Tutorial#Introduc
tion_to_Keil_C
15. *** – Ax51 Macro Assembler and Utilities User’s Guide, Keil Software,
2001;
16. *** – C51 Compiler User’s Guide, Keil Software, 2001;
143
Lista de figuri și de tabele
Lista de figuri
Fig. 1.1 Descărcarea mediului Keil uVision ________________________________________ 1
Fig. 1.2 Ciclu de dezvoltare a programelor ________________________________________ 2
Fig. 1.3 Crearea proiectului ____________________________________________________ 2
Fig. 1.4 Bază de date a diferitelor familii de microcontrolere _________________________ 3
Fig. 1.5 Setare frecvenței de ceas _______________________________________________ 4
Fig. 1.6 Crearea fișierului HEX __________________________________________________ 4
Fig. 1.7 Adăugare de fișiere la proiect ___________________________________________ 5
Fig. 1.8 Compilarea și link editarea proiectului ____________________________________ 5
Fig. 1.9 Fereastra Build Output _________________________________________________ 5
Fig. 1.10 Rularea programului _________________________________________________ 6
Fig. 1.11 Meniul Help și instrucțiunea ADD _______________________________________ 7
Fig. 1.12 Fereastra Registers ___________________________________________________ 8
Fig. 1.13 Fereastra Disassembly ________________________________________________ 9
Fig. 1.14 Fereastra Memorie ___________________________________________________ 9
Fig. 1.15 Bara de meniu ______________________________________________________ 9
Fig. 1.16 Portul 2 ____________________________________________________________ 9
Fig. 1.17 Portul 2 – Analog ___________________________________________________ 10
Fig. 1.18 Exemplu: P2.0 și P2.1 ________________________________________________ 10
Fig. 2.1 Pagina de lucru Proteus _______________________________________________ 12
Fig. 2.2 Adăugarea componentelor ____________________________________________ 13
Fig. 2.3 Alegerea componentelor ______________________________________________ 13
Fig. 2.4 Toolbar-ul cu unelte __________________________________________________ 14
Fig. 2.5 Rotire cu 90⁰ ________________________________________________________ 15
Fig. 2.6 Încărcarea programului în simulatorul Proteus VSM ________________________ 16
Fig. 2.7 Pornirea simulării - Meniu Debug _______________________________________ 16
Fig. 2.8 Pornirea simulării - butoane ___________________________________________ 16
Fig. 2.9 Schema în Proteus - Depanarea programelor ______________________________ 17
Fig. 2.10 Depanare program: Step – Butonate____________________________________ 18
Fig. 2.11 Depanare program: Step – Meniu Debug ________________________________ 18
Fig. 2.12 Regiștrii CPU _______________________________________________________ 18
Fig. 2.13 Fereastra CPU înainte și după Step _____________________________________ 18
Fig. 2.14 Adăugare fișier sursă ASM ____________________________________________ 19
Fig. 2.15 Fișier sursă ASM ____________________________________________________ 19
Fig. 2.16 Încărcarea programului C în simulatorul Proteus VSM ______________________ 20
Fig. 2.17 Adăugare fișier sursă C_______________________________________________ 20
Fig. 2.18 Fișier sursă C _______________________________________________________ 20
Fig. 2.19 Fișier Tools.ini ______________________________________________________ 21
Fig. 2.20 Fereastra Options for Target __________________________________________ 22
Fig. 2.21 Setarea VDM51 Target Setup _________________________________________ 22
Lista de figuri și de tabele
Lista de tabele
Tab. 1-1 Program ___________________________________________________________ 8
Tab. 1-2 Tabel - Tema pentru acasă ___________________________________________ 10
Tab. 6-1 Exemplu 2 _________________________________________________________ 63
Tab. 7-1 Cuvinte cheie în C ___________________________________________________ 67
Tab. 11-1 Ratele de baud uzuale - uC8051 _____________________________________117
Tab. 12-1 Întreruperile _____________________________________________________130
Tab. 12-2 Întreruperile - C __________________________________________________133