proiect software pentru electronica aplicata curs.pdf · prelucrare numerică a semnalului, la...
TRANSCRIPT
1
Proiect Software
pentru Electronica Aplicata
Notite de curs
As. Ing. Ciprian Dughir
2
Capitolul 1. Prezentarea microcontrollerului MSP430
1.1. Prezentare generală a arhitecturii microcontrollerului MSP430
Familia de microcontrolere MSP430 fabricarte de către firma americană Texas
Instruments incorporează o unitate centrală (CPU) tip RISC de 16 biţi, periferice specializate,
memorie internă de tip ROM şi RAM, toate interconectate intern prin intermediul unei
magistrale de adrese (MAB- Memory Address Bus) şi respectiv a unei magistrale de date
(MDB), folosind o arhitectură Von-Neumann cu memorie comună de program şi date.
Spaţiul maxim de memorie adresabil este de 64Kocteţi (bytes). Memoria de tip ROM
disponibilă on-chip (in variante mask-ROM, OTP sau FLASH) are dimensiuni cuprinse între
1Kocteti şi 160Kocteti, iar memoria de tip RAM dimensiuni de până la 116Kocteţi.
Fig. 2.1. Schema generală a unui microcontroller.
Microcontrolerele din familia MSP430 nu pot utiliza o memorie (de program sau date)
externă, deoarece nu există magistrale externe de adrese şi / sau date. Interfaţa cu o memorie
3
externă nu se poate face decat prin intermediul intrărilor / ieşirilor numerice (I/O) de uz
general.
Caracteristicile sale importante, ca sistem de calcul, sunt:
Unitate centrală (CPU) de 16 biti de tip RISC
Doar 27 de instrucţiuni de bază (core instructions) şi 7 moduri de adresare
Un număr de 16 registre de lucru, eliminând limitările unei arhitecturi
orientate pe acumulator
Optimizare pentru programare în limbaje evoluate (C)
Sistem de întreruperi vectorizat (cu vectori de întrerupere la adrese fixe)
Viteza maximă de lucru de 8, 16 sau 25MIPS (cu consumul propriu
dependent de viteză: 250-µA / MIPS )
Memoria de tip FLASH este programabilă in-system (ISP)
O schemă bloc a unui microcontroler MSP430 este prezentată în figura următoare.
Fig. 2.2. Diagrama bloc a microcontrollerului MSP430
În materie de periferice, MSP430 are o serie de resurse tipice pentru orice
microcontroler:
intrări / ieşiri numerice (I/O ports)
4
intrări / ieşiri seriale de tip USART si I2C
timere / numărătoare (Basic timer-16 biti, 8-bit timer)
Ca o particularitate, anumite variante au şi un controler pentru un sistem de afişare de
tip LCD (LCD driver), care permite comanda a pană la 160 de segmente LCD.
Altă particularitate, care se intalneşte numai la anumite variante, este existenţa unui
controler DMA (Direct Acces Memory - acces direct la memorie), care face posibilă
transferarea directă de date intre periferice şi memorie (RAM) fără intervenţia unităţii
centrale.
Pentru sporirea fiabilităţii aplicaţiilor care rulează pe un astfel de microcontrolere, în
afară de un timer de tip watch dog (WDT- Watch Dog Timer, ceas de gardă) există un sistem
de monitorizare a tensiunilor de alimentare (SVS- Supply Voltage Supervisor) şi, separat,
unul de monitorizare a oscilatoarelor utilizate pentru ceasul sistem şi al perifericelor (numai la
anumite variante). WDT trebuie resetat periodic de către codul aplicaţiei – în caz contrar
resetează controlerul, prin aceasta împiedicând “agăţarea” nedorită a programului. Un
controler bun oferă şi facilitatea de a diferenţia un Reset produs de punerea iniţială sub
tensiune de unul datorat WDT.
1.1.1 Sistemul de control şi administrare a alimentării
Sistemul SVS de monitorizare a tensiunilor de alimentare este integrat cu un sistem de
generare a semnalelor de initializare hardware-reset (System Reset and Initialization). Astfel
sunt generate diverse semnale de iniţializare: la punerea sub tensiune (POR – Power On
Reset, PUC – Power On Clear), la scăderea temporară a tensiunii de alimentare BOR (Brown
Out Reset). Acest modul (Brown-Out Detector) resetează controlerul dacă tensiunea de
alimentare a scăzut sub o anumită valoare, prestabilită (şi uneori programabilă) şi menţine
starea de Reset până la revenirea tensiunii de alimentare la vaoarea nominală. Se obţine
astfel o protecţie eficientă împotriva comportării cu erori la tensiuni reduse de alimentare
(inclusiv la funcţionarea defectoasă a memoriei EEPROM, cel mai puernic motiv pentru a
utiliza această facilitate). Există o serie de circuite externe care efectuează această funcţie.
1.1.2. Sistemul de întreruperi
Întreruperile reprezintă un concept fundamental pentru lumea computerelor. Deşi
execuţia unui program este în general liniară, anumite condiţii interne sau externe pot
determina execuţia unei rutine de întrerupere la încheierea căreia îşi reia operaţia curentă de
5
unde ea a fost întreruptă. O întrerupere permite controlerului să răspundă rapid la evenimente
fără ca acţiunea de verificare a apariţiei acestor evenimente să consume din timpul unităţii
centrale. O rutină de tratare a întreruperii trebuie să fie cât mai scurtă a nu introduce întârzieri
în execuţia codului şi a împiedica execuţia altor rutine de tratatre a celorlalte întreruperi. De
obicei cauza întreruperii este indicată prin setarea unui fanion (flag).
Rutina de tratare a întreruperii trebuie să salveze acumulatorul şi/sau locaţiile de
memorie asupra cărora acţionează, în caz contrar funcţionarea programului principal ar fi
compromisă. Stiva este utilizată de obicei pentru salvarea temporară a stării şi conţinutului
registrelor. Multe controlere permit întreruperi imbricate (nested interrupts) – o întrerupere şi
tratarea ei survenind în cadrul altei întreruperi, ceea ce conduce la mărirea gradului de
utilizare a stivei. La pornirea iniţială a programului întreruperile sunt inhibate şi trebuie
activate prin cod.
Timer-ele microcontrollerului MSP430 sunt numărătoare programabile. Semnalul de
tact este obţinut de la oscilatorul controlerului sau poate fi un semnal aplicat unui pin. Unui
timer se poate asocia uneori un prescaler pentru a mări capacitatea de numărare. În prezent
timer-ele sunt pe 8 sau 16 biţi; numărarea poate avea loc în sens crescător sau descrescător.
Un timer generează o întrerupere la depăşire (atunci când conţinutul său devine zero). De
obicei timer-ul poate fi citit şi scris în timpul funcţionării, facilitate care permite generarea
unor intervale de timp extrem de precise. Timer-ele moderne oferă în plus facilităţi de
comparare şi sau captură. Prin captură (capture) se stochează valoarea timer-uluiu în
momentul în care apare o tranziţie activă la unul din pinii controlerului, iar opţional se poate
genera o întgrerupere. Prin comparare (compare) se generează o întrerupere când timer-ul
ajunge la o valoare prestabilită sau se schimbă starea unui pin.
Funcţie şi de varianta constructivă sunt disponibile o serie de periferice orientate pe
interfaţa analogică:
sistem de conversie analog numerică rapid (ADC) de 12 sau 10-biţi, bazat
pe tehnica aproximării succesive, cu o rată de eşantionare de pană la 200
ksps (kilo eşantioane per secundă), cu sursă de referinţă integrată şi un
senzor de temperatură
convertor analog numeric de tip sigma-delta de 16 (14) biti
convertoare numeric analogice(CNA-DAC) de 12-biţi
comparator analogic de precizie integrat flexibil cu sistemul de temporizare
şi numărare
6
Sistemul de ceas al unităţii centrale reprezintă, prin flexibilitatea sa, o caracteristică
unică a acestei familii de microcontrolere şi a fost proiectat specific pentru aplicaţiile care
presupun un consum propriu mic şi foarte mic.
Un aşa zis ceas auxiliar de joasă frecvenţă (ACLK) este obţinut direct dintr-un
oscilator stabilizat cu ajutorul unui cuarţ de 32,768KHz (cuarţ foarte ieftin, utilizat ca bază de
timp în ceasurile electronice). Ceasul ACLK poate fi utilizat pentru funcţionarea unitătii
centrale într-un mod cu consum foarte redus, mod numit de aşteptare (stand-by), mod în care
necesitătile de prelucrare sunt minime. Unitatea centrală poate fi scoasă din acest mod prin
apariţia unui eveniment (are loc trezirea acesteia: wake-up).
Un oscilator controlat numeric (DCO-Digitally Controlled Oscillator), bazat pe o
buclă cu calare de frecventă (FLL-Frequency Locked Loop), poate furniza un aşa zis ceas de
bază (MCLK-Master Clock), atunci când se doreşte ca unitatea centrală şi unele categorii de
periferice să funcţioneze la viteza maximă. Acest oscilator poate deveni activ şi stabil (la
apariţia unui eveniment) în mai putin de 6 µs. Categoria de aplicaţii pentru care a fost
optimizat MSP430 poate fi descrisă ca presupunând funcţionarea pe perioade de timp mai
lungi sau mai scurte într-un mod de lucru cu consum foarte mic (folosind semnalul de ceas de
joasă frecvenţă ACLK), perioade întrerupte de momente în care unitatea centrală RISC de 16
biţi funcţionează la viteze mari (folosind semnalul de ceas de înaltă frecvenţă MCLK), avand
astfel capacităţi de prelucrare numerică deosebite.
Pe ansamblu, consumul mediu este în continuare mic, ducând, de exemplu, la creşterea
semnificativă a duratei de viaţă a unei surse de alimentare independente (de tip baterie sau
acumulator).
Deoarece în setul de instrucţiuni al unităţii centrale nu există instrucţiuni pentru
operaţiile de înmulţire sau înmulţire cu acumulare - însumare (MAC – Multiply and
ACumulate), operaţii foarte utile pentru implementarea în timp real a unor algoritmii de
prelucrare numerică a semnalului, la unele din variantele de MSP430 există o componentă
specializată numită multiplicator hardware. Multiplicatorul hardware este o resursă din
categoria perifericelor, care funcţionează independent de unitatea centrală.
Interfaţa cu utilizatorul (programatorul) este asigurată de un set de registre (din
categoria celor cu funcţii speciale) prin intermediul cărora sunt transmişi operanzii, se
lansează operatiile aritmetice propriu-zise şi se preia rezultatul. Există două registre de 16 biţi
pentru operanzi şi trei registre de 16 biţi pentru rezultat.
Operaţiile pe care le poate efectua multiplicatorul hardware sunt:
înmulţire fără semn
7
înmulţire cu semn
înmulţire cu acumulare, fără semn
înmulţire cu acumulare, cu semn
Combinaţiile posibile pentru dimensiunile operanzilor sunt: 16 biţi x 16 biţi, 16 biţi x
8 biţi, 8 biţi x 16 biţi, 8 biţi x 8 biţi.
Există multe variante ale acestui microcontroler, identificate prin intermediul unui cod
specific, şi grupate, functie de resursele disponibile si tensiunea de alimentare.
1.1.3. Programarea şi depanarea
Facilităţile de emulare şi depanare integrată sunt disponibile prin intermediul interfeţei
standard JTAG/ICE, cea prin care se face şi programarea memoriei FLASH interne, fără să
necesite utilizarea unor resurse suplimentare. Avantajele majore sunt:
posibilitatea realizării unui emulator in circuit (ICE) cu un cost foarte redus
dezvoltarea şi depanarea aplicatiilor în timp real (la viteza maximă de
procesare) folosind un număr minim de conexiuni cu sistemul
dezvoltarea se poate face în aceleaşi condiţii în care va funcţiona aplicaţia
finală
perturbaţii minime introduse în sistem datorită numărului minim de
interconexiuni externe
1.1.4. Memoria şi spaţiul de adresare
Toate microcontrolerele MSP430 fiind maşini Von Neumann au un singur spaţiu de
adresare de 64Kocteti (cu adrese de la 0000 la 0FFFFH), comun pentru program şi date. Acest
spaţiu este comun şi pentru memoria propriu-zisă de tip RAM sau FLASH/ROM, pentru
registrele aferente modulelor periferice şi pentru registrele cu funcţii speciale. Configuraţia
memoriei este specifică pentru fiecare variantă de MSP430, variante care diferă prin
dimensiunea RAM-ului şi a FLASH/ROM-ului, cât şi prin natura şi numărul modulelor
periferice disponibile.
Pentru orice MSP430 accesul la codul program (fetch opcod) se poate face numai la
adrese pare, pe când datele pot fi accesate fie de la adrese pare (cuvinte), fie de la adrese
impare (octeti). În figura următoare este prezentată o hartă a memoriei pentru
microcontrolerele MSP430.
8
Fig. 2.3. Organizarea memoriei microcontrollerului MSP430
1.1.5 Memoria Flash/ROM
Adresa de început a zonei de FLASH/ROM este variabilă şi depinde de dimensiunea
memoriei FLASH/ROM prezente la varianta respectivă de MSP430. Adresa finală este
întotdeauna 0FFFFH.
Zona poate fi folosită pentru memorarea de program sau date (constante, de regulă).
Constantele (sau tabelele de constante), organizate pe octet sau cuvant, pot fi memorate şi
folosite de aici, fără a fi nevoie sa fie copiate în zona de RAM.
Tabela cu vectorii de întrerupere este plasată în ultimele 16 cuvinte din spaţiul de
adrese, de la 0FFE0H la 0FFFFH. Vectorul cu cea mai mare prioritate, vectorul de reset, este
plasat la cea mai mare adresă din FLASH/ROM, la 0FFFEH. Astfel, pentru orice MSP430,
după un reset (initializare hard) prima instructiune se va executa de la adresa 0FFFEH.
1.1.6 Memoria RAM
Spaţiul de memorie RAM începe întotdeauna de la adresa 0200H. Adresa finală este
variabilă şi depinde de dimensiunea RAM-ului prezent la o anumita variantă de
microcontroler MSP430. RAM-ul poate fi utilizat pentru memorarea atât de program cât şi de
date.
9
1.1.7 Organizarea memoriei Octeţi sunt plasaţi la adrese pare sau impare, pe când cuvintele doar la adrese pare.
Astfel, când se folosesc instrucţiuni de prelucrare pe cuvânt se pot utiliza pentru operanzi doar
adrese pare. Octetul inferior (low byte) al unui cuvânt este plasat întotdeauna la o adresă pară,
iar octetul superior (high byte) la urmatoarea adresă impară. De exemplu, dacă o dată
organizată pe cuvânt este plasată la adresa pară xxx4H, octetul inferior va fi plasat la adresa
xxx4H, iar octetul superior la adresa xxx5H (vezi figura 2.4).
Fig. 2.4. Aranjarea datelor în memoria de program
1.1.8 Modulele periferice
Toate resursele modulelor periferice disponibile (pentru o anumita varianta de
MSP430) sunt plasate(mapate) în spatiul de adrese al memoriei. Adresele de la 0100H la
01FFH sunt rezervate pentru modulele periferice de 16 biţi, care trebuie accesate cu
instrucţiuni pe cuvânt. Dacă se utilizeaza instrucţiuni pe octet, sunt permise numai adrese
pare, şi octetul superior al rezultatului va fi întotdeauna zero. Adresele de la 0010H la 00FFH
sunt rezervate pentru modulele periferice de 8 biţi, care trebuie accesate cu instrucţiuni pe
octet. Dacă pentru un astfel de modul se utilizează instrucţiuni pe cuvânt pentru citire,
conţinutul octetului superior al rezultatului este nedefinit. În cazul operaţiilor de scriere pe
cuvânt, se va scrie doar octetul inferior, octetul superior fiind ignorat.
10
1.1.9 Interfeţele seriale (SPI, I2C, USART)
Interfaţa SPI (Serial Peripheral Interface) dezvoltată de Motorola este o interfaţă
serială sincronă realizată pe 3 fire (tact - CLK, data de intrare SDI Serial Data In şi SDO
Serial Data Out). În cazul în care pe interfaţa SPI se conectează mai mult de un circuit, cele 3
fire de mai sus se conectează la toate circuitele iar selecţia circuitului activ se face cu câte un
pin dedicat nCS Chip Select, care poate fi orice pin I/O. Interfaţa SPI este simplă, robustă,
rapidă şi uşor de utilizat. Dacă ea nu este implementată hard, câteva rutine vor rezolva simplu
problema. Pe SPI cele mai frecvente periferice sunt ADC, DAC, EEPROM.
Interfaţa I2C (I2C Integrated InterConnect) dezvoltată de Philips este o interfaţă
serială sincronă care utilizează doar două fire pentru toate circuitele externe conectate la
microcontroler: unul de tact, şi altul bidirecţional de date. Acesta este şi avantajul major al
interfeţei – doar două fire sunt utilizate pentru conectarea a maxim 128 circuite periferice faţă
de minim 3 + log2n fire utilizate la conectarea a n circuite periferice SPI. O deosebire majoră
faţă de SPI este că circuitele I2C au preprogramată o adresă iar numărul maxim de circuite
periferice este de 128. Deşi există o ofertă variată de la Philips şi alţi producători, unele
circuite I2C pot fi scumpe.
Interfaţa I2C foloseşte o interfaţă pe 2 fire pe o lungime de maxim 10 m, multi-master,
multi-slave cu detectarea coliziunilor şi este mai greu de implementat în software. Oricare
circuit (microcontroler sau periferic poate iniţia un mesaj şi apoi transmite sau recepţiona
date).
11
Fig. 2.5 Diagrama portului USCI configurat în modul SPI
Pentru configurarea interfeţei USCI în modul SPI, o serie de regiştrii interni
microcontrollerului trebuiesc configuraţi (UCBCTL0, UCBCTL 1 - registrii pentru controlul
portului SPI). // configurare port SPI
UCB0CTL0 = UCCKPH + UCMST + UCMSB + UCSYNC
// selectie clock -> SMCLK
UCB0CTL1 = UCSSEL1
// selectie multiplicator clock 0x02: SMCLK/2 (4 MHz)
UCB0BR0 = 0x02
12
Fig. 2.6 MSP430 în configuraţie master
Portul SPI al microcontrollerului MSP430 poate fi configurat fie în mod master (Fig.
2.6) la el putându-se conecta dispozitive slave externe, fie în mod slave (Fig. 2.7), putând fi
controlat de un dispozitiv master extern.
Fig. 2.7 MSP540 în configuraţie slave
13
(a)
(b)
Fig. 2.8 Transmiterea datelor în modul Master cu a) CKPH = 0 şi b) CKPH = 1
În funcţie de modul în care este setat bitul de tact faţă de plasarea detelor pe linia de
date, se disting 2 cazuri: datele sunt plasate pe linia de date şi apoi se activeează bitul de tact,
sau invers. În funcţie de modul în care operează dispozitivele conectate pe magistrala SPI,
trebuie ţinut cont şi de plasarea corectă a semnalului de tact (Fig. 2.8 şi 2.9).
14
(a)
(b)
Fig. 2.9 Transmiterea datelor în modul Salver cu a) CKPH = 0 şi b) CKPH = 1
15
Flag-ul CKPH are rolul de a selecta momentul de timp în care sunt puse datele pe linia
de date faţă de momentul în care se activează semnalul de tact.
2.1.10 Registrele cu functii speciale (SFR)
Există periferice care sunt configurate prin intermediul asa numitelor registre cu
funcţii speciale (SFR- Special Function registers). Aceste registre sunt plasate în primii 16
octeti ai spaţiului de adrese şi sunt organizate pe octet-byte, trebuind să fie accesate doar cu
instrucţiuni de prelucrare pe octet.
16
Capitolul 3. Programarea microcontrollerului MSP430F5438
3.1 Iniţializarea microcontrollerului
Pentru iniţializarea microcontrollerului trebuiesc parcurşi mai mulţi paşi:
Oprirea WDT
Programarea registrelor oscilatorului de tact pentru obţinerea frecvenţei
maxime de tact DCO = 16MHz
Programarea porturilor USCI în modul SPI
Programarea porturilor de selecţie a dispozitivelor conectate la magistrala
SPI în modul ieşire.
Secvenţa de program care realizează îniţializarea microcontrollerului este următoarea:
WDTCTL = WDTPW + WDTHOLD; // reseteaza WDT
UCSCTL0 = 0xFC; // Selecteaza cel mai inalt mod DCOx, MODx
UCSCTL1 = DCORSEL_6; // Select domeniul de operare la minim 12MHz
UCSCTL2 = 487; // Seteaza multiplicatorul DCO la 12MHz
// (N + 1) * FLLRef = Fdco
// (487 + 1) * 32768 = 16MHz
UCSCTL3 = SELREF_2; // Seteaza DCO FLL reference = REFO
UCSCTL4 = SELS_3 + SELM_3; // Seteaza MCLK = SMCLK = DCOCLK
P4DIR = 0xFF; // portul P4 în mod ieşire
P2DIR = 0xFF; // portul P2 în mod ieşire
În acest moment, toţi regiştrii de programare a DCO sunt setaţi pentru o funcţionare la
viteza maximă permisă de acest microcontroller: 16MHz. Utilizând microcontrollere din seria
MSP430F5438A este posibilă atingerea unei frecvenţe maxime de lucru de 25MHz. Aceasta
conduce la îmbunătăţirea vitezei de afişare a datelor pe display-ul LCD, dar şi la o creştere
nejustificată a preţului raportată la sporul de performanţă obţinut.
17
3.2 Iniţializarea şi programarea portului SPI
Pentru comunicaţia cu display-ul este folosit portul SPI UCB0, iar pentru comanda de
către un dispozitiv master extern, este folosit portul UCA0. Cele două porturi sunt comandate
în mod identic, singura diferenţă fiind la modul de iniţializare al lor.
Pentru iniţializarea portului UCB0 în modul master s-a implementat următoarea
secvenţă de cod: // configurare port SPI master
UCB0CTL0 = UCCKPH + UCMST + UCMSB + UCSYNC;
// selectie clock -> SMCLK
UCB0CTL1 = UCSSEL1;
// selectie multiplicator clock 0x00: MCLK (16 MHz)
UCB0BR0 = 0x00;
Pentru iniţializarea celui de-al doilea port în modul slave, s-a implementat secvenţa de
cod următoare: // configurare port SPI slave
UCA0CTL0 = UCCKPH + UCMSB + UCSYNC;
// selectie clock -> SMCLK
UCA0CTL1 = UCSSEL1;
// selectie multiplicator clock 0x02: SCLK/2 (4 MHz)
UCA0BR0 = 0x02;
S-a ales o viteză de lucru maximă pentru conexiunea cu afişajul, deoarece acesta
trebuie să funcţioneze la maximul de viteză ce se poate obţine, aceasta pentru că se doreşte
afişarea cursivă şi fără timpi de aşteptare. Conexiunea cu dispozitivul master este realizată la
o viteză mai scăzută, deoarece, pe de o parte s-a dorit ca acest driver grafic să poată fi
interfaţat şi cu sisteme mai lente, iar pe de altă parte volumul de date ce vor fi transferate spre
driverul grafic este foarte mult redus. Tocmai aceste este rolul acestui driver grafic, de a
prelua comenzile (primitive grafice) de la dispozitivul master, a le procesa şi transmite spre
afişaj.
18
3.3 Transmiterea datelor prin intermediul interfeţei SPI.
Pentru transmiterea şi recepţionarea datelor prin intermediul interfeţei SPI este necesar
să se cunoască modul în care funcţionează comunicaţia cu afişajul LCD (prezentată în
capitolul următor) şi mai este necesar totodată să se standardizeze comunicaţia cu dispozitivul
master.
Comunicaţia cu dispozitivul master se realizează într-un mod cât mai simplu prin
transmiterea de către dispozitivul master a comenzilor specifice pentru afişarea diverselor
primitive grafice. Comenzile sunt codate pe 16 biţi, fiecărei primitive grafice fiindu-i asociat
un astfel de cod. O comandă este urmată după caz de lista de parametrii. Driverul, în funcţie
de codul comenzii, recunoaşte automat dacă ceea ce urmează după un cod de comandă este un
parametru sau o nouă comandă. Parametrii comenzilor, acolo unde ei există, sunt obligatorii.
Tabelul 1. Comenzile acceprtate de driverul grafic
Cod comandă Funcţie comandă Parametru 1 Parametru 2 Parametru 3 Parametru 4 Parametru 5 0x01 Iniţializare LCD 0x02 Selecţie mod RGB Mod RGB 0x03 Desenare punct X Y 0x04 Desenare dreapta X1 Y1 X2 X2 Culoare 0x05 Desenare dreptunghi X1 Y1 X2 X2 Culoare 0x06 Desenare cerc X1 Y1 raza Culoare 0x07 Afisare caracter X1 Y1 Cod caracter marime Culoare 0x08 Stergere ecran 0x09 LCD OFF (negru) 0x0A LCD OFF (alb) 0x0B LCD ON 0x0C LCD POWER OFF
Pentru transmiterea datelor spre afişajul LCD prin intermediul portului SPI este
folosită următoarea secvenţă de program:
void CMsp430SPI::Reset(void)
{
P2OUT &= ~LCD_RESET; //reset Display
Delay(500);
P2OUT |= LCD_RESET;
Delay(500); // întârziere aprox 7ms
}
19
void CMsp430SPI::WriteWord(unsigned int uiData)
{
UCB0TXBUF = uiData >> 8; // Transmisie serială ( MSB 8 bits)
while (!(UCB0IFG&UCTXIFG)); // Aşteaptă terminarea transmisiei
UCB0TXBUF = uiData; // Transmisie serială ( LSB 8 bits)
while (!(UCB0IFG&UCTXIFG)); // Aşteaptă terminarea transmisiei
}
void CMsp430SPI::WriteCommand(unsigned int uiData)
{
P2OUT |= LCD_RS; // Se transmite o commanda
P2OUT &= ~LCD_CS; // selectare LCD
WriteWord(uiData);
P2OUT |= LCD_CS;
}
void CMsp430SPI::WriteData(unsigned int uiData)
{
P2OUT &= ~LCD_RS; // Se transmit date
P2OUT &= ~LCD_CS; // selectare LCD
WriteWord(uiData);
P2OUT |= LCD_CS;
}
20
Capitolul 4. Descrierea şi programarea afişajului TFT LS020
4.1. Prezentarea generală a afişajului LS020
Acest afişaj este folosit de către firma Siemens la următoarele tipuri de telefoane
mobile: S65, M65, CX65, şi SK65. LS020 este un afişaj TFT de 16-bit cu 132x176 pixeli.
Acest afişaj foloseşte LED-uri albe pentru iuminare şi are o dimensiune atractivă pentru
majoritatea proiectelor low-cost. Afişajul poate fi găsit la magazinele unde se repară telefoane
şi se pot cumpăra doar anumite părţi de telefoane şi este la un preţ de aproximativ 12euro. În
următoarea figură (4.1) se prezintă afişajul LS020 folosit în telefonul Siemens S65.
Fig. 4.1 Afişajul LS020 prezent în telefoanele Siemens S65
Dimensiunile acestui afişaj sunt de 55,8mm x 38,2mm, fiind ideal pentru realizarea
unor proiecte de mici dimensiuni.
În figura 4.3 este prezentată configuraţia pinilor display-ului.
21
Fig. 4.2. Dimensiunile display-ului LS020
Fig. 4.3 Configuraţia pinilor display-ului LS020
22
4.2. Programarea display-ului LS020
4.2.1. Iniţializare display-ului
Afişajul identifică datele transmise de către μC prin testarea liniei RS: dacă linia RS
este pe nivel înalt afişajul aşteaptă comenzi şi dacă este pe nivel scăzut aşteaptă date. Un
display LCD TFT este programat la început, aceasta pentru că pentru pornirea afişajului este
necesară parcurgerea unei succesiuni specifice de operaţii. Iniţializarea de face în doi paşi,
între aceştia fiind nevoie de o pauză pentru stabilizare tensiunii înalte folosite la electrizarea
sticlei display-ului. Cele două secvenţe care alcătuiesc programul de iniţializare sunt:
INIT1
0xFDFD, 0xFDFD
0xEF00
0xEE04, 0x1B04
0xFEFE, 0xFEFE
0xEF90, 0x4A04, 0x7F3F, 0xEE04, 0x4306
După această secvenţă trebuie să aşteptăm stabilizarea tensiunilor surselor interne de
tensiune, o perioadă de timp foarte sensibilă, care dacă este prea mică sau prea mare display-
ul nu va funcţiona coprect. Această perioadă a fost măsurată la 7ms. Urmează cea de-a doua
secvenţă de iniţializare:
INIT2
0xEF90, 0x0983, 0x0800, 0x0BAF, 0x0A00, 0x0500, 0x0600, 0x0700
0xEF00
0xEE0C
0xEF90, 0x0080
0xEFB0, 0x4902
0xEF00
0x7F01, 0xE181
0xE202
0xE276
0xE183
0x8001
După ce şi cea de-a doua secvenţă a fost introdusă, diplay-ul este gata de utilizare. Se
recomandă un clear screen deoarece display-ul după ce este pornit arată pixeli de culori
aleatoare.
23
4.2.2 Oprirea display-ului
Înainte de oprirea sistemului, afişajul trebuie oprit deoarece lasându-l pornit îi scade
durata de funcţionare. Display-ul se poate opri împreună cu întregul sistem, odată cu oprirea
sistemului de alimentare, lucru care nu este însă de dorit. A fost implementată o secvenţă de
cod care va realiza oprirea în siguranţă a afişajului.
void CDisplay::PowerOFF(void)
{
int i;
const unsigned int powerOFF[] = {
0xEF00, 0x7E04, 0xEFB0, 0x5A48,
0xEF00, 0x7F01, 0xEFB0, 0x64FF,
0x6500, 0xEF00, 0x7F01, 0xE262,
0xE202, 0xEFB0, 0xBC02, 0xEF00,
0x7F01, 0xE200, 0x8000, 0xE204,
0xE200, 0xE100, 0xEFB0, 0xBC00,
0xEF00, 0x7F01};
for(i=0;i<=26;i++)
{
m_spi.WriteCommand(powerOFF[i]);
}
}
4.2.3 Comenzi pentru scriere full-screen sau secţiuni
Comanda pentru scrierea în memorie este:
MEMWR: 0xEF90, 0x05OR, 0x06YS, 0x07XS
După această comandă displayul este gata de folosire pixel cu pixel, în modul 16 biţi-
culoare / pixel. Parametri YS şi XS definesc subsecţiuni ale întregii memorii de afişaj.
Acestea se folosesc dacă nu dorim să scriem în toată zona de memorie, ci doar într-o porţiune
a acesteia. Aceasta se realizează la următoarea comandă MEMWR unde se resetează pointerul
la coordonatele introduse. Ecranul complet se scrie cu parametrii YS=0 şi XS=0. Pentru
această scriere nu este nevoie de o declarare a parametrilor, este suficientă scrierea datelor şi
ulterior suprascrierea lor. Numărul total de biţi este 132x176x2. Memoria este scrisă la
început în direcţia X şi după aceea în direcţia Y, iar parametrul OR defineşte orientarea:
OR=0x04 setează orientarea la 0°, memoria este scrisă pe linia x de la stânga la dreapta,
24
OR=0x00 setează orientarea la 90°, memoria este scrisă pe linie, pe coloane începând din
stânga sus în jos.
4.2.4. Codificarea culorii pixelilor
Afişajul LS020 permite 3 moduri de reprezentare a culorilor:
8 biţi
16 biţi
24 biţi
Imediat după reset, afişajul trece automat în modul de culoare 16 biţi. În acest mod,
memoria este scrisă după codul -5-6-5- adică –R-G-B- , primii cinci biţi codează intensitatea
culorii roşu, următorii şase biţi cea a culorii verde şi ultimii cinci biţi cea a culorii albastru.
Exemplu : 0xFFFF este alb şi 0x0000 este negru.
În modul 24 bit, fiecare culoare este codificată printr-un octet pentru roşu, unul pentru
albastru şi unul pentru verde.
În modul 8 biţi se lucrează cu o reprezentare a culorilor de tipul RRRGGBB, cel mai
uşor fiind prin folosirea unei palete de culori cum este cea din figura de mai jos:
Fig. 4.4 Paleta de culori a display-ului LS020 în modul 8bit
4.2.5 Afişarea parţială a ecranului
Memoria este organizată într-o matrice cu coordonate X şi Y unde în fiecare
locaţie este salvată o informaţie asupra culorii pixelului.
25
Fig. 4.5 Modul de adresare a memoriei grafice
Pentru scrierea parţială se începe din colţul (X1,Y1) şi se sfârşeşte la (X2,Y2).
PMEMWRX direcţia X 0xEF90, 0x0504, 0x08X1, 0x09X2, 0x0AY1, 0x0BY2
PMEMWRY direcţia Y 0xEF90, 0x0500, 0x08X1, 0x09X2, 0x0AY1, 0x0BY2
Este de precizat că afişajul LS020 actualizează tot timpul întreg ecranul, chiar dacă
doar o parte din el se modifică. Motivul pentru aceasta este controlerul grafic s1d13732 care
reţine memoria actuală şi o scrie pe cea nouă print-un mod hardware. Doar comenzile sunt
generate de μC. Secvenţa folosită de Siemens pentru a scrie memoria completă este:
0xEF90, 0x0500, 0x0600, 0x0700
după aceasta urmează datele şi normal dezactivarea liniei RS care acum trebuie să fie
pe nivel scăzut. Întreaga procedură de scriere a memoriei durează 28,59ms care corespunde la
132*176*16=371712 biţi la o frecvenţă de clock de 16MHz.
26
4.2.6. Regiştrii de control ai afişajului LS020
În tabelul 2 sunt prezentaţi regiştrii de control ai afişajului LS020. Aceşti regiştrii se
găsesc la diferite adrese în memoria afişajului, ei putând fi accesaţi de către programator:
Tabelul 2. Setul de comenzi al afişajului LCD
Bank 90h Register number Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 R00h WTH BLK YMIR ACT * * * * Control Register R01h YDIR XDIR * BGR * * * * 10h - B & R colors are swapped R02h * * * * * D2 * D0 05h - Image OFF R04h * * * * * * * 8COL 01h - 8-color display mode R05h * * * * * ROT * * 04h - 90deg ROTATE R06h D7 D6 D5 D4 D3 D2 D1 D0 Cursor position Y R07h D7 D6 D5 D4 D3 D2 D1 D0 Cursor position X R08h D7 D6 D5 D4 D3 D2 D1 D0 Y1 window corner (00h..83h) R09h D7 D6 D5 D4 D3 D2 D1 D0 Y2 window corner (Y1..83h) R0Ah D7 D6 D5 D4 D3 D2 D1 D0 X1 window corner (00h..AFh) R0Bh D7 D6 D5 D4 D3 D2 D1 D0 X2 window corner (X1..AFh) R0Fh D7 D6 D5 D4 D3 D2 D1 D0 Start position (X) of scrolling area R10h D7 D6 D5 D4 D3 D2 D1 D0 Width of scrolling area R11h D7 D6 D5 D4 D3 D2 D1 D0 Scrolling value (up to value of R10h) R13h * * * * * * * COL Inactive area color (00h=black, 01h=white) R14h D7 D6 D5 D4 D3 D2 D1 D0 Active area #1 offset (X) R15h D7 D6 D5 D4 D3 D2 D1 D0 Active area #2 offset (X) R16h D7 D6 D5 D4 D3 D2 D1 D0 Active area #1 width R17h D7 D6 D5 D4 D3 D2 D1 D0 Active area #2 width R1Dh * * * * * D2 * * XMirror + Shift R22h D7 D6 D5 D4 D3 D2 D1 D0 Something occurs R23h D7 D6 D5 D4 D3 D2 D1 D0 Image refresh frequency R24h D7 D6 D5 D4 D3 D2 D1 D0 Image contrast RE8h 0 0 0 0 * * 8BIT * Transfer mode (LCD host mode)
Bank B0h Register number Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Short description R49h 1 D0 Negative/Positive Mode
Any Bank Register number Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Short description REFh D7 D6 D5 D4 D3 D2 D1 D0 Current Bank Register
27
Capitolul 5. Primitive grafice
5.1 Desenare pixeli
Pentru afişarea unui pixel se accesează registrul 00 de la adresa EF90 în care se scriu
coordonatele pixelului ce se doreşte a se afişa cu o culoare specificată.
void CDisplay::PutPixel(unsigned char x, unsigned char y, unsigned int uiColor) { m_spi.WriteCommand(0xEF90); m_spi.WriteCommand(0x0500); m_spi.WriteCommand(0x0800 + x); m_spi.WriteCommand(0x0900 + x ); m_spi.WriteCommand(0x0A00 + y); m_spi.WriteCommand(0x0B00 + y ); m_spi.WriteData(uiColor); }
5.2 Desenare linii
Afişajul LS020 nu are funcţii speciale pentru deenarea de linii, aceasta fiind sarcina
utilizatorului (programatorului). Pentru trasarea unei linii s-a folosit ecuaţia trigonometrică a
unei drepte.
void CDisplay::Line( unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned int uiColor) { if (TEXT_ORIENTATION == TEXT_90_DEG ) { unsigned char ucSwap = 0; ucSwap = x1; x1 = y1; y1 = ucSwap; ucSwap = x2; x2 = y2; y2 = ucSwap; x1 = 132 - x1; x2 = 132 - x2;
28
} short u,s,v,d1x,d1y,d2x,d2y,m,n; int i; u = x2-x1; v = y2-y1; d1x = u/abs(u); d1y = v/abs(v); d2x = u/abs(u); d2y = 0; m = abs(u); n = abs(v); if (m <= n) { d2x = 0; d2y = v/abs(v); m = abs(v); n = abs(u); } s = (int)(m / 2); for (i=0;i<(m);i++) { PutPixel(x1,y1,uiColor); s += n; if (s >= m) { s -= m; x1 += d1x; y1 += d1y; } else { x1 += d2x; y1 += d2y; } } }
5.3 Desenare dreptunghiuri şi suprafeţe
Funcţia pentru desenare dreptunghi poate fi folosită şi pentru desenarea de suprafeţe
prin simpla specificare a culorii de interior.
void CDisplay::FillRect(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned int uiColor) { int x,y; if(x2 < x1){ x = x1; x1 = x2; x2 = x;} // x2 > x1 if(y2 < y1){ y = y1; y1 = y2; y2 = y;} // > x1 m_spi.WriteCommand(0xEF90); m_spi.WriteCommand(0x0500); m_spi.WriteCommand(0x0800 + x1); m_spi.WriteCommand(0x0900 + x2 -1); m_spi.WriteCommand(0x0A00 + y1); m_spi.WriteCommand(0x0B00 + y2 -1); for(unsigned int counter = 0; counter < ((x2 - x1)* (y2 - y1)); counter++){ m_spi.WriteData(uiColor); } }
29
5.3 Afişare caractere
Pentru afişarea caracterelor este nevoie de definirea în prealabil a acestora.
Caractererele sunt generate cu ajutorul unui program software (fontGen.exe) care le
converteşte din caractere în format specific sistemului de operare Windows într-o imagine în
alb şi negru a acestora şi apoi sub formă de înşiruire de octeţi. Funcţia care afişează
caracterele este prezentată mai jos. void CDisplay::WriteString( unsigned char x, unsigned char y, char* pString, unsigned int uiFgColor, unsigned int uiBkColor, FONT_DEF * pFont) { unsigned int offset, width; unsigned char i, j, map, height, k, allwidth = 0; for(k=0 ; pString[k]!=0 ; k++){ map = pFont->mapping_table[pString[k]]; if(pFont->glyph_width == 0) { width = pFont->width_table[map]; } else { width = pFont->glyph_width; } height = pFont->glyph_height; offset = pFont->offset_table[map]; if (TEXT_ORIENTATION == TEXT_0_DEG ) { for(j = 0; j < height * (((width-1)/8)+1) ; j+=(((width-1)/8)+1) ) { // height for(i = 0; i < width ; i++){ // width if( pFont->glyph_table[ offset+j+(i/8) ] & pow2( 7 - ( i % 8 ) )) PutPixel( x+i +allwidth , y+j / (((width-1)/8)+1) , uiFgColor ); else PutPixel( x+i +allwidth , y+j / (((width-1)/8)+1) , uiBkColor ); } } allwidth += width; } if (TEXT_ORIENTATION == TEXT_90_DEG ) { for(i = 0; i < width ; i++){ // width for(j = height * (((width-1)/8)+1); j > 0 ; j-=(((width-1)/8)+1) ) { // height if( pFont->glyph_table[ offset+j+(i/8) ] & pow2( 7 - ( i % 8 ) )) PutPixel(y+j / (((width-1)/8)+1), 172 - x-i - allwidth , uiFgColor ); else PutPixel(y+j / (((width-1)/8)+1), 172 - x-i - allwidth , uiBkColor ); } } allwidth += width; } } }
30
Bibliografie
[1] Gilliland, Matt, The microcontroller application cookbook, Woodglen Press,
2002
[2] Texas Instrtuments, MSP540f5438 Mixed Signal Microcontroller
[3] Texas Instruments, MSP430x5xx Family User's Guide
[4] John H. Davies, MSP430 Microcontroller Basics, Newnes, 2008
[5] Tom Baugh, MSP430 State Machine Programming: with the ES2274,
SoftBaugh Inc., 2008
[6] Chris Nagy, Embedded Systems Design Using the TI MSP430 Series, Newnes,
2003
[7] Jerry Luecke, Analog and Digital Circuits for Electronic Control System
Applications: Using the TI MSP430 Microcontroller, Newnes , 2004
[8] John Catsoulis , Designing Embedded Hardware, O'Reilly Media, 2005
[9] Jack Ganssle, The Firmware Handbook, Newnes, 2004
[10] www.ti.com
[11] http://www.superkranz.de/christian/S65_Display/DisplayIndex.html
[12] http://www.mikrocontroller.net/
[13] Texas Instruments, MSP430x5xx Quick Start Guide, 2009
[14] Texas Instruments, MSP430x5xx Overview Comparison to MSP430x2xx and
MSP430x4xx, 2008
[15] Texas Instruments, MSP-EXP430F5438 Experimenter Board - User's Guide,
Ianuarie 2009
31
Anexa 1. Schema electrică şi cablajul driverului grafic
Schema electrică a circuitului cu microcontroller
32
Schema convertorului de tensiune DC-DC
Cablajul imprimat al driverului grafic
33