Sunteți pe pagina 1din 15

PROIECT 2

TEMA NR. 15

DOBRE ALEXANDRU
17/05/2010
GRUPA 435Ba
TEMA NR. 15

Enunţ:

• Să se simuleze Pspice funcţionarea unui automat finit care realizează funcţia


de recunoaştere a codului de trei biti 010, cu fereastră fixă.

Diagrama stărilor de funcţionare:

–/0
–/0
3 4
1/0

0 0/0
0/0
1/0
1/0 1 2
0/1

Ecuaţii de comandă:

Ecuaţia de ieşire:

Frecvenţa de simulare:
Implementarea pe kitul C8051F320 DK
CERINTE:

• Intrarea X este conectata la pinul P2.5, denumit in program InputX;

• Citirea variabilei se face dupa apasarea switch-ului S3 (P2.1), denumit in


program BTN;

• Afisarea starii de recunoastere a codului corect de intrare se va face cu


LED-ul D2 (P2.3), denumit LED2 in program, care va clipi cu o frecventa
de 19 Hz obtinuta cu Timer1

• Contorul de stare este registrul R0 din bank-ul 2 de registre de uz general;

MODIFICARI SUPLIMENTARE:

• Dupa fiecare apasare a switch-ului S3 se apeleaza subrutina Show_state


care foloseste LED-ul D1 (P2.2) pentru a afisa starea curenta prin clipirea
led-ului de un numar de ori egal cu numarul starii curente. Clipirea led-ului
D1 se face cu o frecventa de aproximativ 2 Hz obtinuta printr-o bucla de
intarziere.

DETALIEREA ORGANIGRAMEI FOLOSIND SECVENTE DE COD

1) Declaratii de definire a microcontrolerului, definirea intrarilor si iesirilor,


vectori de reset si intrerupere, selectarea bank-ului de registre de uz
general

$NOMOD51 ;dezactivarea definitiilor implicite ale registrelor de functii speciale pentru


8051
$include (c8051f320.inc) ;fisier de definire a registrelor de functii speciale si a registrelor
specifice kitului C8051F320 DK
InputX equ P2.5 ;Intrarea X a automatului este conectata la pinul P2.5
LED1 equ P2.2 ;LED-ul conectat la pinul P2.2 este denumit LED1 (se foloseste la
afisarea starii curente)
;clipeste cu aproximativ 2 folosind o bucla de intarziere
LED2 equ P2.3 ;LED-ul conectat la pinul P2.3 este denumit LED2 (se foloseste la
afisarea starii OK)
;clipeste cu 19 Hz folosind intreruperea de overflow a Timer-ului 1
BTN equ P2.1 ;Switch-ul S2 aflat pe pinul P2.1 este denumit BTN, se foloseste pentru a
sincroniza citirea intrarii X
cseg AT 0x0000 ;vectorul de reset
ljmp main ;jump la rutina principala de program
cseg AT 0x001B ;vector de intrerupere pentru Timer 1 overflow
ljmp timer1IRR ;rutina de raspuns la intrerupere pentru Timer 1 overflow
codeSeg segment CODE ;definirea segmentul principal de cod
rseg codeSeg ;selectarea segmentului
using 2 ;selectarea bank-ului 2 de registre de uz general
main: acall init ;rutina principala de program: se apeleaza subrutina de initializare
2) Subrutina de initializare (WDT,XBR,porturi,timer,stingerea LED-urilor)

init:
clr EA ;dezactivare globala a intreruperilor
anl PCA0MD,#0xBF ;dezactivare WDT (Watchdog Timer) PCA0MD.6 = 0
mov XBR1,#0x40 ;activarea crossbar-ului XBR1.6 = 1
orl P2MDOUT,#0x0C ;pinii P2.2(LED1) P2.3(LED2) ca iesiri digitale modul push-pull
orl P2MDIN,#0x22 ;pinii P2.1(switch-ul S2) si P2.5(InputX) nu sunt intrari
analogice
orl CKCON,#0x00 ;pentru CKCON.3=0 clock-ul Timer-ului 1 este dat de bitii
CKCON.1 si CKCON.0 care
;atunci cand iau ambii valoarea 0 Timer-ul 1 functioneaza la frecventa
SYSCLK/12.
;clock-ul sistemului (SYSCLK) este implicit preluat de la oscilatorul
intern de 12Mhz care este
;idivizat cu 8. Deci Timer-ul 1 functioneaza la frecventa f=12MHZ/8/12
= 125KHz careia ii
;corespunde o perioada de 8μs
orl TMOD,#0x10 ;TMOD .5=0 TMOD.4=1 -> Timer-ul 1 functioneaza in modul
16 bit counter/timer
mov TH1,#0xF3 ;pt. a obtine perioada frecventa de clipire de 19hz careia ii
corespunde o perioada T=52632us
mov TL1,#0x27 ;T/2=26316 μs (jumatate de perioada LED2 sta stins si cealalta
jumatate e aprins)
;avand In vedere perioada Timer-ului 1 de 8 μs este nevoie de
26316/8=3289=CD9h perioade
;deoarece timerul incepe sa numere de la o anumita valoare introdusa
in TH1 si TL1 pana la
;atingerea valorii FFFFh se calculeaza aceasta valoare FFFFh+1-
CD9h=F327h
setb EA ;activare globala a intreruperilor EA = IE.7
setb ET1 ;dupa activarea globala a intreruperilor se poate activa in mod
particular intreruperea pentru
;Timer1 Overflow ET1=IE.3
clr LED1 ;stingerea LED-urilor
clr LED2
mov R0,#0x00 ;initializare contorului de stare cu valoarea 0 (se porneste din
starea 0)
ret ;revenire la instructiunea urmatoare apelarii subrutinei Init

