Implementarea unei aplicatii simple de comanda si control digital
Varianta cu microcontroller CISC (Atmel)
Sa se comande utilizand un sistem dotat cu microcontroller-ul AT89C2051 un piston hidraulic (actuator) intr-o miscare de avans si alta de retragere comenzi transmise prin intermediul unei linii de conexiune seriale. Frecventa de transfer pe interfata seriala va fi de 19200 bauds (biti pe secunda), iar frecventa de ceas a sistemului va fi de 11059000Hz. Cuvintele de comanda si control sunt formate dintr-un singur caracter in format ASCII si comenzile pot contine si parametrii.
Cuvintele cheie admise de catre sistem pentru controlul sau sunt:
A - comanda de avans a pistonului, respectiv comanda miscarea de la limitatorul 1 catre limitatorul 2
R - comada de retragere a pistonului, respectiv comanda miscarea de la limitatorul 2 catre limitatorul 1
S - comanda de citire a starii actuatorului care va intoarce urmatoarele ecouri:
D - pregatit sa receptioneze comanda (reaDy)
B - ocupat cu executia unei comenzi (Busy)
P - comanda de aflare a pozitiei actuatorului (Position), care va intoarce urmatoarele ecouri:
E - avansat, actuatorul atinge limitatorul 2
I - retras, actuatorul atinge limitatorul 1
M - actuator aflat in miscare
Structura electro-hidraulica a sistemului de comanda si control include elementele din figura 1. si anume:
pompa de presiune pentru circuitul hidraulic, care porneste simultan cu comanda dorita, comanda pompei este realizata de catre sistem in logica pozitiva (1 logic = pompa actionata, 0 logic = pompa oprita)
doua electro-valve cu doua cai care asigura accesul
presiunii catre camerele pistonului hidraulic comandate tot in logica
pozitiva ceea ce inseamna ca aplicand un 1 logic pe linia de
comanda inalta presiune a pompei are acces catre camera
corespunzatoare a pistonului, iar aplicand un 0 logic pe linia de
comanda presiunea din camera pistonului este eliberata catre
rezervorul de fluid.
doua limitatoare de capat de cursa care functioneaza in logica negativa si care permit detectarea starii actuatorului
interfata seriala RS232C cu care sistemul de comanda este conectat la sistemul ierarhic superior, spre exemplu la un PC.
Proiectarea elementelor electronice ale sistemului o vom face utilizand circuitul AT89C2051, care este dotat cu 2 Ko memorie EEPROM (Flash) care permite stocarea programelor de comanda si control. Sunt necesare atat amplificatoarele in comutatie pentru comanda electrovalvelor si a pompei de presiune cat si circuitele de intrare ce se prezinta sub forma unor trigger-e Schmidt, pentru formarea semnalelor de la limitatoarele 1 si 2. Structura gandita este prezentata in figura 2.
Implementarea software a sistemului implica scrierea programelor care sa permita executia functiunilor sistemului propus. Ca sistem determinist, acesta trebuie sa aibe o stare initiala bine definita, de aceea vom considera ca aceasta corespunde pozitiei cu pistonul retras aflat pe limitatorul L1, dar pe langa aceste elemente ce tin de procesul in care sistemul este utilizat, va trebui sa analizam si sa setam parametrii initiali ai microcontroller-ului. Pentru aceasta, vom urmari starea initiala a UC, prezentata in catalogul produsului (vezi figura 3), iar apoi va trebui ca sa scriem rutina de initializare de sistem pentru a preciza complet starea microcontroller-ului.
Organizarea programelor care determina functiunile sistemului ilustreaza principiile programarii structurate, astfel: programul de initializare este apelat din programul principal, functiunile sistemului, cea de comunicatie seriala, cele de comanda avans si retragere piston, cele de specificare a starii sistemului si cele de oprire pe limitatoare a acestuia sunt specificate prin rutine de servire a intreruperilor (ISR -Interrupt Service Routines).
Rutina de initializare INIT, va realiza urmatoarele:
Umple toate locatiile memoriei interne a microcontroller-ului cu 0. (Fill Memory with zero)
Aduce in pozitia de referinta (pistonul atinge limitatorul L1), sistemul.
Programeaza urmatorii registrii de functii speciale (SFR Special Functions Registers)
PSW (Program Status Word Register)
PCON (Power On Control Regsiter)
TMOD (Timers Mode Register)
TCON (Timers Control Register)
SCON (Serial Control Register)
IE (Interuppt Enable Register)
Intra in bucla de asteptare a comenzilor de la sistemul ierarhic superior, comenzi ce vor fi transmise via interfata seriala.
Rutinele de serive a intreruperilor vor fi concepute pentru a implementa functiunile ce necesita sincronizarea functionarii sistemului cu elementele externe acestuia ce sunt fie comandate fie reprezinta senzori sau traductoare ale sale. Astfel, va trebui sa satisfacem urmatoarele:
Functia de receptie a mesajelor de comanda sau a cererilor de date de stare din partea sistemului ierarhic superior. Implementarea acesteia se refera la interfata seriala a sistemului si necesita analiza mesajului receptionat, comanda corespunzatoare a sistemului sau emiterea ecoului la comenzile Cerere de Stare (Status Request) din partea sistemului ierarhic superior.
Functia de oprire la atingerea limitatoarelor a comenzii actuatorului electrico-hidraulic.
Programul principal, este gandit sa astepte o comada din partea sistemului ierarhic superior sau sa astepte indeplinirea acesteia.
OBSERVATIE: Aceasta organizare a programelor poate fi utilizata mai ales atunci cand sistemul controlat nu este unul extrem de rapid, respectiv noi, prin intermediul microcontroller-ului putem indeplini restrictiile impuse unui sistem de comanda in timp real, adica putem oferi semnalele de comanda si cele de control "ca oportune", respectiv ele verifica teorema esantionarii a lui Shannon.
In ceea ce insemna implementarea, putem alege intre doua variante:
a) Cea mai sus mentionata care permite ca scrierea functiunilor de comanda sa fie facuta direct in cadrul ISR
sau
b) Cea prin care rutinele de servire a intreruperilor ISR consemneaza modificarile de stare in cadrul sistemului in zona dedicata variabilelor de stare, iar programul principal analizeaza ciclic starea sistemului, si functie de aceasta executa comenzile corespunzatoare ei.
Prima varianta, reflecta principiile programarii structurate, fiecare ISR asigura implementarea unei functiuni. Aceasta varianta permite cea mai rapida reactie din partea sistemului, permite ierarhizarea reactiilor in raport cu cerintele impuse de esalonarea in timp a acestora, dar necesita o rationala atribuire a liniilor de intrerupere corespunzator evenimentelor principale din sistem si este aplicabila in special in cadrul unor sisteme de mica amploare.
A doua varianta asigura analiza starii sistemului in cadrul programului principal, analiza fiind implementata prin intermediul unor instructiuni de decizie, majoritatea calate pe bit, transferul informatiilor se face prin utillizarea unei zone comune de memorie ce formeaza legatura dintre lumea externa (elementele aflate in afara sistemului sau cele comandate: actuator, pompa, electrovalve, limitatoare, etc) si functiunile pe care sistemul este obligat sa le implementeze. Aceasta varianta, permite controlul unor sisteme ample - cu multe surse de intrerupere si multe elemente de comanda si control- dar viteza de reactie este variabila neputand fi anticipata aprioric, caci evenimentele ce au loc in afara sistemului vor fi consemnate sincron (adica foarte curand dupa producerea lor), dar analiza si reactia sistemului la acestea va apare mai tarziu, functie de instructiunea curenta pe care sistemul o executa la momentul producerii evenimentului respectiv.
Sa analizam pe rand care vor fi informatiile pe care va trebui sa le scriem in cadrul SFR pentru a initializa sistemul.
PSW
CY |
AC |
F0 |
RS1 |
RS0 |
OV |
F1 |
P |
MSB LSB
CY carry flag este setat atunci cand in urma unei instructiuni aritmetico-logice apare o operatie de transport sau imprumut
AC Auxiliary Flag utilizat tot in cadrul unor instructiuni aritmetico-logice
F0 User definible Flag poate fi scris si citit de catre utilizator ca indicator specific
RS1 si RS0 codifica natura (binar) bancul tinta de registrii generali, adica combinatia:
00 specifica bancul 0 de registrii generali
01 specifica bancul 1 de registrii generali
10 specifica bancul 2 de registrii generali
11 specifica bancul 3 de registrii generali
OV este setat auotmat la aparitia unei depasiri in cadrul unei operatii de transfer a datelor
F1 User definible Flag poate fi scris si citit de catre utilizator ca indicator specific
P Parity Flag specifica paritatea byte-ului de informatie prelucrat
PCON
SMOD |
GF1 |
GF0 |
PD |
IDL |
SMOD (Serial Mode) setat (daca este fixat pe 1 logic) multiplica cu 2 frecventa de emisie/receptie seriala a datelor
GF1 (General Flag 1), este un bit ce poate fi scris sau citit de catre utilizator prin program
GF0 (General Flag 0), este un bit ce poate fi scris sau citit de catre utilizator prin program
PD (Power Down Flag) Setarea acestui bit trece microcontroller-ul in starea de putere redusa blocand functionarea oscilatorului intern si aducand in starea high FFH iesirile porturilor sale. Informatiile stocate in memoria interna a procesorului abstractie facand cele din registrii speciali (SFR) sunt mentinute, chiar cand tensiunea de alimentare a circuitului scade la 2 V. De asemenea, programul in curs va fi oprit imediat dupa efectuarea instructiunii curente in care a aparut setarea acestui flag. Acest flag are precedenta in raport cu flag-ul IDL (Idle) atunci cand cele doua flag-uri sunt setate simultan.
Iesirea din starea PD se face prin aplicarea unui semnal de RESET.
IDL (IDLE Flag) Setarea acestui flag duce la trecerea intr-o stare de consum redus a microcontroller-ului, stare in care frecventa de ceas a sistemului este aplicata doar elementelor periferice, controller-ul de intreruperi, interfata seriala, timer-ele etc. porturile raman in starea anterioara setarii bitului IDL, iar semnalele ALE si PSEN# trec in 1 logic. Revenirea in stare de lucru se poate realiza pe doua cai:
Prin generarea externa a unei intreruperi, aceasta va reseta flag-ul IDL iar la terminarea ei, prin program, dupa instructiunea RETI putem seta din nou acest flag, sau printr-un RESET hardware, caz in care durata minima a impulsului de RESET trebuie sa depaseasca 24 de ciclii de ceas.
Aceste doua stari Power Down si Idle Mode sunt stari in care consumul microcontroller-ului este redus si pot fi exploatate atunci cand aplicatia pe care vrem sa o realizam corespunde unui aparat portabil care trebuie sa protejeze la maximum resursele energetice.
TMOD
GATE |
C/T# |
M1 |
M0 |
GATE |
C/T# |
M1 |
M0 |
Timer 1 Timer0
Registrul TMOD nu poate fi accesat decat pe byte, deci scrierea unei informatii in acest registru poate fi facuta prin instructiuni de tipul:
MOV TCON,#nnH sau
MOV @R0,#nnH unde R0=#TCON. Atentie, aceasta instructiune poate scrie in memoria interna extinsa, daca microcontroller-ul prezinta o astfel de memorie (vezi PCB80C552 si alte analoge lui).
Modurile de functionare ale canalelor temporizatoare/numaratoare sunt in numar de 4 si sunt codate natural prin simpla scriere a numarului binar corespunzator canalului in bitii 0 si 1 pentru Timer0 sau 4 si 5 pentru Timer1. Iata care sunt aceste noduri:
Modul 0, permite temporizarea[1] sau numararea impulsurilor aplicate la intrarea canalului respectiv dispunand de: un divizor cu 25 =32 (prescale) si apoi divizarea programata cu o constanta de timp ce poate fi formata din orice numar reprezentabil pe 8 biti, deci cuprins intre 0 si 255, 0 corespunde unei divizari cu 256. Numaratoarele canalului temporizator numara in sens direct, adica fiecare front negativ al unui impuls aplicat la intrare determina incrementarea numaratorului. Latimea minima a unui impuls este de 1/24 din frecventa de ceas a sistemului. Structura canalului temporizator numarator este data in figura 4.
Modul 1, asigura temporizarea sau numararea impulsurilor aplicate pe intrarea canalului, constanta de timp fiind un numar cuprins intre 0 si 65535 cu 0 corespunzator lui 65536.
Modul 2, permite divizarea frecventei de intrare sau numararea impulsurilor aplicate cu un numar reprezentabil pe 8 biti, aceasta constanta este retinuta in THx si este reincarcata automat in TLx atunci cand canalul numarator efectueaza tranzitia de stare din 11111111B in 00000000B.
Modul 3, este diferit la canalul 0 in raport cu canalul 1. Pentru canalul 0 setarea acestui mod permite impartirea celor doua numaratoare TH0 si TH0 intre pinii de comanda ai canalelor 0 si 1. Temporizatoarele/numaratoarele canalului 0 low pot fi comandate de catre pinii corespunzatori canalului 0 (TL0), si temporizatoarele/numaratoarele canalului 0 high de catre pinii corespunzatori ai canalului 1 (TH0). Daca programam canalul 1 in modul 3 aceasta duce la blocarea acestuia si retinerea informatiilor de la momentul respectiv. Utilizarea canalului 0 in modul 3 va permite multiplicarea canalelor temporizatoare/numaratoare cu un canal de temporizare/numaratoare de 8 biti
TCON
TF1 |
TR1 |
TF0 |
TR0 |
IE1 |
IT1 |
IE0 |
IT0 |
Registrul TCON (Timer Control) permite modificarea setarilor bit cu bit, semnificatia acestora o detaliem in continuare:
TFx, exprima starea canalului temporizator corespunzator. Setarea se realizeaza hardware, automat la trecerea de la starea 11.11B la starea 00..00B a numaratoarelor canalului respectiv (overflow).
Bitii TRx setati/resetati permit sau respectiv inhiba soft poarta de control ce asigura accesarea numaratoarelor de catre semnalul de intrare al canalului respectiv.
Bitii IEx se seteaza automat (hardware) atunci cand un front descrescator apare pe linia de intreruperi externe corespunzatoare si sunt resetati tot automat la servirea intreruperii. (la intrarea in ISR).
Bitii ITx setati/resetati stabilesc daca intrarile corespunzatoare intreruperilor externe de stare vor fi sensibile pe frontul descrescator al semnalului, respectiv pe nivelul logic zero. In cazul in care bttii respectivi (ITx) sunt resetati, daca semnalul extern aplicat pe intrarile INTx este de durata mai mare decat durata ISR corespunzatoare, la sfarsitul ISR se va genera o noua intrerupere corespunzatoare respectivului canal.
SCON
SM0 |
SM1 |
SM2 |
REN |
TB8 |
RB8 |
TI |
RI |
SM0 si SM1 seteaza unul dintre cele patru moduri distincte in care interfata UART a microcontroller-ului poate functiona. Detalierea acestor moduri este realizata in continuare:
Modul 0, corespunzator combinatiei 00 a bitilor respectivi permite serializarea octetilor ce sunt transmisi si receptionati semi-duplex pe linia RxD. Linia TxD este utilizata pentru transferul semnalului de ceas serial, in acest caz 1/12 din frecventa de ceas a microcontroller-ului.
Modul 1, corespunzator combinatiei 10 a bitilor respectivi asigura transferul full-duplex asincron al informatiilor, respectiv 1 bit de start (0), 8 biti de date si in final un bit de stop (1). Frecventa de transmisie este variabila ea fiind setata de catre canalul 1 temporizator corespunzator frecventei de aparitie a starii overflow.
Modul 2, corespunzator combinatiei 01 a bitilor respectivi, asigura transferul asincron al informatiilor cu 1 bit de start (0), 8 biti de date, un bit programabil, care poate fi chiar bitul de paritate si un bit de stop (1). La transmisie bitul 9 este retinut in locatia TB8, iar la receptie acesta este memorat in RB8. Rata de transfer este programabila la 1/32 sau 1/64 din frecventa de ceas a sistemului.
Modul 3, corespunzator combinatiei 11 a bitilor respectivi, asigura transferul asincron al informaiilor intr-un format analog celui din modul 2 cu exceptia faptului ca rata de transfer este variabila si setata de catre frecventa programata pentru canalul 1 al circuitului temporizator intern al microcontroller-ului.
Bitul SM2 permite validarea unui mod special de comunicatie via interfata seriala USART si anume a modului prin care pe acelasi bus pot fi prezente mai multe sisteme care pot recepta informatia. In acest caz, al 9-lea bit poate fi utilizat ca bit de specificare a tipului de informatii ce sunt transmise. Astfel, setand bitul SM2, poate fi generata o intrerupere atunci cand si bitul al 9-lea transmis este 1 (spre exemplu), ceea ce va determina analiza de catre sistemul receptor a informatiilor si rejectarea acestora atunci cand cuvantul de adresare respectiv nu corespunde propriei adrese.
Bitul REN permite validarea intreruperilor la receptie atunci cand este setat, ceea ce face ca la receptia bitului de stop corespunzator formatului de transmisie specificat sa se genereze o intrerupere si totodata sa se seteze bitul RI.
Bitul TI este setat harware la incheirea transferului unei informatii via interfata seriala, caz in care daca intreruperile corespunzatoare acesteia au fost validate are loc transferul programului catre ISR corespunzatoare. Resetarea acestui bit cade in responsabilitatea programatorului, acesta trebuind s-o efectueze in cadrul ISR.
Bitul RI semnaleaza receptia completa a unitatii de informatie, via interfata UART. La receptia bitului de stop, flag-ul RI este automat (hardware) setat . Programatorul are obligatia ca in ISR corespunzatoare receptiei datelor sa stearga bitul RI, pentru a reanclasa mecanismul de semnalizare a receptiei datelor pe UART.
IE
EA |
SI |
TF1 |
IE1 |
TF0 |
IE0 |
Acest registru specifica care dintre sursele de intreruperi admise de microcontroller poate genera intreruperi. Astfel:
IE0 corespunde liniei intreruperi externe de stare INT0
TF0 corespunde starii timer 0 overflow
IE1 corespunde liniei intreruperi externe de stare INT1
TF1 corespunde starii timer 1 overflow
SI corespunde intreruperilor ce provin de la unitatea UART integrata pe microcontroller.
Registrul IE permite validarea individuala a acestora, dar pentru ca o intrerupere sa se declanseze este necesar ca bitul EA sa fie obligatoriu setat. Prioritatile in servirea intreruperilor sunt stabilite de catre programator, fiind permise doua nivele de prioritizare a intreruperilor: unul superior (high) setat prin inscrierea unui 1 logic in dreptul sursei de intrerupere respective (vezi structura pe surse de intreruperi a registrului IP (Interuppt Priority Register), este analoga celei a registrului IE), si restul inferior (low). Sursa de prioritate inalta va fi capabila sa intrerupa o rutina de servire ISR corespunzatoare unei surse de nivel de prioritate low, dar nu si invers.
Daca simultan apar mai multe intreruperi avand acelasi nivel de prioritate (low), ordinea de analiza a cererilor se face de la IE0 catre SI.
Odata incheiata analiza structurii SFR sa specificam informatiile adecvate aplicatiei noastre. Iata-le:
In PSW vom scrie: 00000000B
In PCON vom scrie: 10000000B setam SMOD pentru multiplicarea cu doi a frecventei de emisie pe interfata seriala
In TMOD vom scrie: 00100000B, respectiv vom programa in modul 2 temporizatorul 1 cu autoreincarcarea constantei de timp, iar canalul 0 il vom mentine in modul 0
Constanta de timp o vom calcula dupa ce vom seta si parametrii interfetei UART, respectiv vom transmite 8 biti/caracter, la 19200 bauds, cu un bit de start si unul de stop. In consecinta in SCON vom scrie:
SCON : 01010000B, adica vom alege modul 1 de functionare si vom valida receptia caracterelor pe interfata seriala.
In acest caz, calculul constantei de timp se va face utilizand formula:
Baud Rate=2SMOD/32*fCLK/(12*(256-TH1)). Rezulta, inlocuind in formula valoarea de 253, respectiv FDH, respectiv 11111101B ce va trebui incarcata in TH1 drept constanta de timp.
In registrul IE vom scrie informatia: 10010000B corespunzatoare starii initiale a sistemului cand acesta va trebui doar sa accepte receptia comenzilor de la sistemul ierarhic superior.
Iata rutina de initializare a sistemului:
;Rutina de initializarea a sistemului
INIT:
MOV R0,#7FH
;Incarca in registrul R0 limita superioara a memoriei interne
LOOP0: MOV @R0,#0H
;Scrie indirect 0 in locatia adresata via R0
DJNZ R0,LOOP0
;Efectueaza umplerea cu zero a memoriei interne a controller-ului
LOOP1:
JNB P3.2,START_POSITION
;Testare stare piston, Daca atinge limitatorul L1, sistemul este in pozitia de referinta
SETB P3.6
SETB P3.5
CLR P3.7
;Comanda Electrovalva 1 si pompa, si anuleaza comanda pentru Electrovalva 2
JMP LOOP1
START_POSITION:
SETB STATUS0
MOV PSW,#00H
MOV PCON,#80H
MOV TMOD,#20H
MOV TH1,0FDH
SETB TR1
MOV SCON,#50H
MOV IE,#90H
;Setarea starii initiale a microcontroller-ului implica validarea doar a intreruperilor UART
RET
Rutina de servire a intreruperilor corespunzatoare UART va trebui sa realizeze urmatoarele:
Sa citeasca informatia receptionata de pe linia seriala
Sa analizeze informatia, si functie de aceasta sa reactioneze astfel:
Daca este vorba de o comanda sa initieze executia acesteia
Daca este vorba de o cerere de stare a microcontroller-ului din partea sistemului ierarhic superior sa initieze transferul acesteia.
Pentru a rezolva aceasta functiune va trebui sa introducem o variabila locala de stare STATUS, avand structura prezentata in figura 5, scrisa de fiecare data cand are loc o schimbare a starii de catre rutinele de servire a intreruperilor ce asigura sincronizarea functionarii unitatii centrale.
STATUS
CDA |
L2 |
L1 |
Bitul L1 este setat la atingerea limitatorului L1, in rest este resetat
Bitul L2 este setat la atingerea limitatorului L2, in rest este resetat
Bitul CDA este setat la initierea unei comenzi de avans sau retragere si resetat in rest, la sfarsitul miscarii.
Rutina de servire a intreruperilor din partea UART (ISR_SI) asigura tratarea fiecarui cuvant de comanda dintre cele admise de protocolul instituit:
Locatiile STATUSx asigura memorarea starii sistemului. in acest sens, asamblorul permite rezervarea de spatiu de memorie in zona de adrese 20H la 2FH, respectiv bitii de la 00H la 7FH.
;Variabile de stare ale actuatorului electo-hidraulic.
STATUS0 BIT 20H
STATUS1 BIT 21H
STATUS2 BIT 22H
;Rutina de servire a intreruperilor generate de UART
;Atentie UART genereaza o unica intrerupere atat la receptie cat si la transmisie
ISR_SI:
JB RI,RECEPTIE
TRANSMISIE:
CLR TI
;Sterge flag-ul Transmision Buffer Empty (Buffer de transmisie gol) pentru reanclansarea
;intreruperilor la transferul unui nou caracter
JB RI,RECEPTIE
;Retestare receptie caracter de catre UART
RETI
RECEPTIE:
MOV A,SBUF
;Citeste carecterul receptionat in registrul ACC
CJNE A,#'A',ISR_SI_1
CDA_AVANS:
SETB P3.7 ;Comanda Ev1
CLR P3.6 ;Blocheaza Ev2
SETB P3.5 ;Comanda pompa de presiune
;Comanda miscarea de avans a actuatorului actionand Ev1 si P.
CLR STATUS0
;Reseteaza starea consemnata anterior, respectiv "actuator retras"
SETB STATUS2
;Consemneaza comanda actuatorului
SETB IE.1
;Valideaza si intreruperile corespunzatoare limitatorului 2
JMP END_ISR_SI
ISR_SI_1:
CJNE A,#'R',ISR_SI_2
SETB P3.6 ;Comanda Ev2
CLR P3.7 ;Blocheaza Ev1
SETB P3.5 ;Comanda pompa de presiune
;Comanda miscarea de retragere a actuatorului actionand Ev2 si P.
CRL STATUS1
; Reseteaza starea consemnata anterior, respectiv "actuator avansat"
SETB STATUS2
;Consemneaza comanda actuatorului
SETB IE.0
;Valideaza si intreruperile corespunzatoare limitatorului 1
JMP END_ISR_SI
;Testare cereri de stare din partea sistemului ierarhic superior
;Ecoul la aceste consta intr-un caracter ce defineste starea curenta a sistemului
ISR_SI_2:
CJNE A,#'S',ISR_SI_3
JB STATUS2,ISR_SI_4
MOV SBUF,#'D' ;Transmite ecoul corespunzator starii reaDy - pregatit
JMP END_ISR_SI
ISR_SI_3:
CJNE A,#'P',END_ISR_SI ;In cazul in care codul nu corespunde
;protocolului stabillit, - cuvantul receptionat nu este unul dintre cuvintele cheie- el va fi ignorat
JB STATUS0,LIM1
JB STATUS1,LIM2
MOV SBUF,#'M' ;Transmite ecoul "actuator in miscare (pozitie intermediara)
JMP END_ISR_SI
LIM1:
MOV SBUF,#'I' ;Transmite ecoul "actuator retras"
JMP END_ISR_SI
LIM2:
MOV SBUF,#'E' ;Transmite ecoul "actuator avansat"
END_ISR_SI:
CLR RI ;Reseteaza flag-ul "receptie caracter"
RETI
ISR_SI_4:
MOV SBUF,#'B'
JMP END_ISR_SI
Vom descrie in continuare rutinele de servire a intreruperilor ce asigura oprirea comenzilor de avans si retragere a actuatorului electro-hidraulic. Corespunzator fiecarei linii de intreruperi externe vom scrie cate o rutina (ISR_EXT0 si respectiv ISR_EXT1)
ISR_EXT0:
CLR IE.0 ;Sterge flag-ul de validare a intreruperilor corespunzator sursei
CLR P3.6 ;Sterge comada corespunzatoare lui Ev2
CLR P3.5 ;Sterge comanda corespunzatoare pompei de presiune
CLR STATUS2 ;Sterge bitul ce consemneaza miscarea actiuatorului
SETB STATUS0 ;Seteaza bitul ce specifica starea 'actuator retras'
RETI
ISR_EXT1:
CLR IE.2 ;Sterge flag-ul de validare a intreruperilor corespunzator sursei
CLR P3.7 ;Sterge comada corespunzatoare lui Ev1
CLR P3.5 ;Sterge comanda corespunzatoare pompei de presiune
CLR STATUS2 ;Sterge bitul ce consemneaza miscarea actiuatorului
SETB STATUS1 ;Seteaza bitul ce specifica starea 'actuator avansat'
RETI
Programul principal al sistemului va include doar o rutina de asteptare a unui eveniment. Iata-l:
ORG 0H
JMP MAIN
JMP ISR_EXT0 ;Saltul la rutina de intreruperi corespunzatoare limitatorului 1
ORG 13H
JMP ISR_EXT1 ;Saltul la rutina de intreruperi corespunzatoare limitatorului 1
ORG 23H
JMP ISR_SI ;Saltul la rutina de intreruperi corespunzatoare UART intern
ORG 100H
$INCLUDE INIT
$INCLUDE SERIAL
$INCLUDE EXT1&2
;Dispozitii de inserare a programelor anterioare in cadrul programului principal
MAIN:
CALL INIT
;Constuim tabela cu salturile la rutinele de servire a intreruperilor sau la programul principal
JMP $ ;Instructiunea asigura saltul permanent la ea insasi
Ca urmare a scrierii programului in acest mod, memoria de program a sistemului dupa ce s-au parcurs etapele de asamblare, link-editare si conversie OBJ->HEX (IntelHEX code), va cuprinde in ordine, la adresa 0 instructiunea de salt la programul principal, instructiunile de salt catre rutinele de servire a intreruperilor si rutinele de servire a intreruperilor si programul principal in ordinea specificata prin dispozitiile INCLUDE. Odata inscris in memoria flash a procesorului sistemul este gata sa satisfaca functiunile specificate in raport cu protocolul stabilit.
Varianta cu microcontroller RISC (PIC - Michrocip)
Implementarea aceleiasi aplicatii utilizand procesorul PIC16F84 presupune urmatoarele:
Implementarea interfetei cu aplicatia, respectiv comanda celor doua electrovalve si a pompei de presiune
Implementarea controlului cursei pistonului, adica achizitia semnalelor digitale de la cele doua limitatoare
Implementarea interfetei seriale ce asigura conexiunea catre nivelul ierarhic superior, pentru aplicatia noastra.
Figura 6, Structura
microcontroller-ului PIC16F84
Vom analiza pe scurt care sunt principalele elemente
caracteristice ale procesorului ales.
Structura acestuia este prezentata in figura 6.
Dispune de 13 linii utilizabile ca linii de intrare/iesire cu capabilitate ridicata in curent (pana la 20 mA, fiecare). Arhitectura procesorului este Harvard, cu latimea magistralei de date de 8 biti si a celei corespunzatoare memoriei de program de 14 biti. Dispune de 1Ko memorie de program (flash sau EPROM), de 2x128 bytes memorie SRAM organizata in doua zone, zona SFR (Special Function Regsiter) si zona GPR (General Purpose Register) si de 64 bytes memorie EEPROM ce poate fi inscrisa si stearsa prin program. Dispune de un canal temporizator/numarator sau ce poate indeplini functia de Watch Dog de 8 biti cu un prescaler de 5 biti. Controller-ul de intreruperi intern admite 4 surse de intreruperi: una externa (RB0/INT, una de la canalul TMR0 (timer overflow), una de la portul B comuna pentru 4 dintre liniile portului care genereaza o intrerupere la schimbarea nivelului logic de semnal pe ele si o intrerupere interna generata la scrierea datelor in EEPROM. Stiva microcontroller-ului este mai deosebita, respectiv este implementata intr-o zona speciala a memoriei interne si are maximum 8 nivele nefiind permisa citirea sau inscrierea acesteia prin adresare directa. Procesorul nu dispune de instructiuni PUSH sau POP si astfel doar prin instructiuni de tipul CALL, GOTO, RETURN, RETFIE si RETLW putem introduce, respectiv extrage informatii la nivelul stivei. O observatie importanta de care va trebui sa tinem cont, este aceea ca nu este prevazut nici un indicator de depasire a dimensiunii stivei, ceea ce poate duce la grave erori atunci cand numaruil de apeluri sau de instructiuni GOTO este mai mare de 8.
Instructiunile procesorului au o latime de 14 biti si ele include atat codul respectiv cat si operanzii aferenti acestuia, respectiv adresa registrului din zona file Register si/sau indexul bitului corespunzator locatiei respective.
Instructiunile de salt, cum ar fi, CALL si GOTO sunt singurele care dureaza mai mult de un ciclu instructiune si care necesita modificarea continutului PC-ului.
Setul de instructiuni al procesorului este "ortogonal", ceea ce presupune ca modalitatea de acces la orice locatie de memorie este identica aat la scriere cat si la citire, atat pentru zona GPR cat si pentru zona SFR.
In cazul operatiilor calate pe bit, instructiunile vor citi intai tot registrul, vor opera pe bitul selectat ( specificat ) si vor intoarce inapoi rezultatul in registru specificat.
Uniformitatea in tratare atat la nivel de bit cat si la nivel de octet, precum si a registrilor de uz general si speciali si a porturilor permite reducerea semnificativa a operatiilor de transfer intermediar care sunt specifice procesoarelor CISC.
Este de mentionat ca Work Regsiter (W Register), functioneaza ca acumulator si participa la majoritatea instructiunilor atat cele de transfer direct cat si la cele de transfer indirect -via un registru de adresare INDR -, adica un registru ce memoreaza adresa sursa sau destinatie a informatiilor.
Iata cateva instructiuni pe care in cadrul programului le vom utiliza. Prezentarea lor o facem pentru ca ele prezinta trasaturi specifice in raport cu cele de la microcontroller-ul Atmel.
Aceste instructiuni le vom putea clasifica asa in :
Instructiuni de transfer, aritmetico-logice si de redirectare a programului, cum ar fi:
Pot contine drept parametrii pana la trei valori si anume:
Prin k (8 biti) specificam o valoare imediata ce este inclusa in corpul instructiunii
Prin f (8 biti) specificam adresa din zona de memorie File Register la care face referire instructiunea.
Prin b specificam bitul la care face referire instructiunea (valoare pe 3 biti)
Falg-ul d specifica registrul destinatie in care se stocheaza rezultatul operatiei sau al transferului, daca acesta este 0, atunci rezultatul este retinut in regsitrul W, altfel el este retinut in regsitrul f din File Register.
MOVF f,d Transfer data intre W si registrul f cu indicarea registrului de memorare a rezultatului.
MOVWF f Transfer data din W in registrul f
MOVLW k Transfer valoare imediata k (specificata in cadrul instructiunii) in registrul W.
SWAPF f,d Comutare semi-bytes in cadrul registrului f cu retinerea rezultatului in W sau f functie de d.
ANDWF f,d SI-LOGIC, intre informatiile din W si F, bitul d are acelasi rol,
ANDLW k SI-LOGIC intre valoarea specificata k si valoarea stocata in W. Rezultatul este retinut in W.
ADDWF f,d Adunarea informatiilor din W si F, bitul d specifica destinatia rezultatului.
ADDLW k Adunarea intre valoarea specificata k si valoarea stocata in W. Rezultatul este stocat in registrul W.
SUBWF f,d Scaderea informatiile din W si F cu acelasi rol pentru flag-ul d
SUBLW k SI-LOGIC intre valoarea specificata k si valoarea stocata in W. Rezultatul este stocat in registrul W.
IORWF f,d SAU-LOGIC, intre informatiile din W si F, bitul d are acelasi rol,
IORLW k SAU-LOGIC intre valoarea specificata k si valoarea stocata in W. Rezultatul este retinut in W.
XORWF f,d SAU-EXCLULSIV, intre informatiile din W si F, bitul d are acelasi rol,
XORLW k SAU-EXCLUSIV, intre valoarea specificata k si valoarea stocata in W. Rezultatul este retinut in W.
CALL k Apel rutina k (11/13 niti specificati prin instructiune)
GOTO k Salt la adresa k (11/13 niti specificati prin instructiune)
RETURN Revenire din subrutina
RETFIE Revenire din subrutina de tratare a intreruperilor
RETLW k Revenire din subrutina cu incarcarea unei valori "literale" in W.
Instructiunilede setare/resetare bytes sau biti, cele de rotire pot fi incadrate in categoria curenta, unele dintre acestea le vom detalia, avand in vedere particularitatile pe care ele le prezinta. Spre exemplu, instructiunea :
RRF f,d nu face altceva decat sa deplaseze catre dreapta cu o pozitie informatia din registrul f, rezultatul fiind retinut conform valorii lui d, in W sau chiar in registrul f. La fiecare deplasare, bitul 0 este mutat in bitul de C (de transport), iar acesta este transferat in bitul 7 al registrului f.
Analog,
functioneaza si instructiunea RLF f,d , caz in care bitul C (de transport) va fi copiat in bitul
0 al registrului f si bitul 7 al aceluiasi registru fi memorat in C.
Instructiuni de decizie:
BTFSS Test bit si salt peste instructiunea urmatoare daca acesta este 1 logic
BTFSC Test bit si salt peste instructiunea urmatoare daca acesta este 0 logic
Instructiuni ce permit executia repetitiva a unui sir de operatii:
DECFSZ f,d Decrementeaza registrul f si sare instructiunea urmatoare daca este zero rezultatul. Valoarea rezultat este retinuta functie de flag-ul d in W d=0 sau f d=1.
INCFSZ f,d Incrementeaza registrul f si sare instructiunea urmatoare daca este zero rezultatul. Valoarea rezultat este retinuta functie de flag-ul d in W d=0 sau f d=1.
Restul instructiunilor de resetare sau setar pe bit si byte, cele de incrementare si decrementare, cele de complementare si instructiunea NOP sunt prezentate in anexa la curs. (vezi documentul 30430c.pdf de la Microchip).
Vom utiliza instructiunile de deplasare la dreapta prin bitul de carry pentru emularea UART.
Registrii generali ai microcontroller-ului asigura pe de-o parte implementarea functiunilor de control pentru program, iar pe de alta parte permit memorarea datelor si transferul comenzilor catre mediul extern. Iata structura celor mai importanti dintre acestia.
STATUS
IRP |
RP1 |
RP0 |
T0# |
PD# |
Z |
DC |
C |
IRP este bitul care selecteaza bancul de registrii ( la adresarea indirecta) valoarea 0 corespunde intervalului de adrese 00H la FFH, iar valoarea 1 corespunde intervalului 100H la 1FFH.
RP1,RP0 corespunde selectiei bancului de registrii (la adresarea directa) selectei astfel:
00 corespunde intervalului de adrese 00H la 7FH
01 corespunde intervalului de adrese 80H la FFH
10 corespunde intervalului de adrese 100H la 17FH
11 corespunde intervalului de adrese 180H la 1FFH
T0# (time out bit), exprima depasirea capacitatii de numarare a canalului 0, respectiv tranzitia de stare de la FFH spre 00H.
PD# (Power Down), odata setat exprima "trezirea sistemului", la pornirea acestuia sau dupa executia instructiunii CLRWDT.In rest bitul de mai sus este resetat.
Z (Zero flag), este setat la intalnirea coincidentei a doua valori numerice sau cand rezultatul operatiei aritmetico-logice este zero. In rest, acesta este resetat.
DC (Digital Carry), exprima transportul sau imprumutul la nivel de semibyte. Setat la aparitia transportului, resetat la aparitia unui imprumut.
C (Carry), este setat la aparitia unui transport la nivel de byte, si resetat in rest.
OPTION
RBPU# |
INTEDG |
TOCS |
TOSE |
PSA |
PS2 |
PS1 |
PS0 |
RBPU#, (Pull up bits port B),setat exprima invalidarea functiunii pull-up pentru liniile portului B, iar resetat, asigura functia pull-up pentru aceste linii.
INTEDG (Interrupt Edge Select) setat permite generarea intreruperilor pe frontul crescator, iar resetat realizeaza generarea intreruperii pe frontul descrescator.
TOCS (TMR0 Source Clock), selecteaza sursa impulsurilor ce sunt numarate de catre canalul 0 numarartor/temporizator, setat permite numararea impulsurilor externe, aplicate la pinul RA4, resetat selecteaza frecventa interna de ceas divizata cu 4.
TOSE (TMR0 Source Edge Select), setat realizeaza incrementarea numaratorului canalului pe frontul negativ, iar reseta incrementeaza impulsurile pe frontul pozitiv.
PSA, (Prescaler Assignemet Bit), setat asigneaza prescaler-ul pentru WDT (Watch Dog Timer), resetat il rezerva pentru canalul TMR0.
PS2, PS1, PS0 (Biti de selectie a constantei de divizare a prescaler-ului), dupa cum urmeaza:
000H reprezinta ½ ptr. TMR0 si 1/1 pentru WDT
001H reprezinta 1/4 ptr. TMR0 si 1/2 pentru WDT
010H reprezinta 1/8 ptr. TMR0 si 1/4 pentru WDT
011H reprezinta 1/16ptr. TMR0 si 1/8 pentru WDT
100H reprezinta 1/32 ptr. TMR0 si 1/16 pentru WDT
101H reprezinta 1/64 ptr. TMR0 si 1/32 pentru WDT
110H reprezinta 1/128 ptr. TMR0 si 1/64 pentru WDT
111H reprezinta 1/256 ptr. TMR0 si 1/128 pentru WDT
Structura canalului
temporizator/numarator este ilustrata in figura 8.
Intreruperile in cazul microcontroller-ului PIC16F84 au un singur "vector", si anume cel plasat la adresa 004H din memoria de program, iar cum sursele de intreruperi sunt in numar de patru este necesar sa implementan in cadrul rutinei de servire programul de identificare si apoi de tratare a acestora. Registrul INTCON, este cel ce da posibilitatea utilizatorului sa valideze sau invalideze atat declasarea intreruperilor de la diverse surse, cat si sa valideze sau invalideze global intreruperile.
INTCOM
GIE |
EEIE |
TOIE |
INTE |
RBIE |
TOIF |
INTF |
RBIF |
GIE, (Global Interrupt Enable), permite setat sa valideze acele cereri de intrerupere ce apar daca acestea au fost validate si individual, respectiv resetat inhiba orice cerere de intrerupere.
EEIE (EEPROM Interrupt Enable) setat valideaza intreruperile la operatiile de scriere sau citire a EEPROM-ului intern, resetat ignora acestecereri de intrerupere
TOIE (TMR0 Overflow Enable), setat valideaza intreruperile corespunzatoare depasirii la canalul temporizator/numarator, resetat acestea sunt ignorate
INTE (External Interrupt Enable), valideaza intreruperile datorate variatiei semnalului aplicat pe intrarea RB0 atunci cand este setat, respectiv resetat le ignora
RBIE (B Register Interrupt Enable), setat valideaza intreruperile datorate schimbarii starii uneia dintre intrarile portului RB7, RB6, RB5 sau RB4 al microcontroller-ului, respectiv, resetat ignora schimbarile de stare la nivelul portului RB
TOIF (Timer Overflow Interrupt Flag), este setat hard la aparitia starii "depasire" a capacitatii numaratorului corespunzator canalului 0, resetat in rest.
INTF (Interrupt Flag) setat hard la aparitia unei intreruperi la nivelul liniei RB0, in rest resetat.
RBIF (B Port Interrupt Flag), setat hard, atunci cand una sau mai multe linii ale portului B au schimbat starea, resetat in rest.
Ca observatie generala trebuie retinut ca bitii de stare prezenti in structura registrului INTCON sunt setati hard (prin mecanismul implementat in cadrul microcontroller-ului) si programatorul, in cadrul rutinei de servire a intreruperilor va trebui sa-i reseteze, pentru a putea detecta urmatoarea conditie de declasare a intreruperilor.
Registrii EEDATA (EEPROM Data Register -retine data de inscris sau de sters din/in EEPROM), EEADR (EEPROM address), retine adresa de memorie la care, sau de la care se face: scrierea, respectiv citirea datelor si registrii EECON1 si EECON2 permit efectuarea memorarii datelor in memoria EEPROM asignand comenzile de scriere WR sau citire si cele de validare.
Avand imaginea registrilor prcesorului sa gandim cum am putea utiliza acest microcontroller pentru transferul datelor si implementarea functiunilor actuatorului electro-hidraulic.
Observam un fapt mai putin imbucurator: circuitul nu dispune de o interfata seriala implementata hard, deci va trebui sa o emulam soft (prin program).
In ceea ce insemna implementarea controlului, observam ca portul B este deosebit de util el detectand automat variatia nivelului logic pe liniile RB4 la RB7. In figura 9 dam schema electrica de conectare propusa, schema in care am ignorat eventualele circuite amplificatoare in comutatie sau formatoare de implus.
Pentru liniile RxD si respectiv TxD, vom folosi liniile portului B si anume RB6 (atentie vom utiliza si facilitatea de generare a intreruperilor la schimbarea nivelului logic pe aceasta intrare, in acest sens vom folosi posibilitatea pe care aceasta linie o ofera, de generare a intreruperii la sesizarea bitului de START in cazul transmisiei seriale), respectiv RB1 pentru transmisie.
Principalele idei in baza carora vom emula interfata seriala sunt urmatoarele:
programam timer0 astfel incat acesta sa genereze cate o intrerupere cu frecventa cat mai apropiata de frecventa de transfer serial a informatiilor
transferam cu ocazia servirii intreruperii corespunzatoare, cate un bit si rotim informatia respectiva pentru a simula felul in care decurge transferul serial pe un UART implementat hard.
vom stabili rata de transfer seriala, programand corespunzator timer-ul 0 pentru aceasta. Iata cum se realizeaza acest lucru:
Formula de calcul -aproximativa[3]- pentru stabilirea frecventei de daca presupunem utilizarea unui microcontroller ce functioneaza la fClk=10MHz va fi:
, unde BR este rata de tranmisie seriala ( o vom stabili la 19200 Bauds), fClk este frecventa de ceas a sistemului, PS este factorul de divizare al prescaler-ului, iar CT este constanta de timp incarcata de catre programator. Formula nu tine cont de erorile datorate momentului de timp la care are loc reincarcarea constantei de timp si de timpul necesar microcontroller-ului pentru a intra in ISR.
In cazul nostru, vom obtine: 130 valoarea produsului PS*(256-CT). Considerand pentru PS valoarea 1, deci nu utilizam prescaler-ul, vom inscrie in registrul corespunzator timer-ului 0, valoarea 7EH.
Atentie, este de observat ca timer-ul numara in sens direct, deci valoarea corespunzatoare este data de diferenta intre valoarea la care se realizeaza consemnarea depasirii capacitatii canalului si valoarea dorita.
Eroarea datorata rotunjirii valorii corespunzatoare ratei de transfer va fi de 0,16%.[4]
Pentru a implementa aceasta functie, vom folosi cateva locatii de memorie si anume:
CHR_TRS: locatie ce memoreaza octetul de transmis
CHR_REC: locatie ce retine octetul receptionat
RI bit ce specifica receptia completa a caracterului pe linia seriala
TI bit ce exprima transmisia completa a caracterului pe linia seriala
R bit ce exprima transferul in curs la receptie (este utilizat de ISR).
T bit ce exprima transferul in curs la transmisie(este utilizat de ISR).
Transferul se va efectua semi-duplex, cu 8 biti/caracter, un bit de start si unul de stop.
Structura byte-ului de stare este cea de mai jos:
SI_STARE
T |
R |
TI |
RI |
END |
C2 |
C1 |
C0 |
Unde:
END are semnificatia de sfarsit transmisie sau receptie byte
C2,C1,C0 sunt bitii utilizati pentru contorul de biti, transmisi sau receptionati
Astfel, la transmisie vom face urmatoarele:
Transferam la locatia CHR_TRS octetul de transmis si setam flag-ul INT_TRS.
Resetam linia TxD (respectiv bitul corespunzator ei, adica RB1) semnalizand bitul de start (Break pentru transmisie).
Setam bitul T, ce exprima ocuparea CPU (Central Processing Unit) cu transferul serial.
Initiem ceasul de transmisie, adica programam TMR0 in scopul generarii intreruperilor
Vom inscrie bitul corespunzator la fiecare intrerupere pana la transefrul complet al celor 8 biti.
Setam linia RB1, cel putin pentru o perioada de ceas, (bitul de stop), setam bitul TI ce exprima incheierea transmisiei caracterului ("buffer de transmisie gol") pentru programul principal si resetam bitul T -eliberand astfel UC de task-ul de serializare a informatiilor.
La receptie este necesar sa parcurgem urmatoarele etape:
La aparitia schimbarii de stare pe bitul RB0, setam bitul ce consemneaza ocuparea interfetei seriale, respectiv bitul R.("receptie in curs").
Pe fiecare intrerupere de timp vom citi (esantiona) linia seriala la receptie - RB0 - si vom scrie in Carry Flag bitul citit si vom deplasa la dreapta prin carry byte-l CHR_REC ce va contine ceea ce receptam.
Dupa 8 ciclii de temporizare, vom seta bitul RI, ce specifica pentru programul principal, receptia completa a caracterului ("caracter receptionat disponibil"), resetand in acelasi timp bitul CHR_REC. Va fi necesar sa invalidam intreruperile corespunzatoare canalului 0 temporizator, respectiv TMR0.
Avand in vedere structura de registri ai procesorului, precum si faptul ca punctul de intrare in rutina de servire a intreruperilor este unic, va trebui ca aceasta sa implementeze absolut toate functiunile ce impun sincronizarea CPU cu mediul extern. De aceea, programul principal va initializa sistemul si nu va face decat sa astepte intreruperile si sa dea comenzile corespunzatoare informatiilor receptionate din mediul extern dupa prealabila memorare si analiza a acestora (informatiile provin de la interfata seriala sau sunt culese din proces).
Byte-ul de stare a sistemului va avea aceiasi structura ca si in cazul implementarii anterioare. In plus, avand in vedere variabilele care controleaza starea interfetei seriale UART, am mai introdus locatia INT_TRS ce retine cererea de transfer a unui caracter.
In cadrul fisierului sursa am inclus si o serie de instructiuni auxiliare cum sunt:
DB dispozitie de asamblare care permite rezervarea unui byte in memoria de date a microcontroller-ului.
EQU dispozitie ce permite definirea valorii unei variabile.
ORG dispozitie ce asigura asamblarea incepand de la adresa specificata a codului obiect.
Iata in continuare programul ce implementeaza aplicatia:
list p=16f84
#include p16f84.inc
ORG 0x00
START GOTO MAIN
ORG 0x04
ISR
;Salvare stare microcontroller PIC, respectiv W si STATUS
MOVWF TEMP_WORK ; TEMP_WORK <-W
MOVF STATUS,W ; W <- STATUS
MOVWF TEMP_WORK1 ; TEMP_WORK1 <- W
BTFSC INTCON,INTF ;Testare aparitie bit de start pe RxD
GOTO PRIM_CHR ;Directare spre rutina ce initiaza receptia
;seriala a caracterelor
BTFSC INTCON,RBIF ;Testare mofidififcare stare L1 sau L2
GOTO LIMITATORI ;Directare spre rutina de tratare corespunzatoare
;atingerii limitatorilor de cursa ai actuatorului electro-hidraulic
BTFSC INTCON,T0IF ;Testare depasire contor TMR0
GOTO REC_TRS ;Directare spre rutina corespunzatoare
;depasirii contorului de timp corespunzator
MOVF INTCON,W ; W <- INTCON
ANDLW 0xF8 ;Resetez contorul de biti
MOVF INTCON,F ; INTCON <- W
END_ISR
;Refac starea microcontroller-ului
MOVF TEMP_WORK1,W
MOVWF STATUS
MOVF TEMP_WORK,W
RETFIE
PRIM_CHR
BCF INTCON,INTE ;Invalidez INTE Nu mai accept alte intreruperi de la RxD
;(revalidarea se va face doar la sfarsitul receptiei complete a caracterului curent, odata cu setarea flag-ului RI)
MOVLW 3/2*CT ;Incarc in W: 3/2 din constanta de timp corespunzatoare
;perioadei frecventei de transmisie seriale a datelor (vezi diagrama de timp)
;De ce? Caci esantionarea liniei RxD se face cat mai aproape de mijlocul perioadei de ceas a UART.
MOVF TMR0,F ; TMR0 <- W
BSF SI_STARE,6 ;Setez indicatorul 'in receptie' respectiv flag-ul R
MOVF SI_STARE,W ;Incarc in W vectorul de stare: W <- SI_STARE
ANDLW 0xF8 ;Resetez bitii 0,1 si 2, respectiv contorul de biti la receptie
MOVF SI_STARE,F ; SI_STARE <- W
;Se poate introduce in acest punct testul de overrun la receptie (receptia 'peste' un alt caracter a caracterului curent
BCF INTCON,INTF ;Resetez flag-ul INTE corespunzator liniei RxD
GOTO END_ISR
LIMITATORI
BCF INTCON,RBIF ;Resetez flag-ul indicator al intreruperii
;datorate variatiei starii liniilor portului B de la 4 la 7
BTFSS PORTB,4 ;Testare atingere limitator L1?
;Da! A fost atins
GOTO L1_ATINS
;Nu!
BTFSS PORTB,5 ;Testare atingere limitator L2?
;Da! A fost atins
GOTO L2_ATINS
;Ignorare intrerupere la schimbarea de stare, respectiv ignorare fronturi pozitive
;ale semnalelor de la limitatoarele 1 si 2
GOTO END_ISR
L1_ATINS
BCF PORTB,3 ;Opreste comanda Ev2
BCF PORTA,0 ;Opreste comanda pompa de fluid
;Actualizeaza starea sistemului in vectorul STARE
BSF STARE,0 ;Atins limitator L1 pozitie retras
BCF STARE,2 ;Oprita miscarea actuatorului
GOTO END_ISR
L2_ATINS
BCF PORTB,2 ;Opreste comanda Ev1
BCF PORTA,0 ;Opreste comanda pompa de fluid
;Actualizeaza starea sistemului in vectorul STARE
BSF STARE,1 ;Atins limitator L2 pozitie avansat
BCF STARE,2 ;Oprita miscarea actuatorului
GOTO END_ISR
REC_TRS
BTFSC SI_STARE,6 ;Test intrerupere de la TMR0 la receptia caracterelor?
;Da! Intrerupere la receptia caracterelor
GOTO RECEPTIE
;Nu!
BTFSC SI_STARE,7 ;Test intrerupere de la TMR0 la transmisia caracterelor?
;Da! Intrerupere la transmisia caracterelor
GOTO TRANSMISIE
;Nu! Eroare, refacem doar flag-ul ce semnaleaza intreruperea corespunzator lui TMR0
BCF INTCON,T0IF
GOTO END_ISR
RECEPTIE
BTFSS PORTB,0 ;Esantionare linie RxD (linia RxD este linia RB0)
;Da, linia este zero!
GOTO REC_ZERO
;Nu, Setez carry flag
BSF STATUS,C ;Setez bitul 0 din STATUS reg. care este Carry Flag
GOTO REC_CONT
REC_ZERO
BCF STATUS,C ;Resetez bitul 0 din STATUS reg. care este Carry Flag
REC_CONT
RRF CHR_REC,F ;Rotesc prin Carry locatia (file register REC_CHR)
;Bitul de Carry va ajunge in pozitia bitului 7 din REC_CHR si dupa 8 biti receptati pe pozitia 0
INCF SI_STARE,F ;Incrementez contorul din SI_STARE si il salvez in el insusi
BTFSS SI_STARE,3 ;Testez atingerea receptiei celui de-al 8-lea bit al caracterului
GOTO END_REC_BIT
END_REC_CHR
BCF SI_STARE,6 ;Resetez flag-ul ce indica starea 'in receptie caracter'
BSF SI_STARE,4 ;Setez flag-ul RI, 'Caracter receptionat disponibil'
BCF INTCON,T0IF ;Resetez flag-ul ce semnalizeaza overflow canal temporizator
BCF INTCON,T0IE
;Invalidez intreruperile corespunzatoare canalului temporizator
BCF SI_STARE,3 ;Resetez contor numarator biti receptionati
GOTO END_ISR
END_REC_BIT
MOVWF CT ;Incarc constanta de temporizare in W
MOVF TMR0,F ;O transfer catre TMR0
BCF INTCON,T0IE
;Resetez flag-ul corespunzator intreruperilor de la TMR0, pentru a reanclansa timer-ul
GOTO END_ISR
TRANSMISIE
BTFSC SI_STARE,3
;Test corespunzator incheierii transferului datelor ce formeaza caracterul -cei 8 biti-
GOTO TEST_END_TRS
CONT_TRS
BTFSC CHR_TRS,0
GOTO SET_BIT_TRS
BCF PORTB,1 ;Scriu 0 logic pe linia TxD
GOTO TRS_BITI
SET_BIT_TRS
BSF PORTB,1 ;Scriu 1 logic pe linia TxD
TRS_BITI
RRF CHR_TRS,F ;Rotesc bitii caracterului de transmis in buffer transmisie
MOVLW CT
MOVF TMR0,F
;Reincarc constanta de timp corespunzatoare frecventei de transmisie pe UART
BCF INTCON,T0IF ;Resetez flag-ul indicator timer overflow
BSF INTCON,T0IE ;Validez intreruperile ptr. canalul temporizator
INCF SI_STARE ;Incrementez contorul de biti la transmisie
GOTO END_ISR
TEST_END_TRS
BTFSC SI_STARE,0 ;Testez daca este de transmis bitul de STOP
GOTO END_TRS
TRS_STOP_BIT
BSF PORTB,1 ;Scriu 1 logic pe linia seriala, corespunzator bitului de STOP
GOTO TRS_BITI
END_TRS
BCF INTCON,T0IE ;Invalidez intreruperilor corespunzatoare TMR0
BCF INTCON,T0IF ;Sterg flag-ul indicator de intrarupere
MOVLW 0x76 ;Maschez bitul T, si bitii contorului de biti ai UART
ANDWF SI_STARE,F ;Realizez resetarea bitilor 7,3 si 0 din SI_STATUS
BSF SI_STARE,5 ;Setez TI, indica 'buffer transmisie gol'
GOTO END_ISR
INIT
MOVLW 0x0C
MOVWF FSR
NEXT
CLRF INDF
INCF FSR
BTFSC FSR,6
GOTO NEXT
BTFSC FSR,4
GOTO NEXT
;Umple cu 0 memoria SRAM a microcontroller-ului de la adresa 0x0C la 0x4F
BCF STATUS,RP0 ;Select bank 0
MOVLW 0x02
MOVF PORTB,F
MOVLW 0x01
MOVF PORTA,F
BSF STATUS,RP1 ;Select bank 1
MOVLW 0x31
MOVWF TRISB
MOVLW 0x00
MOVWF TRISA
BCF STATUS,RP0
;Initializeaza porturile A si B
RETURN
; ** ** ** ** ** ** ** ** ** ** ***** MAIN
CALL INIT
LOOP
BTFSC SI_STARE,4 ;Testare daca a fost receptionat un caracter pe UART
CALL EXEC_CDA ;Exexcutie comanda venita pe UART de la PC
CONTINUE0
BTFSC INT_TRS,0 ;Testare daca este de transmis un caracter via UART
CALL INIT_TRS
CONTINUE1
GOTO LOOP
EXEC_CDA
MOVLW 0x41 ;Incarc comanda 'A' - avans
XORWF CHR_REC,W ;Testez identitatea intre caracterul receptionat si 'A'
BTFSC STATUS,Z ;Testez identitatea Z=1 IDENTIC
GOTO AVANS ;Executa avans
MOVLW 0x52 ;Incarc comanda 'R' - retragere
XORWF CHR_REC,W ;Testez identitatea intre caracterul receptionat si 'r'
BTFSC STATUS,Z ;Testez identitatea Z=1 IDENTIC
GOTO RETRAGERE
MOVLW 0x53 ;Incarc comanda 'S' - stare
XORWF CHR_REC,W ;Testez identitatea intre caracterul receptionat si 'S'
BTFSC STATUS,Z ;Testez identitatea Z=1 IDENTIC
GOTO REQ_STARE
MOVLW 0x50 ;Incarc comanda 'P' - pozitie
XORWF CHR_REC,W ;Testez identitatea intre caracterul receptionat si 'P'
BTFSC STATUS,Z ;Testez identitatea Z=1 IDENTIC
GOTO POZITIE
END_EXEC_CDA
BCF SI_STARE,4
;Resetez flag corespunzator caracterului receptionat disponibil, Acesta a fost citit si interpretat
RETURN
AVANS
BSF PORTB,2 ;Comand Ev1
BSF PORTA,0 ;Comanda Pompa de presiune
BCF STARE,0 ;Resetez stare actuator coresp. lui L1 atins
BSF STARE,2 ;Setez starea 'actuator in miscare'
GOTO END_EXEC_CDA
RETRAGERE
BSF PORTB,3 ;Comand Ev1
BSF PORTA,0 ;Comanda Pompa de presiune
BCF STARE,1 ;Resetez stare actuator coresp. lui L1 atins
BSF STARE,2 ;Setez starea 'actuator in miscare'
GOTO END_EXEC_CDA
REQ_STARE
BTFSS STARE,2 ;Testez daca actuatorul atinge limitatorul 1
;Da! Consemneaza stare si initiaza emisie ecou
GOTO READY
BUSY
MOVLW 0x42 ; W <-'B' Busy
MOVF CHR_TRS,F ; CHR_TRS <- W
BSF INT_TRS,0 ;Initiere transmisie
GOTO END_EXEC_CDA
READY
MOVLW 0x44 ; W <-'D' reaDy
MOVF CHR_TRS,F ; CHR_TRS <- W
BSF INT_TRS,0 ;Initiere transmisie
GOTO END_EXEC_CDA
POZITIE
BTFSC STARE,0
GOTO LIM1
BTFSC STARE,1
GOTO LIM2
BTFSC STARE,2
GOTO MOVE
GOTO END_EXEC_CDA
LIM1
MOVLW 0x49 ; W <-'I' retras (L1 Atins)
MOVF CHR_TRS,F ; CHR_TRS <- W
BSF INT_TRS,0 ;Initiere transmisie
GOTO END_EXEC_CDA
LIM2
MOVLW 0x45 ; W <-'E' avansat (L2 Atins)
MOVF CHR_TRS,F ; CHR_TRS <- W
BSF INT_TRS,0 ;Initiere transmisie
GOTO END_EXEC_CDA
MOVE
MOVLW 0x4C ; W <-'M' in miscare (L1 si L2 Liberi)
MOVF CHR_TRS,F ; CHR_TRS <- W
BSF INT_TRS,0 ;Initiere transmisie
GOTO END_EXEC_CDA
INIT_TRS
BTFSS SI_STARE,5 ;Testez daca TI este activ,
;In acest caz nu am voi sa initiez o noua transmisie, voi astepta!
GOTO END_INIT_TRS
BCF PORTB,1 ;Scriu 0 logic pe linia TxD
MOVLW CT
MOVF TMR0,F ;Incarc constanta de timp ptr. TMR0
BSF SI_STARE,7 ;Set 'transmisie in curs'
BSF INTCON,T0IE ;Validez intreruperile corespuinzatoare lcanalului TMR0
END_INIT_TRS
RETURN
STARE DB 0x00 ;Vectorul de stare al actuatorului electro-hidraulic
;Bit 0 L1 atins
;Bit 1 L2 atins
;Bit 2 in miscare
SI_STARE DB 0x00 ;Vectorul de stare corespunzator UART emulat
CHR_REC DB 0x00 ;Locatie ce retine caracterul receptionat
CHR_TRS DB 0x00 ;Locatie ce retine caracterul de transmis
TEMP_WORK DB 0x00 ;Locatie ce memoreaza Work register pe durata ISR
TEMP_WORK1 DB 0x00 ;Locatie ce memoreaza STATUS register pe durata ISR
INT_TRS DB 0x00
;Locatie ce memoreaza in bitul 0 cererea de transmisie a unui caracter. TR 'Transmission request'
CT EQU 0x7E ;Constanta de timp corespunzatoare ceasului UART
end
In text toate etichetele la care se face referire sunt scrise cu caractere ingrosate. Pentru a avea imaginea modului in care assembler-ul plaseaza codul nostru, dam si partea referitoare la locatare din listing-l rezultat in urma asamblarii. Aceasta lista este data cu titlu informativ pentru a putea sesiza modalitatea in care sunt asignate locatiile de memorie, variabilelor.
MPASM 02.40 Released 16F84.ASM 11-22-2000 2:36:03 PAGE 8
SYMBOL TABLE
LABEL VALUE
AVANS 0000008A
BUSY 00000096
C 00000000
CHR_REC 000000BB
CHR_TRS 000000BC
CONTINUE0 00000075
CONTINUE1 00000077
CONT_TRS 00000048
CT 00000056
DC 00000001
EEADR 00000009
EECON1 00000088
EECON2 00000089
EEDATA 00000008
EEIE 00000006
EEIF 00000004
END_EXEC_CDA 00000088
END_INIT_TRS 000000B8
END_ISR 00000010
END_REC_BIT 00000042
END_REC_CHR 0000003C
END_TRS 00000058
EXEC_CDA 00000078
F 00000001
FSR 00000004
GIE 00000007
INDF 00000000
INIT 0000005E
INIT_TRS 000000B1
INTCON 0000000B
INTE 00000004
INTEDG 00000006
INTF 00000001
INT_TRS 000000BF
IRP 00000007
ISR 00000004
L1_ATINS 00000023
L2_ATINS 00000028
LIM1 000000A5
LIM2 000000A9
LIMITATORI 0000001D
LOOP 00000073
MAIN 00000072
MOVE 000000AD
NEXT 00000060
NOT_PD 00000003
NOT_RBPU 00000007
NOT_TO 00000004
OPTION_REG 00000081
PCL 00000002
PCLATH 0000000A
PORTA 00000005
PORTB 00000006
MPASM 02.40 Released 16F84.ASM 11-22-2000 2:36:03 PAGE 9
SYMBOL TABLE
LABEL VALUE
POZITIE 0000009E
PRIM_CHR 00000014
PS0 00000000
PS1 00000001
PS2 00000002
PSA 00000003
RBIE 00000003
RBIF 00000000
RD 00000000
READY 0000009A
RECEPTIE 00000033
REC_CONT 00000038
REC_TRS 0000002D
REC_ZERO 00000037
REQ_STARE 00000094
RETRAGERE 0000008F
RP0 00000005
RP1 00000006
SET_BIT_TRS 0000004C
SI_STARE 000000BA
STARE 000000B9
START 00000000
STATUS 00000003
T0CS 00000005
T0IE 00000005
T0IF 00000002
T0SE 00000004
TEMP_WORK 000000BD
TEMP_WORK1 000000BE
TEST_END_TRS 00000054
TMR0 00000001
TRANSMISIE 00000046
TRISA 00000085
TRISB 00000086
TRS_BITI 0000004D
TRS_STOP_BIT 00000056
W 00000000
WR 00000001
WREN 00000002
WRERR 00000003
Z 00000002
_CP_OFF 00003FFF
_CP_ON 0000000F
_HS_OSC 00003FFE
_LP_OSC 00003FFC
_PWRTE_OFF 00003FFF
_PWRTE_ON 00003FF7
_RC_OSC 00003FFF
_WDT_OFF 00003FFB
_WDT_ON 00003FFF
_XT_OSC 00003FFD
__16F84 00000001
MPASM 02.40 Released 16F84.ASM 11-22-2000 2:36:03 PAGE 10
In final vom face o scurta analiza comparativa a solutiilor avute in vedere la implementarea aplicatiei.
Criteriul |
Atmel AT89C2051 |
PIC16F84 |
Procesorul Arhitectura Setul de instructiuni Registrii de uz general Memoria interna Numar intrari/iesiri: Linii de comanda/control Canale temporizatoare WatchDog UART Sistemul de intreruperi Alte facilitati speciale Tensiune alimentare Programarea controller-ului Memoria de program Facilitati energetice |
Von Neumann CISC[5] 4 bancuri a cate 8 registrii fiecare 128 bytes 15 I/O 2 (4 moduri de programare) 1 canal (8 biti) 256 valori 1 canal sincron/asincron Vectorizat[6] Dispune de 2 intrari analogice[7] 2,7 la 5 V Flash Reprogramabil 2 Kbytes Low Power si IDLE mode[8] |
Harvard RISC[9] 2 Bancuri "File Registres" a cate 68 de bytes fiecare NU 13 I/O 1 (2 moduri de programare) 1 canal (8 biti) 16 valori NU Cu unica servire NU 2 la 6 V Programare tip ICSP [10] 1024 x 14 biti (RISC) PowerDown[11] si IDLE mode |
Facilitati software Assembler Compilaror C Link-editor Translator INTEL-HEX code Emulator Mediu integrat |
A51, SAM51, etc. Extrem de multe variante de asambloare C51 si altele L51 DA DA NU |
MASM macro-asamblor, integrabil in mediul MPLAB DA MPLINK DA DA DA (MPLAB) |
Aspecte economice Pret/bucata Optenabilitate: Seria produsului: |
7,24 DM (Hoepping Elektronik) DA Nu avem date precise |
8,03 DM (ASA Micros) DA Nu avem date precise |
Grad de pregatire proiectant: calat pentru microcontroller-ul respectiv |
Nu avem date precise |
Nu avem date precise |
Suport de dezvoltare[12]: |
NU |
DA |
Strategia firmei: |
NU |
NU |
Timpul preconizat pentru dezvoltarea aplicatiei |
NU |
NU |
Ce concluzii putem trage in urma analizei acestui tablou cu caracteristici ale celor doua procesoare?
Putem stabili factori de pondere corespunzatori fiecarui parametru si putem calcula coeficientul de eficienta al implementarii produsului. Un aspect deseori esential il constituie pregatirea proiectantilor, experienta lor anterioara si timpul in care se preconizeaza dezvoltarea aplicatiei. Rubricile la care nu se poate raspunde de la inceput (vezi cele ce contin "NU") pot influenta substantial eficienta deciziei, caci, spre exemplu, pregatirea unui specialist in domeniu presupune timp si bani suplimentari ceea ce nu intotdeauna ii avem. (vezi rubrica "strategia firmei").
Alte informatii privind microcontroller-ele familiei PIC de la Microchip gasiti la urmatoarele adrese:
Don McKenzie: https://www.dontronics.com/dtlinks.html
Adam Davis: https://www.ubasics.com/adam/pic/piclinks.shtml
Sam Powell: https://come.to/thepicarchive
Brian Lane: https://www.nexuscomputing.com/~picarchive/
Richard Spencer: https://engmtasd.derby.ac.uk
Michael Covington: ftp://ftp.ai.uga.edu/pub/microcontrollers/pic/
Steve Walz: ftp://ftp.armory.com/pub/user/rstevew/PIC/DaveTait/
https://www.tinaja.com/pic500.html
Iar pentru familia I8051 la adresele:
Implementarea interfetelor la proces
In acest exemplu vom aborda cateva aplicatii care presupun folosirea convertoarelor analog-digitale si a celor digital-analoge in aplicatii de comanda si control.
In acest sens vom folosi urmatoarele tipuri de convertoare:
Convertoarele analog - digitale controlabile serial
Convertoarele analog - digitale controlabile paralel
Convertoarele analog - digitale complexe
Convertoarele tensiune - frecventa
Convertoarele digital - analoge controlabile serial
Convertoarele digital - analoge controlabile serial.
Vom prezenta pentru fiecare dintre aceste cazuri atat aspectele legate de implementarea hardware, inclusiv caracteristicile convertoarelor, cat si aspectele ce tin de implementarea software.
Pentru primul exemplu, am ales un convertor reprezentativ pentru domeniul achizitiei de semnale din codrul instalatiilor industriale, si anume: ADS7822, convertor cu regsitru de aproximatii succesive a carui schema o dam in figura urmatoare.
Convertorul prezinta un amplificator de instrumentatie pe intrare la care ambele intrari sunt accesibile din exterior. Regietrul cu aproximatii succesive SAR (Succesive Aproximation Register), controlat de catre semnalele de interfatare CS#/SHDN declaseaza si apoi controleaza procesul de conversie, aplicand succesiv combinatiile ce implementeaza metoda divizarii intervalului in aflarea valorii digitale corespunzatoare semnalului de pe intrare. Domeniul de masurare este setat de catre valoarea tensiunii sursei de referinta externe ce aplica tensiunea stabilizata pe intrarea VREF. Comparatorul intoarce la fiecare tact al convertorului rezultatul comparatiei si astfel intruna cu logica de control realizeaza trecerea la testarea urmatorului bit. Convertorul va realiza in 12 ciclii testarea fiecarui bit de informatie sincron cu semnalul de ceas DCLOCK, incepand cu al 1,5-lea impuls de ceas (perioada de esantionare, caracteristica acestui convertor) dupa care informatia va fi disponibila bit de bi incepand cu bitul cel mai semnificativ pe iesirea DOUT a circuitului. "Latimea implusurilor" (durata acestora), nu trebuie sa fie mai mica de 400ns, circuitul acceptand astfel frecvente de ceas cuprinse intre 10KHz si 1,2 MHz, ceea ce corespunde unor rate de esantionare a semnalului analogic cuprinse intre:625 Hz si respectiv 75kHz.
Impulsurile corespunzatoare de ceas sunt oferite de conexiunile pe care le vom realiza intre convertor si microcontroller. Am ales tot microcontroller-ul Atmel, avand in vedere simplitatea schemei ce implementeaza aplicatia si faptul ca acesta prezinta doua canale numaratoare temporizatoare ceea ce favorizeaza aplicatia. Timing-ul este prezentat in figura 13, iar schema de conectare in figura 14.
Vom utiliza canalul 1 al circuitului drept generator al ratei de transmisie seriala a datelor, iar canalul 0 drept generator al frecventei de ceas necesara convertorului A/D.
Formarea semnalului DCLOCK va fi realizata soft, prin generarea ratei de achizitie, programand corespunzator canalul respectiv. Aici este momentul sa facem cateva comentarii:
Daca microcontroller-ul functioneaza la o frecevnta de ceas de 24MHz, teoretic frecventa maxima pentru semnalul DCLOCK ar trebui sa fie de 1MHz, dar va trebui sa tinem cont de alte cateva "amanunte", si anume:
Intarzierea datorata procesului de servire a intreruperilor, care in acest care este de minimum 7 ms.
De intarzierea datorata executiei instructiunilor rutinei de servire a intreruperilor
De intarzierile (care pot fi aleatorii) datorate proceselor de schimb de informatie concurente procesului de achizitie, cum ar fi procesul de transfer serial al datelor catre sistemul ierarhic superior, alte procese ce
La finalul vom specifica cum se
calculeaza frecventa maxima de ceas corespunzatoare
achizitiei de semnal.
Proiectarea programelor in cazul astfel specificat, implica:
Initializarea de sistem, ceea ce presupune:
resetarea memoriei sistemului,
setarea valorilor corespunzatoare frecventei de achizitie,
Scrierea rutinelor de servire a intreruperilor
implementarea transferului semnalului de ceas catre convertorul A/D
implementarea achizitiei datelor de la convertor
implementarea buffer-elor de intrare/iesire
implementarea transferului serial al datelor, la frecventa si in conditiile dorite.
Scrierea programului principal, care are ca principal rol, rolul de a astepta producerea unor evenimente.
In acest sens,
in figura 15 dam structura principalelor fluxuri de informatie in
cadrul sistemului propus.
Dam in continuare programul ce implementeaza aplicatia.
;Rutina de servire a intreruperilor corespunzatoare achizitiei de semnal
;Realizeaza achizitia unei date in cadrul ei, necesita urmatoarele locatii:
CT_H EQU 11H
CT_L EQU 00H
SET_UART EQU 5CH ;Setarea parametrilor interfetei seriale
SET_TIMER EQU 21H
;Setarea modului de functionare pentru timer-ele microcontroller-ului
SET_T1 EQU 0FDH ;Setarea constantei de timp pentru rata de transfer a UART
DSEG
ORG 24H
STATUS DATA 00H
CONTOR DATA 00H
;locatie ce retine numarul de pasi in achizitie
DATA_REC DATA 00H
;locatie ce retine comanda venita de la sistemul ierarhic superior
DATA_LSB DATA 00H ;Locatie byte mai putin semnificativ
DATA_MSB DATA 00H ;Locatie byte mai semnificativ
BSEG
TRS_MSB BIT 10H
;Specifica necesitatea transferului celui mai semnificativ byte al datei achizitionate
REC_EN BIT 11H
;Specifica receptia completa a unui caracter, caz in care programul principal il va analiza
;generand ecourile specifice comenzii primite
;Rutina de servire a intreruperilor corespunzatoare canalului 0 temporizator
;In cadrul programului principal se vor seta:
;rata de esantionare prin setarea constantei de timp
;modul de achizitie: 1.un singur punct / 2. puncte multiple
CSEG
ORG 0H
JMP MAIN
ORG 0BH
ISR_T0:
PUSH PSW ;Salvez contextul respectiv registrii PSW si ACC (24)
PUSH ACC (24)
SETB PSW.3 ;Schimb bancul tinta de registrii generali cu bancul1 (12)
MOV TH0,#CT_H (12)
MOV TL0,#CT_L (12)
;Reincarca constantele de timp si redeclaseaza temporizarea corespunzatoare
CLR IE.1 ;Reseteaza flag-ul de intrerupere corespunzator canalului 0 (12)
SETB P1.5 (12)
CLR P1.5 ;Activeaza CS# pentru accesul la convertor (12)
CLR P1.4 ;Reseteaza DCLOCK pentru 1 ms:Formeaza DCLOCK =0 (12)
SETB P1.5 ;Formeaza DCLOCK =1 (12)
CLR P1.5 ;Formeaza DCLOCK =0 (12)
;S-a incheiat perioada de esantionare pentru convertor. Urmeaza citirea datelor
;Aceasta presupune urmatoarele: DCLOCK=1, Incrementeaza contor,DCLOCK=0, Citeste data,
;Numarul de cicluri este de 13 avand in vedere ca prima valoare citita de la CAD este 0
MOV R0,#8 ;Initializez contor (12)
MOV A,#00H ;Resetez ACC (12)
LOOP_MSB: TIMP SCURS: 180/12= mS
SETB P1.4 ;Formeaza DCLOCK =1 (12)
CLR P1.4 ;Formeaza DCLOCK =0 (12)
JNB P1.7,CLR_BIT8 (24)
SETB ACC.0 (12)
CLR_BIT8:
RL A (12)
DJNZ R0,LOOP_MSB (24)
MOV DATA_MSB,A ;Salvez bitii 4 la 12 achizitionati (12)
MOV R0,#4 ;Initializez contor (12)
MOV A,#00H ;Resetez ACC (12)
TIMP SCURS: 180/12= mS
LOOP_LSB:
SETB P1.4 ;Formeaza DCLOCK =1 (12)
CLR P1.4 ;Formeaza DCLOCK =0 (12)
JNB P1.7,CLR_BIT0 (24)
SETB ACC.0
CLR_BIT0:
RL A (12)
DJNZ R0,LOOP_LSB (24)
MOV DATA_MSB,A ;Salvez bitii 0 la 3 in DATA_LSB (12)
;Am achizitionat toti cei 12 biti oferiti de ADS7822
TIMP SCURS: 180/12=14,5mS
SETB P1.5 ;Inactivez CS# (12)
;Formez rezultatul conversiei
MOV A,DATA_MSB (12)
SWAP A (12)
PUSH ACC (24)
ANL A,#0F0H ;Maschez LSB=bitii 4-7 ai LSB (12)
ORL A,DATA_LSB (12)
MOV DATA_LSB,A ;Formez primii 8 biti ai datei convertite (12)
POP ACC (24)
ANL A,#0FH ;Maschez cel mai seminificativ semibyte (12)
MOV DATA_MSB,A ;Formez urmatorii 4 biti -cei mai semnificativi (12)
POP PSW ;Refac starea PSW dinaintea intrarii in intreruperi (24)
POP ACC ;Refac starea ACC dinaintea intrarii in intreruperi (24)
RETI (24)
TIMP SCURS: 180/12=8,5mS
TIMPUL TOTAL CORESPUNZATOR ISR: 66,5mS
;Rutina de servire a intreruperilor corespunzatoare UART
;Sistemul va transmite date doar la cererea sistemului ierarhic superior si
;numai maximum doi bytes
ORG 23H
ISR_SI:
JB RI,REC ;Testare daca a fost receptionat un caracter (24)
TRS: ;NU! Intrerupere la transmisie
CLR TI (12)
JNB TRS_MSB,END_TRS ;Test daca mai sunt de transmis date (24)
MOV SBUF,DATA_MSB ;Transfer MSB data achizitionata (12)
CLR TRS_MSB (12)
END_TRS:
RETI (24)
REC:
CLR RI (12)
MOV DATA_REC,SBUF ;Scriu data in buffer-ul de receptie (12)
SETB REC_EN ;Specific receptia unui caracter (12)
RETI (24)
MAIN:
CALL INIT ;Rutina de initializarea a sistemului
LOOP:
JNB REC_EN,LOOP
ANALIZA:
MOV A,#'A' ;Incarca primul caracter utilizat drept comanda
CJNE A,DATA_REC,CONTINUE0
CALL INIT_ACHIZITIE
JMP LOOP
CONTINUE0:
;Aici pot fi inserate celelate teste pentru comenzile pe care le instituim prin protocol
NOP
INIT_ACHIZITIE:
;Rutina de initiere a achizitiei datelor trebuie sa valideze intreruperile
;corespunzatoare canalului 0 si sa incarce constanta de timp corespunzatoare
;ratei de esantionare
MOV TH0,#CT_H
MOV TL0,#CT_L
SETB TR0
SETB T0
RET
INIT:
;Rutina de initiere de sistem. Nu mai detaliem aspectele legate de initializarea memoriei
MOV IE,#90H ;Initializez intreruperile corespunzatoare UART
MOV PSW,#0 ;Initializez PSW
MOV SCON,#SET_UART ;Initializez UART
MOV TMOD,#SET_TIMER ;Setez modurile de functionare ale timer-elor
MOV TL1,#0
MOV TH1,#SET_T1 ;Setez constantele de timp
RET
END
Sa observam ca daca calculam timpul de executie corespunzator instructiunilor rutinei de servire a intreruperilor la achizitia datelor in cazul unei frecvente de ceas de 24 MHz obtinem o durata de 66,5 ms, adica frecventa maxima de achizitie este de: 15.037 Hz. Putem constata ca si in situatia in care am utilizat facilitatile hard de sincronizare, respectiv sistemul de intreruperi totusi viteza de achizitie este puternic legata de modul de implementare prin program a acesteia, deci acest aspect va trebui cu cea mai mare grija analizat si proiectat.
Observam ca daca am fi
utilizat facilitatea interfetei UART a microcontroller-ului (vezi modul 0
de functionare) am fi putut creste frecventa maxima de
achizitie aproape de limita superioara corespunzatoare convertorului
analog-digital. In acest caz, observam ca ar fi fost necesar sa
receptionam sincron doi octeti, ceea ce ar fi dus la consumarea
unui timp de aproximativ 16 ciclii de ceas, adica la 24 MHz timpul de
achizitie ar fi fost de 8ms, ceea ce corespunde unei
rate de esantionare de 125000Hz. Evident, in acest caz am fi renuntat
la utilizarea UART drept port de legatura cu sistemul ierarhic
superior.
In acest scop vom utiliza convertorul ADS7821 convertor cu registru de aproximatii succesive de 16 biti. Cateva date tehnice importante: frecventa maxima 100 kHz, domeniul tensiunilor de intrare: 0 la 5 V, poate utiliza atat o referinta de tensiune interna, cat si una externa, poate fi conectat direct la un bus de sistem.
Schema bloc a sa este
prezentata in figura
Pentru a-l putea conecta, este necesar sa cunoastem care este modul de functionare al convertorului. Astfel, semnalul Read/Convert (R/C#) asigura citirea rezultatului sau declansarea conversiei, semnalul CS# permite trecerea bus-ului din starea High Impedance intr-una din starile 1 sau 0 logic, semnalul BYTE permuta magistralele low/high de iesire, iar linia BUSY# semnaleaza situatia in care convertorul se gaseste in faza de esantionare si conversie a semnalului analogic.
Pentru a realiza conversia de semnal va trebui sa cunoastem care este succesiunea de semnale de comanda. Combinatiile posibile sunt prezentate in figura
Astfel aplicand simultan un 0 logic pe liniile CS# si R/C# si mentinand cel putin 40 ns linia R/C# in zero logic realizam esantionarea si conversia semnalului analogic. Semnalul BUSY va sta in zero logic din momentul initierii conversiei si pana la momentul la care aceasta s-a incheiat. Convertorul il va aduce automat pe 1 logic, moment la care valoarea numerica corespunzatoare semnalului de intrare va fi valida pe iesirea convertorului.
Linia BYTE va
permuta bitii inferiori si superiori ai rezultatului. Astfel
daca BYTE=0, pinii de iesire ai convertorului de la 6 la 13 vor
scoate semi-byte-ul mai semnificativ, pentru ca daca BYTE = 1,
aceiasi pini sa retina cei mai putini 8 biti ai
rezultatului conversiei.
Strategia urmata va consta in:
declansarea
conversiei prin resetarea liniilor CS#
si R/C#
trecerea dupa mai mult de 40 ns a semnalului R/C#in 1 logic
citirea rezultatului atunci cand linia BUSY# va trece in 1 logic.
Pentru implementarea achizitiei vom putea folosi atat unul cat si celalalt dintre controller-e.
Sa analizam avantajele si dezavantajele acestor implementari.
Structura schemei electrice este gandita pentru procesorul AT89C2051, in urma analizei resurselor pe care acesta le poseda, precum si a necesitatilor datorate convertorului analog-digital ADS7821.
Legand liniile CS#, R/C# si BYTE la portul 3 al microcontroller-ului nu afectam functionalitatea acestuia caci cele doua canale temporizatoare le vom folosi, unul pentru generarea ratei de esantionare a semnalului analogic, iar celalalt drept generator al frecventei de ceas pe linia seriala de date a UART.
Liniile portului P1 sunt direct conectate la liniile 6 la 13 ale convertorului.
Esalonarea in timp a evolutiei semnalelor este data in figura urmatoare
respectiv comutarea celor doua bus-uri -inferior (low), respectiv superior (high), este realizata de catre semnalul BYTE. Vezi figura
Pentru achizitia datelor va trebui sa alocam resursele disponibile ale microcontroller-ului astfel:
vom scrie rutina de servire a intreruperilor corespunzatoare semnalului BUSY, astfel ca pe frontul pozitiv al acestuia sa se declanseze rutina de servire. (vezi declansarea se face pe frontul descrescator, iar starea de interes la achizitie este starea corespunzatoare frontului crescator, deci am introdus inversorul).
vom scrie rutina de start al conversiei A/D -rutina de servire corespunzatoare intreruperilor timer overflow de la canalul 0.
vom scrie rutina de servire a intreruperilor corespunzatoare UART
vom proiecta rutina de initializare
vom scrie programul principal de functionare ce cuprinde rutina de analiza a informatiilor vehiculate prin UART
Programul ce implementeaza aceasta aplicatie a considerat urmatorul protocol:
Caracterul "A" reprezinta comanda de achizitie neconditionata a datei
Caracterul "C" reprezinta comanda de achizitie continua cu o rata fixa de esantionare, aprioric stabilita prin constantele de timp CT_L si CT_H a datelor
Caracterul "D" reprezinta comanda de transfer a datei achizitionate via interfata UART.
Dam in continuare programul:
CT_L EQU 00H
CT_H EQU 80H
CT_SMOD EQU 21H ;
CT_ST EQU 55H ;
CT_SSCON EQU 5CH ;
;Valori pentru constanta de timp necesara la declansarea conversiei semnalului analogic
DSEG
BSEG
RX BIT 10H ;Specifica receptia unui caracter
TX BIT 11H ;Specifica necesitatea transferului DATA_LSB
DE BIT 12H ;Specifica existenta unei date achizitionate
DATA_UART DATA 30H ;Locatie data receptionata pe UART
DATA_LSB DATA 31H ;Locatie LSB data achizitionata
DATA_MSB DATA 32H ;Locatie MSB data achizitionata
CSEG
;ISR_EXT0 Rutina de servire a intreruperilor corespunzatoare achizitiei de la CAD
ORG 0H
JMP MAIN
JMP ISR_EXT0
ORG 0BH
JMP ISR_T0
ORG 23H
JMP ISR_SI
ISR_EXT0:
PUSH PSW ;Salveaza starea UC
SETB PSW.3
;Seteaza bancul 1 de regsitrii generali, ca registrii 'tinta'
MOV DATA_MSB,P1 ;Salveaza partea mai semnificativa a datei
SETB P3.7 ;Comanda switch-area bytes: LSB <->MSB
MOV DATA_LSB,P1 ;Salveaza partea mai putin semnificativa a datei
SETB DE
POP PSW ;Reface starea UC
RETI ;Iese din ISR
;ISR_T0 Rutina de servire a intreruperilor corespunzatoare frecventei de esantionare
ISR_T0:
PUSH ACC ;Salveaza acumulatorul ;
MOV A,P3
ANL A,#0E7H
MOV P3,A ;Genereaza simultan CS#=0 si R/C#=0 ;
POP ACC ;Reface acumulatorul
SETB P3.5 ;Pregatim citirea datei coresp.valorii analogice
MOV TL0,#CT_L
MOV TH0,#CT_H ;Scriu valorile de temporizare
RETI ;Iese din ISR
;ISR_SI Rutina de servire a intreruperilor corespunzatoare UART
ISR_SI:
JB RI,RECEPTIE ;Testare intrerupere la receptie
;NU! Intrerupere la transmisie
TRANSMISIE:
CLR TI ;Sterg flag pentrua reanclasa intreruperea
JB TX,SCRIE ;Test daca trebuie sa transmit si LSB
;NU!
RETI ;Iesire din ISR
SCRIE:
MOV SBUF,DATA_LSB ;Scriu LSB
CLR TX ;Sterg flag atentionare transfer via UART a LSB
RETI ;Iesire din ISR
RECEPTIE:
CLR RI ;Sterg flag receptie data pe UART
MOV DATA_UART,SBUF ;Citesc data receptionata pe linia seriala
SETB RX ;Semnalez receptia si citirea datei
RETI
;Programul principal de functionare a sistemului
MAIN:
CALL INIT
LOOP:
MOV A,DATA_UART
CJNE A,'A',TEST1
;Comanda SOC ('Start Of Conversion')
MOV A,P3
ANL A,#0E7H
MOV P3,A ;Genereaza simultan CS#=0 si R/C#=0 ;
SETB P3.5
TEST1:
CJNE A,'C',TEST2
MOV A,P3
ANL A,#0E7H
MOV P3,A ;Genereaza simultan CS#=0 si R/C#=0 ;
POP ACC ;Reface acumulatorul
SETB P3.5 ;Pregatim citirea datei coresp.valorii analogice
MOV TL0,#CT_L
MOV TH0,#CT_H ;Scriu valorile de temporizare
SETB TR0 ;Validez impulsurile catre temporizator -canalul 0-
SETB IE.1 ;Validarea intreruperilor 'timer 0 overflow'
TEST2:
CJNE A,'D',FINAL
SETB DE
FINAL:
JNB DE,LOOP
INIT_TRS:
JB TI,INIT_TRS
MOV SBUF,DATA_MSB
SETB TX
CLR DE
JMP LOOP
INIT:
MOV R0,7FH
LP:
MOV @R0,#0H
DJNZ R0,LP
;Reseteaza memoria interna a controller-ului
MOV SP,#60H
MOV TMOD,#CT_SMOD
MOV TCON,#CT_ST
MOV SCON,#CT_SSCON
MOV IE,#91H
MOV P3,#0FFH
RET
END
Locatarea variabilelor si a registrilor utilizati de catre aplicatie este data in continuare:
N A M E T Y P E V A L U E ATTRIBUTES
ACC. . . . D ADDR 00E0H A
CT_H . . . N NUMB 0080H A
CT_L . . . N NUMB 0000H A
DATA_LSB . D ADDR 0031H A
DATA_MSB . D ADDR 0032H A
DATA_UART. D ADDR 0030H A
DE . . . . B ADDR 0022H.2 A
FINAL. . . C ADDR 008DH A
IE . . . . D ADDR 00A8H A
INIT . . . C ADDR 009CH A
INIT_TRS . C ADDR 0090H A
ISR_EXT0 . C ADDR 0026H A
ISR_SI . . C ADDR 004AH A
ISR_T0 . . C ADDR 0037H A
LOOP . . . C ADDR 0064H A
LP . . . . C ADDR 009EH A
MAIN . . . C ADDR 0061H A
P1 . . . . D ADDR 0090H A
P3 . . . . D ADDR 00B0H A
PSW. . . . D ADDR 00D0H A
RECEPTIE . C ADDR 0059H A
RI . . . . B ADDR 0098H.0 A
RX . . . . B ADDR 0022H.0 A
SBUF . . . D ADDR 0099H A
SCON . . . D ADDR 0098H A
SCRIE. . . C ADDR 0053H A
SP . . . . D ADDR 0081H A
TCON . . . D ADDR 0088H A
TEST1. . . C ADDR 0071H A
TEST2. . . C ADDR 0088H A
TH0. . . . D ADDR 008CH A
TI . . . . B ADDR 0098H.1 A
TL0. . . . D ADDR 008AH A
TMOD . . . D ADDR 0089H A
TR0. . . . B ADDR 0088H.4 A
TRANSMISIE C ADDR 004DH A
TX . . . . B ADDR 0022H.1 A
Convertoarele analog - digitale complexe
Sistemele de achizitie ce cuprind convertoare analog-digitale complexe sunt utilizate in aplicatii cum ar fi achizitia semnalelor in tensometrie, in domeniul medical, in domeniile ce necesita frecvente de esantionare relativ reduse (cativa KHz) si rezolutii ridicate (16 la 24 de biti).
Dintre realizarile tehnologice actuale ne vom opri asupra circuitului ADS1211, cap de serie al convertoarelor de inalta rezolutie al firmei Burr-Brown/Texas Instruments.
Structura
acestuia este prezentata in figura ..
Circuitul ADS1210/1211 este un convertor analog-digital cu un domeniul de intrare deosebit de larg. Ofera o rezosutie de 24 de biti, cu facilitatea de autocalibrare si de multiplexare interna diferentiala pentru 4 canale distincte in cazul ADS1211. Circuitul poseda un amplificator cu amplificare programabila digital, un modulator sigma-delta de ordinul 2, un filtru digital programabil care include un microcontroller ce dispune de reistrii de instructiuni, comenzi, precum si de registrii de date, offset si calibrare la capat de scala. Referinta de tensiune este interna si setabila digital cu valori de pana la 2,5V. Functionarea detaliata a convertorului este prezentata in foaia sa de catalog. (www.burr-brown.com) unde sunt detaliate si modurile sale de functionare. Doua sunt tipice: master mode (MODE=1) -caz in care convertorul are initiativa transferului datelor achizitionate imediat dupa faza de initializare si slave-mode, (MODE=0)caz in care initiativa si frecevnta de ceas sunt oferite de catre controller-ul magistralei de conexiune.
In figura dam diagrama de timp pentru cazul in care circuitul este conectat ca element slave (pinul MODE este plasat pe 0 logic) pe bus.
Schema de
conectare aleasa permite realizarea tuturor modurilor de functionare
pentru convertor, respectiv atat a modului 'slave' cat si a
modului 'master'. De asemenea prin controlul liniei CS# este
posibila inserarea mai multor convertoare pe acelasi bus si
adresarea acestora. In figura este
prezentata aceasta
schema.
Pentru a putea scrie programele de initializare si cele de achizitie este necesar sa cunoastem structura registrilor interni ai convertorului.
Registrul de instructiuni are structura:
INSTR
R/W# |
MB1 |
MB0 |
A3 |
A2 |
A1 |
A0 |
Bitul R/W# specifica tipul operatiei: de citire/scriere respectiv 1/0 logic.
Bitii MB1 si MB2 codifica numarul de octeti de comanda pe care circuitul ii va receptiona, via interfata seriala: combinatia 00 corespunde unui octet, 01 la doi octeti, 10 la 3 octeti si 11 la 4 octeti transmisi succesiv.
Bitii A3,A2,A1,A0 adreseaza registrii interni ai convertorului, conform tabelului urmator.
Circuitul este astfel conceput incat dupa fiecare sesiune de scriere adreseaza implicit, din nou, regsitrul de instructiuni.
Odata declasata, spre exemplu achizitia datelor, acestea vor fi emise autonom, functie de setarile stabilite.
Registrii de comenzi permit setarea parametrilor de achizitie pentru convertorul analog-digital. Intre acestia amintim: rata de esantionare in concordanta cu frecventa de decimare si castigul obtinute pe convertor, canalul selectat, formatul datelor, sursa pentru tensiunea de referinta si modul de achizitie: unipolar sau bipolar, ordinea de emisie a datelor incepand cu LSB (Last Signifiant Bit) sau cu MSB (Most Signifiant Bit). De asemenea, este posibila setarea modului de functionare, conform tabelului urmator.
Structura cuvintelor corespunzatoare registrului de comenzi este data in schemele urmatoare.
Byte 3 (MSB)
BIAS |
REF |
DF |
U/B# |
BD |
MSB |
SDL |
DRDY/ DSYNC# |
O = Off |
1 = On |
1 =comp 2 |
Bipolar |
0= MSB |
0=MSB |
0=SDIO |
Valorile trecute pe a doua linie sunt cele implicite. Pnetru valoarea 0 a bitului BIAS, tensiunea de referinta este de 2,5V, iar pentru valoarea 1 ea este 1,33*2,5V adica aproximativ 3,3V.
Un 1 logic pe bitul REF asigura utilizarea sursei interne de referinta, iar 0 aduce in starea de mare impedanta aceasta sursa, permitand utilizarea unei surse de referinta externe.
DF exprima formatul datelor, 0 implica formatul datelor in complement fata de doi +FSR=7FFFFFH, 0=000000H, iar -FSR=800000H (FSR este abrevierea scalei complete 'Full Scale Range').
U/B# exprima cand este 0 achizitia bipolara a datelor, iar cand este 1 exprima achizitia unipolara a acestora.
BD exprima ordinea de transfer a bytes, setand bitul ordinea este crescatoare de la LSB catre MSB si invers daca-l resetam.
MSB exprima cine este primul bit emis in cadrul fiecarui byte, 1 implica transferul intai al bitului cel mai nesemnificativ, iar 0 implica transferul intai al bitului cel mai semnificativ.
SDL comanda utilizarea a unei linii bidirectionale seriale (SDIO) daca este resetat, respectiv a doua linii seriale daca este setat (SDIO pentru comenzi si SOUOT pentru date)
DRDY# exprima resetat prezenta datelor (Data Ready), iar setat exprima date invalide.
Byte 2
MD2 |
MD1 |
MD0 |
G2 |
G1 |
G0 |
CH1 |
CH0 |
Acest byte seteaza, modurile de functionare, codate binar de la 0 la 7, valorile castigului si selecteaza canalul de intrare pentru achizitia de semnal.
Modurile de functionare codate binar sunt in ordine, incepand de la 000H urmatoarele:
normal,
'self calibration' calibrare automata,
calilbrare de offset,
calibrare la capat de scala,
'pseudo-calibrare',
calibrare in fundal 'background calibration',
'sleep' si
rezervat -neutilizat.
Prin pseudo-calibrare intelegem posibilitatea de a
Byte 1
SF2 |
SF1 |
SF0 |
DR12 |
DR11 |
DR10 |
DR9 |
DR8 |
SF2, SF1, SF0 selecteaza una dintre valorile modului turbo de functioare a circuitului, iar valorile DR12 la DR0 seteaza frecventa de decimare pentru filtrul digital al convertorului.
Byte 0
DR7 |
DR6 |
DR5 |
DR4 |
DR3 |
DR2 |
DR1 |
DR0 |
In modul de conectare din fugura convertorul poate fi controlat dinamic, respectiv poae lucra in modul de citire continua, admitand in acelasi timp comenzi prin intermediul liniei SDIO si generand date via linia SDOUT.
Implementarea unui ciclu descriere a comanzilor in modul slave presupune indeplinirea urmatorilor pasi:
Asteapta ca ADS1211 sa plaseze DRDY# pe zero logic
Asteapta ca CS# sa treaca la randul sau in zero logic
Genereaza 8 cicluri de ceas pentru a trece in instruction register data de configurare via SDIO
Genereaza n ciclii de ceas de transmisie pentru inscrierea registrilor tinta ai comenzilor (vezi documentatia la ADS1210 ads1210.pdf de la Burr-Brown)
Ads1210 pune pe 1 logic DRDY
Repeta pasii 3 la 5 pana la transmiterea tuturor cuvintelor de comanda catre ADS1210, dupa care intra in ciclul/ciclurile de citire a datelor, ceea ce presupune:
Asteapta ca ADS1211 sa plaseze DRDY# pe zero logic
Asteapta ca CS# sa treaca la randul sau in zero logic
Daca este in modul citire continua (Continous Read), trece la pasul 5
Microcontroller-ul genereaza 8 ciclii de ceas si transfera cuvantul de control in registrul de instructiuni via SDIO
Daca utilizam SDIO drept linie bidirectionala vom urmarii evolutia acesteia in continuare, daca nu atunci linia SDIO trece in starea de mare impedanta
Microcontroller-ul emite n ciclii de ceas (n multiplu de 8) si transmite/receptioneaza informatia din registrul specificat prin instructiunea de la punctul 4. Receptia acestor biti se face pe linia SDOUT sau SDIO dupa caz.
SDOUT sau SDIO intra in starea de mare impedanta, dupa ce a transmis informatia comandata
Testare daca mai sunt de transmis alte comenzi sau cereri de date. Daca da se reia ciclul de la punctul 2. CS# ramane inactiv 10,5 ciclii de ceas.
Programul de mai jos prezinta cateva rutine, ca de transfer a unui cuvant de comanda, precum si cea de citire a unei date formata din trei octeti. Programarea microcontroller-ului va fi specifica pentru fiecare aplicatie in parte, ea trebuind sa realizeze adaptarea parametrilor convertorului in raport cu rezolutia si rata de esantionare impuse de aplicatie.
Programul de
functionare permite
Sincronizarea transferului comenzilor catre CAD;
Generarea soft si emiterea semnalului de ceas (SCLK), catre CAD
Transferul informatiilor de initializare si a comenzilor catre CAD
Receptia datelor corespunzatoare semnalului analogic convertit
Iata acest program:
ORG 28H
PROG: DB 01100100B ;Cuvant de instructiuni
DB 01000010B ;Cuvant de C-da nr. 3
DB 00000000B ;Cuvant de C-da nr. 2
DB 00000000B ;Cuvant de C-da nr. 1
DB 00000000B ;Cuvant de C-da nr. 0
;Cuvantul de instructiuni asigura scrierea cuvintelor de comanda 3, 2, 1 si 0
DB 11000000
;Cuvantul asigura citirea celor 3 registrii corespunzatori valorii semnalului analogic convertit
BUFFER: DS 03H
CAD: JB P1.0,CAD
;Testeaza starea CAD, respectiv DRDY#=0
MOV R1,#04H
MOV R0,#PROG
;Pregateste transmiterea a 5 octeti catre CAD, ce sunt: cuvantul de instructiuni si cele 4 cuvinte
;de comanda. Cuvintele sunt memorate incepand de la adresa PROG
LOOP_1: MOV A,@R0
CALL SERIAL_OUT
INC R0
DJNZ R1,LOOP_1
CAD1: JB P1.0,CAD1
;Testeaza starea CAD, respectiv DRDY#=0
MOV A,@R0
CALL SERIAL_OUT
LOOP_2: JB P1.0,LOOP_2
;Asteapta conversia datelor de catre CAD, semnalul DRDY# va fi resetat
MOV R1,#03H
MOV R0,#BUFFER
;Pregateste citirea celor 3 bytes de date, corespunzatori semnalului analogic convertit
LOOP_3:
CALL SERIAL_IN
MOV @R0,A
INC R0
DJNZ R1,LOOP_3
;Incheie un ciclu complet Initializare comanda si achizitie data convertita
SERIAL_OUT: CLR P1.3
MOV R7,#08H
RL A
RL A
LOOP_OUT:
JB ACC.2,SET_OUT
CLR P1.2
JMP CLOCK_OUT
SET_OUT: SETB P1.2
CLOCK_OUT: SETB P1.3
CRL P1.3
;Genereaza semnalul SCLK
RL A
DJNZ R7,LOOP_OUT
;Transfera un octet catre CAD
RET
SERIAL_IN: CLR P1.3
MOV R7,#08H
LOOP_IN:
JB P1.1,SET_IN
CLR ACC.0
JMP CLOCK_IN
SET_IN: SETB ACC.0
CLOCK_IN: SETB P1.3
CRL P1.3
RL A
DJNZ R7,LOOP_IN
;Recepteaza un octet de la CAD
RET
Convertoarele digital - analoge controlabile serial
Aplicatia pe care o vom descrie in continuare se refera la comanda unui convertor digital - analog cu intrare seriala, cum ar fi cele utilizate in cadrul aparaturii audio de inalta performanta. Vom exemplifica aceasta prin circuitul PCM56 convertor digital-analog de 16 biti. Structura convertorului este data in figura de mai jos.
Cateva dintre caracteristicile convertorului sunt: domeniul dinamic de peste 96 dB FSR, nu necesita componente externe, 16 biti rezolutie, eroare liniara sub 0,001%, timp de stabilire 1,5 ms, opereaza cu tensiuni intre 5V si 12V.
LE 'Latch Enable', lacatuieste informatia serial receptata si o aplica convertorului la momentul validarii lacatuirii.
Data este
intrarea de 'Date', ce sunt transmise in format complement
fata de 2, sincron cu semnalul de ceas 'Clock'.
Amanunte privind fronturile si sincronizarea datelor si
timming-ul corespunzator transferului unei date sunt prezentate in
figura . Se constata ca datele
sunt transmise incepand cu cel mai semnificativ octet, frontul negativ realizeaza
deplasarea acestora la dreapta bit de bit. Frontul pozitiv reprezinta
frontul pe care data este memorata in registrul de deplasare aflat pe
intrarea convertorului digital-analog PCM56. Intrarea LE trebuie sa stea
pe 1 logic cel putin un ciclu de ceas, ea plasandu-se pe durata
transferului serial al datelor pe 0 logic. La sfarsitul transferului ea va
fi trecuta in 1 logic pentru cel putin 1,5 perioade de ceas.
Utilizand microcontroller-ul AT89C2051 vom conecta liniile P1.7 la linia Clock, P1.6 la linia Date, iar P1.5 la linia LE. Dam mai jos rutina care realizeaza comanda convertorului.
CT_TMOD EQU 21H
;Setare mod functionare canale temporizatoare
; canalul 0 utilizat pentru rata de esantionare in comanda folosit in modul 1
; canalul 1 utilizat pentru rata de transfer seriala a informatiilor folosit in modul 2
CT_TCON EQU 50H
;Setez flag-urile de dezinhibare a numararii pentru canalele 0 & 1
CT_SCON EQU 90H
;Setez modul 1 de transfer serial UART 8 biti pilotat cu rata variabila de catre canalul 1 temporizator
CT_LOW0 EQU 00H
CT_HIGH0 EQU 00H
CT_LOW1 EQU 0FDH ;Constanta de timp corespunzatoare ratei de 9600 Baud la fceas=11,059MHz
LEN_BUFFER EQU 20H ;Lungime prestabilita a blocului de date de transferat
;CONTOR_B este mai mic sau egal cu LEN_BUFFER
BSEG
REC BIT 0H ;Flag setat exprima receptia completa a unui caracter via UART
RANG_DATA BIT 1H ;Flag ce exprima byte-ul care este transferat catre CDA
DSEG
DATA_CDA: DS LEN_BUFFER
;Buffer bloc date (cazul trasnferului catre CDA a unui bloc de date la frecventa presetata
DATA_LOW DATA 00H ;LSB corespunzator datei de convertit D/A
DATA_HIGH DATA 00H ;MSB corespunzator datei de convertit D/A
;Locatii corespunzatoare datei transferate catre CDA in modul transfer cuvant (16 biti / 2 bytes)
DATA_SI DATA 00H ;Buffer de receptie a datelor (comenzi) via UART
CONTOR_B DATA 00H ;Marime bloc de date de transferat catre CDA
POINTER_D SET DATA_CDA
CSEG
ORG 000H
BOOT:
JMP MAIN
ORG 0BH
ISRT0:
JMP ISR_T0
ORG 23H
ISRSI:
JMP ISR_SI
;Rutina corespunde transferului unui cuvant catre CDA
ISR_T0:
PUSH PSW
PUSH ACC
;Salvez starea microcontroller-ului
SETB PSW.3 ;Utilizez bancul 1 de registrii generali
CLR P1.5
;Invalidez LE, => Posibilitate de scriere in buffer-ul de serializare al CDA
MOV R7,08H
;Incarc contor al bitilor de serializat corespunzator MSB
MOV A,DATA_HIGH ;Incarc MSB
LOOP_CDA1:
RL A ;Rotesc informatia din Acumulator
CLR P1.7 ;Reset semnal Clock catre CDA
JB ACC.0,SET_BIT_CDA
CLR P1.6 ;Reset DATA catre CDA
CLK_CDA:
SETB P1.7 ;Set semnal Clock catre CDA
DJNZ R7,LOOP_CDA1
JMP CONT
SET_BIT_CDA:
SETB P1.6 ;Set DATA catre CDA
JMP CLK_CDA
;Am transmis MSB catre CDA, urmeaza LSB
CONT:
MOV R7,08H
MOV A,DATA_LOW
LOOP_CDA2:
RL A
CLR P1.7 ;Reset semnal Clock catre CDA
JB ACC.0,SET_BIT_CDA1
CLR P1.6 ;Reset DATA catre CDA
CLK_CDA1:
SETB P1.7 ;Set semnal Clock catre CDA
DJNZ R7,LOOP_CDA1
SETB P1.5
;Lacatuiesc informatia transferata serial in buffer-ul de iesire al CDA
CLR P1.5
;Revalidez accesul la buffer-ul de intrare (serial) al CDA
POP ACC
POP PSW ;Refac starea UC dinaintea intreruperii de timp
RETI
SET_BIT_CDA1:
SETB P1.6 ;Set DATA catre CDA
JMP CLK_CDA1
ISR_SI:
JB RI,RECEPTIE
TRANSMITE:
CLR TI
RETI
RECEPTIE:
MOV DATA_SI,SBUF
CLR RI
SETB REC
RETI
MAIN:
MOV R0,#7FH
LP:
MOV @R0,#00H
DJNZ R0,LP
;Scriu 0 in toate locatiile corespunzatoare memoriei interne a controller-ului
MOV SP,70H
;Setez adresa pentru stiva sistemului
CALL INIT
;Realizez initializarile canalelor temporizatoare si a interfetei seriale
MOV IE,#92H
;Validez intreruperile corespunzatoare canalului 0 temporizator si UART
LOOP:
;Se va particulariza programul functie de protocolul dorit si functie de particularitatile sistemului
JNB REC,LOOP
;Testare caracter receptionat si comanda corespunzatoare codului asignat
CLR REC ;Reanclasare analiza a unui eventual nou caracter receptionat via UART
JMP LOOP
INIT:
MOV TMOD,CT_TMOD
MOV TCON,CT_TCON
MOV TL0,#CT_LOW0
MOV TH0,#CT_HIGH0
MOV TL1,#CT_LOW1
SETB 0D7H ;Dublez rata de transfer serial a informatiilor =>PCON.7=SCON=1
RET
END
Prin temporizare se intelege masurarea unui interval de timp ca multiplu al frecventei de ceas a sistemului (microcontroller-ului). In acest caz impulsurile numarate de canalul respectiv provin de la ceasul de sistem, care in cazul circuitului AT89C2051 este divizat cu 12 si aplicat pe intrarea de numarare.
Numararea impulsurilor ce sunt aplicate pe o intrare accesibila din exterior (vezi pinii T0 sau T1). Aceste impulsuri pot proveni de la o sursa externa de semnal.
Formula este aproximativa caci ea nu tine cont de timpii necesari executiei instructiunilor din cadrul rutinei de servire a intreruperilor, timpi care de altfel pot fi diferiti, functie de starea in care este gasit procesorul la anclasarea intreruperii
Prin sistem de intreruperi vectorizat intelegem capacitatea dispozitivului respectiv de a realiza automat, la servirea unei intreruperi saltul la o adresa specifica sursei de intreruperi
Intrarile pot fi conectate intern ca intrari inversoare/neinversoare ale unui comparator analogic, iesirea acestuia fiind accesibila soft, ca bitul 6 al portului 3 al microcontroller-ului
Mod de functionare in care procesorul consuma putin caci reduce tensiunea de alimentare pe liniile porturilor si opreste executia instructiunilor. Accepta intreruperile ca modalitate de iesire din stare data
ICSP prescurtare a "In Circuit Serial Programming", este facilitatea prin care utilizand drept linii de conexiune liniile microcontroller-ului se poate realiza programarea memoriei flash a circuitului fara ajutorul unui programator specializat
Politica de confidentialitate |
.com | Copyright ©
2024 - Toate drepturile rezervate. Toate documentele au caracter informativ cu scop educational. |
Personaje din literatura |
Baltagul – caracterizarea personajelor |
Caracterizare Alexandru Lapusneanul |
Caracterizarea lui Gavilescu |
Caracterizarea personajelor negative din basmul |
Tehnica si mecanica |
Cuplaje - definitii. notatii. exemple. repere istorice. |
Actionare macara |
Reprezentarea si cotarea filetelor |
Geografie |
Turismul pe terra |
Vulcanii Și mediul |
Padurile pe terra si industrializarea lemnului |
Termeni si conditii |
Contact |
Creeaza si tu |