3) Subrutina de prelucrare a raspunsului la apasarea switch-ului 3


(DEBOUNCE)

mainLoop: ;bucla principala a programului


acall Debounce; ;apelarea subrutinei Debounce care asteapta apsarea si
relaxarea switch-ului S3

Aceasta subrutina se apeleaza la inceputul buclei principale a programului si


are rolul de a elimina problemele introduse de scurtele momente de oscilatie
produse din cauza contactului imperfect la apsarea sau relaxarea unui buton de
pe placa de dezvoltare. Aceste oscilatii dureaza aproximativ 15 ms si de aceea
citirea corecta nu se face la prima schimbare a valorii ci dupa o intarziere de cel
putin 15ms, obtinandu-se astfel un semnal dreptunghiular corespunzator apasarii
si relaxarii butonului.
Debounce: jb BTN,Raised ;daca BTN=1, butonul este relaxat si se sare la eticheta Raised altfel
se executa instr. urmatoare
jnb BTN,$ ;daca BTN=0 (apasat) se asteapta pana cand BTN=1 (relaxat) (se sare
la instructiunea curenta $)
sjmp Delay ;salt la bucla de intarziere Delay de durata aprox. 16ms
Raised: jb BTN,$ ;daca BTN=1(relaxat) se asteapta pana cand BTN=0
(apasat)
Delay: mov R2,#0x30 ;bucla de de intarziere de ((2*<R1>+4)*<R2>+2)*8/12M =
((2*256+4)*48+2)*8/12M= 0.0165133s
Loop: mov R1,#0x00
djnz R1,$
djnz R2,Loop
jnb BTN,Debounce ;daca switch-ul este apasat se reia subrutina Debounce
ret ;daca switch-ul a fost apasat si apoi relaxat se revine la instructiunea
imediat uramtoare apelarii

Debounc
e

NU BTN= DA
0?

BTN= DA NU BTN= DA
Delay
NU 0? 0?

DA BTN= NU Return
0?

4) Cautarea starii curente conform cu continutul registrului contor de stare


R0 din bank-ul 2

Registrul R0 memoreaza starea curenta in care se afla automatul.


Instructiunile folosite pentru a verifica valoarea stocata in R0 sunt instructiuni cjne
(compare and jump if not equal). Fiecare stare este reprezentata printr-o eticheta
la inceputul careia se compara continutul registrului R0 cu numarul starii
respective. In caz de egalitate se executa instructiunile specifice starii, in caz
contrar se sare la urmatoarea eticheta si se face din nou comparatia.
State0: cjne R0,#0x00,State1 ;daca R0=0 se executa instructiunea imediat
urmatoare, in caz contrar
se sare la Eticheta State1
(instructiuni specifice starii 0)
State1: cjne R0,#0x01,State2 ;daca R0=1 se executa instructiunea imediat
urmatoare, in caz contrar
;se sare la Eticheta State2
(instructiuni specifice starii 1)
State2: cjne R0,#0x02,State3 ;daca R0=2 se executa instructiunea imediat
urmatoare, in caz contrar
;se sare la Eticheta State3
(instructiuni specifice starii 2)
State3: cjne R0,#0x03,State4 ;daca R0=3 se executa instructiunea imediat
urmatoare, in caz contrar
;se sare la Eticheta State4
(instructiuni specifice starii 3)
State4: cjne R0,#0x04,StateOK ;daca R0=4 se executa instructiunea imediat
urmatoare, in caz contrar
;se sare la Eticheta StateOK
(instructiuni specifice starii 4)
StateOK: (instructiuni specifice starii OK) ;fiind ultima stare posibila (R0=5) nu mai
este nevoie de comparatie

5) Modul de functionare al automatului, bucla principala de program.

State0: cjne R0,#0x00,State1 ;Daca R0=0 se executa instructiunea imediat urmtoare,


daca nu se sare la starea1
jnb InputX,$+7 ;Daca InputX=1 se executa instructiunea urmatoare, daca nu
se sare peste urmatoarele
;2 instructiuni. (JNB-3 perioade,mov – 2 perioade, sjmp - 2 perioade) in
total 7 perioade
mov R0,#0x03 ;suntem in cazul InputX=1, se trece in starea 3 conform
diagramei de stari
sjmp show_state ;se sare la rutina de afisare a starii curente. Aceasta clipeste
ledul D1 de un numar de ori egal
;cu numarul starii curente
mov R0,#0x01 ;suntem in cazul InputX=0, se trece in starea 1 conform
diagramei de stari
sjmp show_state ;se sare la rutina de afisare a starii curente
State1: cjne R0,#0x01,State2 ;Daca suntem in starea 1 se executa instructiunea
urmatoare, daca nu se sare la starea 2
jnb InputX,$+7 ;daca InputX=1 se executa instr. urmatoare, daca nu se sare
peste urmatoarele 2 instructiuni
mov R0,#0x02 ;suntem in cazul InputX=1, se trece in starea 2 conform
diagramei de stari
sjmp show_state ;se sare la rutina de afisare a starii curente
mov R0,#0x04 ;suntem in cazul InputX=1, se trece in starea 4 conform
diagramei de stari
sjmp show_state ;se sare la rutina de afisare a starii curente
State2: cjne R0,#0x02,State3 ;Daca suntem in starea 2 se executa instructiunea
urmataore, daca nu se sare la starea 3
jnb InputX,$+7 ;starea 2 ;daca InputX=1 se executa instr. urmatoare , daca nu se sare
peste urmatoarele 2 instructiuni
mov R0,#0x00 ;x=1 ;suntem in cazul InputX=1, se trece in starea 0 conform diagramei de
stari
sjmp mainLoop ;se sare la inceputul buclei principale, nu este nevoie de
afisare (suntem in starea 0)
mov R0,#0x05 ;suntem in cazul InputX=0, se trece in starea OK si se incepe
clipirea LED-ului D2 cu f=19HZ
setb TR1 ;se porneste timer-ul 1 (Timer1 Run=1)
sjmp show_state ;se sare la rutina de afisare a starii curente
State3: cjne R0,#0x03,State4 ;Daca suntem in starea 3 se executa instructiunea
urmatoare, daca nu se sare la starea 4
mov R0,#0x04 ;se trece in starea 4 indiferent de intrarea InputX, conform
diagramei de stari
sjmp show_state ;se sare la rutina de afisare a starii curente
State4: cjne R0,#0x04,StateOK ;Daca suntem in starea 4 se executa instructiunea
urmatoare, daca nu se sare la starea OK
mov R0,#0x00 ;se trece in starea 0 indiferent de intrarea InputX, conform
diagramei de stari
sjmp mainLoop ;se sare la bucla principala de program (suntem in starea 0)
StateOK: mov R0,#0x00 ;suntem in starea OK ultima stare posibila dupa verificarea
starilor 0-4, se trece in starea 0
clr TR1 ;se opreste Timer-ul 1 (Timer 1 Run=0)
clr LED2 ;se stinge LED-ul 2
sjmp mainloop ;se sare la bucla principala de program
6) Subrutina de raspuns la intreruperea generata de Timer1

Aceasta subrutina este apelata automat atunci cand valoarea din registrele
TH1 si TL1 depaseste valoarea FFFFh si trece in 0000h. Flagul TF1 este resetat
automat de hardware la intrarea in subrutina. TH1 si TL1 trebuie incarcate din
nou cu valorile specifice frecventei necesare.

timer1IRR:
mov TH1,#0xF3 ;se incarca valoarea necesara obtinereii frecventei de clipire de
19Hz in octetul superior
mov TL1,#0x27 ;TH1 si octetul inferior TL1 al timerului 1. Timerul incepe sa
numere de la aceasta valoare
;pana cand depaseste valoarea FFFFh moment in care se genereaza
intreruperea.
cpl LED2 ;LED2 ia valoarea complementului sau (0->1 1->0)
reti ;se iese din rutina de intrerupere si se reia executia normala a
programului
;din punctul in care se afla inainte de producerea intreruperii
;nu este nevoie sa resetam flagul de overflow TF1, acesta este resetat
automat
;de hardware la intrarea in subrutina de intrerupere
7) Subrutina de afisare a starii curente folosind LED-ul D1

Subrutina Show_state foloseste o bucla de de intarziere pentru a clipi ledul D1


(LED1) de un numar de ori egal cu numarul starii curente aflat in registrul contor
de stare R0. Durata intarzierii se poate calcula dupa formula:

(<R7>*(<R6>*(R5*2+4)+4)+2)*8/12M=(3*(256*(256*2+4)+4)+2)*8/12M=0.2
6420133 s

Show_state:
mov A,R0 ;se incarca in acumulator valoarea starii curente din registrul contor
de stare R0
rl A ;se rotesc la stanga bitii acumulatorului (inmultire cu 2)
mov R4,A ;se incarca valoarea din acumulator in registrul R4
;Loop2 se va executa de un numar de ori egal cu dublul numarului
starii curente
;LED1 se aprinde si se stinge cu factor de umplere 50% de un numar
de ori egal cu
;numarul corespunzator starii curente
Loop2: cpl LED1 ;se complementeaza valoarea pinului LED1
mov R3, #0x03 ;bucla exterioara se executa de 3 ori, mov – 2 perioade
Loop1: mov R2, #0x00 ;bucla intermediara se executa de 256 ori, mov – 2 perioade
Loop0: mov R1, #0x00 ;bucla interioara se executa de 256 ori mov – 2 perioade
djnz R1, $ ;se descreste R1 pana cand ajunge la 0
djnz R2, Loop0 ;se descreste R2 iar daca acesta e diferit de 0 se sare la
eticheta Loop0
djnz R3, Loop1 ;se descreste R3 iar daca acesta este diferit de 0 se sare la
Loop1
djnz R4, Loop2 ;se descreste R4 iar daca acesta e diferit de 0 se sare la Loop2
sjmp mainLoop ;se sare la bucla principala de program
Codul complet al programului:

$NOMOD51 mov R3,#0x03


$include (c8051f320.inc) sjmp mainloop
A equ P1.5 STATE3: setb TR1
B equ P2.0 sjmp mainloop
LED2 equ P2.3
SW3 equ P2.1 init: clr EA
cseg AT 0x0000 mov WDTCN, #0xDE
ljmp main mov WDTCN, #0xAD
cseg AT 0x001B mov SFRPAGE, #CONFIG_PAGE
ljmp timer1IRR mov XBR1,#0x40
codeSeg segment CODE orl P1MDIN, #0x20; P1.5
rseg codeSeg orl P2MDIN, #0x03; P2.0&P2.1
using 2 and P2MDOUT, #0x04 ; P2.3
main: acall init orl CKCON,#0x00
mainLoop: acall button_press orl TMOD,#0x10
mov A,R3 mov TH1,#0xF3
jz STATE0 mov TL1,#0x27
subb A, #0x01 setb EA
jz STATE1
setb ET1
subb A, #0x01
jz STATE2 clr LED2
subb A, #0x01 mov R3,#0x00
jz STATE3 ret
STATE0:jnb A,testB0 button_press: jb SW3,Raised
mov R3,#0x01 jnb SW3,$
sjmp mainLoop sjmp Delay
testB0: jnb B,mainloop Raised: jb SW3,$
mov R3,#0x02 Delay:mov R7,#0x01;0x32
sjmp mainloop Loop: mov R5,#0x01
STATE1: jnb A,testB1 djnz R5,$
mov R3,#0x02 djnz R7,Loop
sjmp mainLoop jnb SW3,button_press
testB1: jnb B,mainloop ret
mov R3,#0x03 timer1IRR:
sjmp mainloop mov TH1,#0xF3
STATE2: jnb A,testB2 mov TL1,#0x27
mov R3,#0x03 cpl LED2
sjmp mainLoop reti
testB2: jnb B,mainloop END
DOBRE
ALEXANDRU START

435B 1) Declaratii de
definire a
TEMA NR 15
microcontrolerului
2)
Init
Stingerea ledurilor aprinse D1 si
D2

3)
Debounce
4) Cautarea starii curente
conform cu continutul registrului
contor de stare R0 din bank-ul 2
Starea Starea Starea Starea Starea
5) Starea OK
0 1 2 3 4
Citeste X Citeste X
Citeste X

Starea Starea Starea


X= X= X= 4 0 0
1? 1? 1?
Starea
Starea 2 Starea
Starea 3 Starea 0
1 Starea OK
4

Arata starea curenta folosind


7)
LED-ul D1