116
ELEKTROTEHNIČKI FAKULTET U BEOGRADU Katedra za elektroniku Softverska rešenja za razvojnu ploču sa MSP430F449 mikrokontrolerom - Diplomski rad - Student: Marko Atanasievski 03/064 Profesor: Lazar Saranovac Beograd, 2008.

Diplomski+rad+Marko+Atanasievski+

Embed Size (px)

DESCRIPTION

jj

Citation preview

Page 1: Diplomski+rad+Marko+Atanasievski+

ELEKTROTEHNIČKI FAKULTET U BEOGRADU

Katedra za elektroniku

Softverska rešenja za razvojnu ploču sa MSP430F449 mikrokontrolerom

- Diplomski rad -

Student:

Marko Atanasievski 03/064

Profesor:

Lazar Saranovac

Beograd, 2008.

Page 2: Diplomski+rad+Marko+Atanasievski+

Sadržaj

Poglavlje StranaUvod 31. MSP430F449 i komponente na razvojnoj ploči 52. Prekidi 93. Tajmeri A i B 154. A/D konvertor 225. Eksterni tasteri 286. PWM izlazi 347. LED displej 408. Tastatura 489. LCD displej pogonjen od strane mikrokontolera 5610. Inteligentni LCD displej 6311. Temperaturni PWM senzor 76

12. 1-wire temperaturni senzor 8013. SPI digitalni potenciometar 8914. SPI EEPROM memorija 9515. I2C EEPROM memorija 100PRILOG A - Fajl sa definicijama simboličkih oznaka korišćenih u radu sa razvojnom pločom

110

Literatura 116

Page 3: Diplomski+rad+Marko+Atanasievski+

Uvod

U svetu danšnjice, pri tempu razvoja tehnike i tehnoligije kao nikada ranije, postoji ogromna potreba za razvojem namenskih digitalnih sistema (embedded systems). Sistemi sa specifičnom, namenskom primenom, nalaze se bukvalno na svakom mestu. O tome govori podatak da je od oko pet milijardi čipova proizvedenih godišnje, svega trista miliona završi u personalnim računarima, na koje se najčešće misli kada se govori o svetu mikroprocesora. Preostali broj svoje mesto nalazi u tosterima, mp3 uređajima i vojnim avionima.

Značajno pojeftinjenje mikrokontrolera (neki mikrokontroleri se mogu kupiti za manje od jednog dolara), njihova raznovrsnost i veliki broj proizvođača doprinose velikoj ekspanziji namenskih digitalnih sistema. Postoje naravno razlčite klase mikrokontrolera, od vrlo jednostavnih PIC kontrolera kakve bi recimo koristili za kontrolu niza led dioda do vrlo kompleksnih i moćnih ARM procesora koji pogone večinu današnjih mobilnih telefona.

Zahvaljući fleksibilnom i velikom tržištu, gotovo uvek je moguće lako naći prave komponente za svoj dizajn. Ukoliko to nije slučaj, neki proizvođači isporučuju svoje čipove u vidu HDL (hardware description language) izvornog koda, sa mogućnošću da se mikroprocesori prilagode svojim potrebama (najpoznatija po ovome je svakako kompanija ARM, koja uopšte ne proizvodi ove procesore već samo ustupa dizajn pod licencom).

Do pre nekoliko godina veliki deo izdatka za razvoj namenskih digitalnih sistema je predstavljao softver. U profesionalnih primenama nije neobično da se za opremanje jednog razvojnog kompjutera potroši desetak hiljada dolara. IDE razvojna okruženja za razvoj softvera za mikrokontrolere su moćna, brza, stvaraju efikasan i brz kompajlirani kod i pružaju najšire mogućnosti debagovanja. Međutim ovakva okruženja koštaju bar hiljadu dolara. Na sreću studenata i dizajnera sa malim budžetom, gotova sva IDE razvojna okruženja su dostupna u trial i kickstart verzijama, koje su potpuno funkcionalne, ali uz ograničenje veličine koda i naprednih mogućnosti. Za razvoj softvera prikazanog u ovom radu je korišćen IAR embedded workbench za MSP430 mikrokontroler, koji ima ograničenje od 4 kb za C kod(asemblerski kod je neograničen). Iz tog razloga je većina softvera pisana u asembleru, zato što se autoru dešavalo da na početku pisanja programa posle upotrebe celobrojnog deljenja i nekoliko funkcija za rad sa stringovima u C kodu, program zbog veličine ne može da bude kompajliran. Još jedno pogodno razvojno okruženje za ovu ploču je Code Composer Essentials firme Texas Instruments, čija verzija 3 treba da izađe u vreme nastanka ovog rada. Ovaj razvojni sistem je bazirani na Eclipse IDE okruženju i ograničenje koda je 16 kb.

Ukoliko se želi besplatno legalno razvojno okruženje za mikrokontrolere bez ograničenja, na internetu se mogu naći kompajleri, debageri i razvojna okruženja pod besplatnom GNU licencom. Najčešće je potrebno uložiti malo više truda i pretraživanja internet foruma da se instalira i osposobi za rad ovakav sistem, ali sa druge strane ne postoje pomenuta ograničenja. Autor je nedavno malo eksperimentisao i posle određenog broja sati dobio odličan GNU razvojni sistem baziran na Eclipsu i gcc kompajleru i debageru za ARM mikrokontrolere.

Page 4: Diplomski+rad+Marko+Atanasievski+

Za eksperimentisanje i razvoj novih dizajna, postoji veliki broj najrazličitijih razvojnih ploča za mikrokontrolere. One obično poseduju standardne periferije i konektore, i omogućavaju lako proširivanje sistema svim potrebnim komponentama. Za studente i hobiste je to velika pogodnost, zato što je moguće imati svoj razvojni sistem, sa mogućnošću programiranja i debagovanja preko PC računara, za manje od stotinak dolara. Generacija studenata ETF-a 2003 je koristila takve gotove kupovne ploče sa MSP430 mikrokontrolerima kompanije Olimex iz Bugarske na laboratorijskim vežbama iz IRS-a.

Za potrebe Katedre za elektroniku ETF-a u Beogradu je od strane kolege Danila Skorkovića kao diplomski rad [8] isprojektovana razvojna ploča sa MSP430F449 mikrokontrolerom i brojnim periferijama prilagođena za potrebe laboratorijskih vežbi i diplomskih radova studenata Katedre za elektroniku.

Ovaj diplomski rad prikazuje softverska rešenja i primere programa za upotrebu svih komponenata prisutnih na ploči. Podeljen je na poglavlja koja se bave posebno jednom komponentom i njenim korišćenjem, u formi uputstva. U prilogu je dat u celosti .h fajl sa definicijama simboličkih oznaka korišćenih u programu.

Prvo poglavlje ukratko prikazuje arhitekturi MSP430F449 mikrokontrolera i ploče. Drugo poglavlje se bavi prekidima MSP430F449 mikrokontrolera. Treće poglavlje opisuje najčešći način korišćenja tajmera A i B prisutnih u mikrokontroleru. Četvrto poglavlje prikazuje upotrebu A/D konvertora. Peto poglavje se bavi tasterima, kojih je na razvojnoj ploči prisutno četiri, i njihovom upotrebom. Šesto poglavlje opisuje PWM (pulse width modulation) izlaze, i daje primer njihovog korišćenja. Sedmo poglavlje se bavi LED displejom prisutnim na ploči. Osmo poglavlje razrađuje upotrebu numeričke tastature prisutne na ploči. Deveto poglavlje prikazuje upotrebu LCD displeja pogonjenog od strane mikrokontrolera. Deseto poglavlje se bavi inteligentnim LCD displejom sa integrisanim kontrolerom. Jedanaesto poglavlje razrađuje upotrebu PWM temperaturnog senzora. Dvanaesto poglavlje pokazuje primenu 1-wire temperaturnog senzora. Trinaesto poglavlje razrađuje upotrebu SPI digitalnog potenciometra. U četrnaesto poglavlju opisuje se primena SPI EEPROM memorije. I konačno, petnaesto poglavlje se bavi I2C EEPROM memorijom.

Autor se nada da će ovaj rad pomoći kolegama studentima ETF-a da brzo i lako iskoriste željene i potrebne funkcije MSP430F449 razvojne ploče.

Page 5: Diplomski+rad+Marko+Atanasievski+

1. MSP430F449 i komponente na razvojnoj ploči

MSP430F449 je šesnaestobitni mikrokontroler firme Texas Instruments [1]. Projektovan je sa posebnim osvrtom na malu potrošnju, tako da je pogodan za aplikacije gde se koristi baterijsko napajanje. Karakteriše ga Von Neumann-ova arhitektura, i 16-bitni RISC CPU, sa svega 27 procesorskih naredbi i 7 načina adresiranja. Svaka od naredbi podržava sve načine adresiranja.

Kod ove familije mikrokontrolera periferije i interna memorija su mapirani u jedinstveni adresni prostor, prikazan na slici 1.1. Adresna i magistrala podataka su šesnaestobitne, tako da se u adresnom prostoru se može adresirati 64 Kb.

MSP430F449 poseduje 4 Kb rama, u donjem delu memorijskog prostora. Registri sa specijalnim namenama su mapirani u najnižih 16 bajtova memorije. Od adrese 10h do 1FFh su mapirane periferije. Lokacije od 100h do 1FFh su rezervisane za šesnaestobitne periferije, tako da manipulacije na ovim lokacijama zahtevaju šesnaestobitni pristup. Ram memorija, koja se uobičajeno koristi za podatke i tekuće rezultate obrade u programima, je u opsegu adresa od 200h do FFFh. Za program koji se izvršava na mikrokontroleru i fiksne podatke je raspoloživa memorija na lokacijama od 1000h na više. Vektorska tabela prekida je u vrhu memorijskog prostora. Program počinje izvršenje od adrese koja je upisana u reset prekidni vektor na lokaciji FFFEh.

Bajtovima u memorijskom prostoru se može pristupati na parnim i neparnim adresama. Šestnaestobitnim rečima se može pristupati samo na parnim adresama.

Mikrokontroler MSP430F449 ima šesnaest šesnaestobitnih registara, od toga prva četiri imaju specijalne funkcije a ostali su registri opšte namene.

Takt sistem ovog mikrokontrolera je vrlo fleksibilan. Postoje tri taktna signala koje je softverski moguće distribuirati do različith delova sistema. Sva podešavanja taktnog sistema se rade softverski, korekcijom bita u registrima za kontrolu takta.

ACLK – Auxiliary Clock – spoljni takt na iz 32768 Hz oscilatora koji se nalazi na ploči.

Slika 1.1 Memorijski prostor

Page 6: Diplomski+rad+Marko+Atanasievski+

MCLK – Master Clock – glavni takt sistema. Koristi se za CPU i softverski se usmerava na periferije velike brzine. Njegov izvor je DCO – digitaly controlled oscilator, i omogućava brzine takta do 8 Mhz brzine. Po uključenju takt je 1 Mhz.

SMCLK – Sub-master clock – rakođe je pogonjen od DCO-a. Koriste ga periferije velike brzine.

MSP430F449 je po dovođenju napajanja aktivan i stabilan za najviše 6 us. Takođe osim aktivnog postoji i pet različitih low power stanja, koja su vrlo korisna za upotrebu u sistemima sa baterijskim napajanjem(ovaj rad se ne bavi njima).

MSP430F449 od integrisanih periferija poseduje:− dva ugrađena 16-bitna tajmera sa mnoštvom capture/compare registara− 12-bitni A/D konvertor sa 16 registara za čuvanje rezultata, maksimalnom

brzinom od 200 kilosempla u sekundi, kao i brojnim opcijama za prilagođavanje rada A/D konvertora specifičnim zahtevima. A/D konvertor radi nezavisno od procesora.

− Integrisani lcd kontroler− Šesnaestobitni hardverski množač koji rezultat daje trenutno.− Dve USART jedinice, sa mogućnošću rada u asinhronom ili SPI režimu rada− Šest ulazno-izlaznih portova, sa mogućnošću podešavanja svakog pina. Pinovi

portova P1 i P2 imaju i mogućnosti prekidnih zahteva.

Na razvojnoj ploči se nalaze sledeće komponente:

− Ćetiri eksterna dugmeta, od čega su tri povezana na pinove portova P1 i P2, sa mogućnošću obrade njihovog pritiska u prekidnim rutinama.

− Četiri potenciometra koja se vode na analogne ulaze A/D konvertora, u slučaju da nije prisutan a neophodan je analogni signal na pinovima za proširenje ploče.

Slika 1.2 Arhitektura mikrokontrolera MSP430F4xx familije

Page 7: Diplomski+rad+Marko+Atanasievski+

− Dve brojčane tastature.− LCD displej sa četiri cifre pogonjen od strane mikrokontrolera.− Inteligentni LCD displej AC-162B sa dva reda od po šesnaest karaktera.− LED displej sa šest cifara− 1-wire konekor sa DS1820 temperaturnim senzorom firme Dallas Semiconductors− PWM temperaturni senzor DSSMT16030− SPI digitalni potenciometar MCP41010− SPI EEPROM 25C320 sa 32 KBita memorije− I2C EEPROM ATMEL 24C04 sa 4 KBita memorije− 4 PWM izlaza mikrokontrolera se preko led dioda vode na eksterni konektor− eksterni RS232 konektor− Signali SPI magistrale se takođe vode na eksterne pinove radi mogućnosti

dodavanja eksternih periferija

Page 8: Diplomski+rad+Marko+Atanasievski+

Slika 1.1 Razvojna ploča sa MSP430F449 mikrokontrolerom

Page 9: Diplomski+rad+Marko+Atanasievski+

2. Prekidi

U savremenim namenskim digitalnim sistemima komunikacija sa perijerijama i drugim sistemima se u najvećoj meri zasniva na obradi prekidnih zahteva. Prekidi MSP430F449 [1] mikrokontrolera mogu da budu:

− Sistemski reset− Nemaskirajući prekidni zahtev− Maskirajući prekidni zahtevi

Na slici 2.1 je prikazan arhitektura hardverskog povezivanja prekidnih izvora na procesor.

U slučaju sistemskog reseta, procesor očitava reset prekidni vektor sa lokacije FFFEh i izvršavanje programa kreće sa očitane adrese.

Na nemaskirajući zahteve nema uticaja bit GIE (general interrupt enable), ali se omogućavaju odnosno onemogućavaju posebnim bitima prisutnim u sistemskim registrima

Slika 2.1 Hardversko povezivanje prekidnih izvora.

Page 10: Diplomski+rad+Marko+Atanasievski+

(ACCVIE, NMIIE, OFIE). Povodi za nemaskirajuće zahteve su ivica na RST/NMI ulaznom pinu, greška u radu oscilatora i greška u pristupu fleš memoriji.

Ovde ćemo se ograničiti na maskirajuće prekidne zahteve koji se koriste za komunikaciju sa svim perijerijama. Vektorska tabela prekida se nalazi u samom vrhu adresnog prostora mikrokontrolera i prikazana je u tabeli 2.1. Prekidi čiji su vektori na višoj adresi imaju veći prioritet ukoliko dođe do istovremene pojave više prekidnih zahteva.

Prekidni izvor Prekidni fleg Tip prekida u sistemu

Adresa prekidnog

vektora

Prioritet

Dovod napajanja, eksterni reset, watchdog(reset mod)

WDTIFGKEYV

Reset 0FFFEh 15, najviši

NMI, greška u radu oscilatora, greška u pristupu flešu

NMIIFGOFIFGACCVIFG

Nemaskirajući 0FFFCh 14

Tajmer B CCO TBCCR0 CCIFG Maskirajući 0FFFAh 13

Timer B CC1-6, TB

TBCCRx CCIFG,TBIFG

Maskirajući 0FFF8h 12

Comparator A CAIFG Maskirajući 0FFF6h 11

Watchdog Timer(tajmer mod)

WDTIFG Maskirajući 0FFF4h 10

USART 0 Receive URXIFG0 Maskirajući 0FFF2h 9

USART 0 Transmit

UTXIFG0 Maskirajući 0FFF0h 8

ADC ADC12IFGx Maskirajući 0FFEEh 7Timer A CC0 TACCR0

CCIFGMaskirajući 0FFECh 6

Timer A CC1-2, TA

TACCRx CCIFG,TAIFG

Maskirajući 0FFEAh 5

Port 1 P1IFGx Maskirajući 0FFE8h 4USART 1 Receive URXIFG1 Maskirajući 0FFE6h 3USART 1 URXIFG1 Maskirajući 0FFE4h 2

Page 11: Diplomski+rad+Marko+Atanasievski+

TransmitPort 2 P2IFGx Maskirajući 0FFE2h 1Basic Timer BTIFG Maskirajući 0FFE0h 0, najniži

Tabela 2.1 Prekidi.

Uz IAR razvojno okruženje se isporučuje i .h fajl msp430x44x.h koji sadrži simboličke definicije svih naziva registara, bitova i flegova koje ima MSP430F449 kontroler. Ovaj fajl bi trebalo da se uključi na početku svakog programa namenjenog ovom mikrokontoleru direktivom #include. Između ostalog u ovom fajlu se definišu i vektori prekida koji značajno olakšavaju rad sa prekidnim rutinama, i deo sa tim definicijama je prikazan u nastavku:

/************************************************************* Interrupt Vectors (offset from 0xFFE0)************************************************************/

#define BASICTIMER_VECTOR (0 * 2u) /* 0xFFE0 Basic Timer */#define PORT2_VECTOR (1 * 2u) /* 0xFFE2 Port 2 */#define USART1TX_VECTOR (2 * 2u) /* 0xFFE4 USART 1 Transmit */#define USART1RX_VECTOR (3 * 2u) /* 0xFFE6 USART 1 Receive */#define PORT1_VECTOR (4 * 2u) /* 0xFFE8 Port 1 */#define TIMERA1_VECTOR (5 * 2u) /* 0xFFEA Timer A CC1-2, TA */#define TIMERA0_VECTOR (6 * 2u) /* 0xFFEC Timer A CC0 */#define ADC12_VECTOR (7 * 2u) /* 0xFFEE ADC */#define USART0TX_VECTOR (8 * 2u) /* 0xFFF0 USART 0 Transmit */#define USART0RX_VECTOR (9 * 2u) /* 0xFFF2 USART 0 Receive */#define WDT_VECTOR (10 * 2u) /* 0xFFF4 Watchdog Timer */#define COMPARATORA_VECTOR (11 * 2u) /* 0xFFF6 Comparator A */#define TIMERB1_VECTOR (12 * 2u) /* 0xFFF8 Timer B CC1-6, TB */#define TIMERB0_VECTOR (13 * 2u) /* 0xFFFA Timer B CC0 */#define NMI_VECTOR (14 * 2u) /* 0xFFFC Non-maskable */#define RESET_VECTOR (15 * 2u) /* 0xFFFE Reset [Highest Priority] */

#define UART1TX_VECTOR USART1TX_VECTOR#define UART1RX_VECTOR USART1RX_VECTOR#define UART0TX_VECTOR USART0TX_VECTOR#define UART0RX_VECTOR USART0RX_VECTOR#define ADC_VECTOR ADC12_VECTOR

Kod 2.1 Definicije simboličkih naziva za prekidne vektore u vektorskoj tabeli prekida.

Pri definiciji prekidnih rutina u C kodu se koristi direktiva #pragma koju prati simbolički naziv prekidnog vektora. Ključna reč __interrupt govori kompajleru da se radi o prekidnoj rutini. Jezgro jedne prekidne rutine u C kodu, ovde za primer je uzet prekid A/D konvertora, je prikazana u sledećem kodu 2.2. Dovoljno je da ova rutina bude u nekom od C fajlova uključenih u projekat i kompajler i linker će se pobrinuti za ostalo.

Page 12: Diplomski+rad+Marko+Atanasievski+

#include "msp430x44x.h" #pragma vector=ADC12_VECTOR // prekidna rutina A/D konvertora__interrupt void adc12_prekidna_rutina(void)

{ //Neki kod

}

Kod 2.2 Jezgro prekidne rutine A/D konvertora.

Prekidna rutina ne sme imati povratnu vrednost funkcije, t.j. ona mora biti void, i njoj se ne mogu preneti nikakvi parametri. U slučaju C prekidne rutine, kompajler vodi računa da statusni registar i registri R4 do R11 budu sačuvani na steku i ovo se dešava automatski, kao deo poziva prekidne rutine. Ovo je neophodno budući da prekidni zahtev može da dođe u proizvoljnom trenutku u toku izvršavanja nekog programa. Po izlasku iz rutine restaurira se stanje registara kakvo je bilo pre ulaska u prekidnu rutinu.

Da bi program uopšte ušao u prekidnu rutinu, mora biti setovan bit GIE, i još jedan periferijski bit koji dozvoljava obradu prekidnih zahteva i čiji naziv i lokacija zavisi od periferije. U C kodu postoje kompajlerske direktive koje uključuju odnosno isključuju GIE bit a to su __enable_interrupt(), __disable_interrupt(). U asembleru se to radi direktivama eint i dint, ili ručno bis.b #GIE,SR odnosno bic.b #GIE,SR.

Da bismo omogućili prekid npr. sa svih pinova porta P1 moramo setovati i sve bite u P1IE registru(port 1 interrupt enable), t.j. u C kodu naredbom P1IE=0xFF; odnosno u asembleru bis.b #0xFF,P1IE.

Po dovođenju napajanja bit GIE i prekidni bitovi periferija(u najvećem broju slučajeva) su 0, odnosno prekidi su onemogućeni.

Za periferije se često koristi jedna prekidna rutina, međutim ukoliko su one kompleksnije, mogu imati više različitih vrsta prekida. Na primer, završenom konverzijom i upisom u bilo koji od šesnaest registara A/D konvertora, inicira se prekidna rutina. U koji je od šestaest registara tačno upisana vrednost mora se proveriti u samoj prekidnoj rutini. U sledećem kodu izvršava se očitavanje konvertovane vrednosti iz jednog od tri baferska registra ADC12MEMx A/D konvertora u koji je upisom nove konvertovane vrednosti inicirana prekidna rutina. Podatak koji je baferski registar inicirao prekidnu rutinu se čuva u registru ADC12IV A/D konvertora.

#include "msp430x44x.h" #pragma vector=ADC12_VECTOR // prekidna rutina A/D konvertora__interrupt void adc12_prekidna_rutina(void){

extern unsigned int kanal; if (ADC12IV==0x006) { kanal=ADC12MEM0; }

if (ADC12IV==0x008) { kanal=ADC12MEM1; }

if (ADC12IV==0x0A)

Page 13: Diplomski+rad+Marko+Atanasievski+

{ kanal=ADC12MEM2; }

}

Kod 2.3 Prekidna rutina A/D konvertora sa utvrđivanjem prekidnog izvora

Takođe, prekidni flegovi se negde brišu automatski, kao u prethodnoj rutini očitavanjem registra, ili u slučaju drugih periferija nekom drugom radnjom, dok se na primer kod obrade prekidnih zahteva pristiglih sa portova P1 i P2 prekidni flagovi moraju izbrisati ručno, u protivnom će se stalno iznova izvršavati prekidna rutina. Da li se ručno ili ne brišu prekidni flegovi naravno zavisi od toga koja je periferija u pitanju i na to se mora obratiti pažnja.

#include "msp430x44x.h" #pragma vector=PORT1_VECTOR // Prekidna rutina porta 1__interrupt void port1_int_rutina(void)

{... if ((P1IFG&0x10)==0x10) // da li je stigao prekidni zahtev na sa pina P1.4?

{//reakcija na pritisnuto dugme }

...

...

P1IFG=P1IFG&0xEF; // isključuje prekidni fleg za pin P1.4 na kraju rutine}

Kod 2.4 Prekidna rutina za pin P1.4 porta P1 sa brisanjem prekidnog flega.

Prekidne rutine je često zgodno pisati u asembleru, pogotovu kada su vremenski kritične. Pri tome se posebno mora voditi računa o čuvanju registara opšte namene koji se koriste u prekidnoj rutini zato što se to ne vrši automatski. Takođe, mora se ručno upisati u vektorsku adresu prekida adresa početka prekidne rutine.

Primer prekidne rutine u koju se ulazi kada se pojavi prekidni zahtev na nekom od pinova porta P1 je prikazan sledećim kodom.

#include "msp430x44x.h"

NAME PORT1_ISRPUBLIC port1_isrRSEG CODE

port1_isr ;labela, ovde pocinje izvršavanje prekidne rutine

push R6 push R7 push R8 push R9

Page 14: Diplomski+rad+Marko+Atanasievski+

;ovde ide kod prekidne rutine

bic.b #0xFF,&P1IFG ;brišu se prekidni flegovi porta P1 pop R9 pop R8 pop R7 pop R6reti

COMMON INTVEC(1) ;prekidni vektoriORG PORT1_VECTORDW port1_isrEND

Kod 2.5 Prekidna rutina za port P1 pisana u asembleru

U datasheetu za mikrokontroler [1], u opisu svake periferije postoji i poglavlje koje se bavi njenim prekidnim zahtevima tako da pre pisanja prekidnih rutina treba pročitati relevantne sadržaje.

Page 15: Diplomski+rad+Marko+Atanasievski+

3. Tajmeri A i B

MSP430F449 poseduje dva šesnaestobitna tajmera, A i B [1]. Ovi tajmeri mogu imati različite izvore takta, imaju četiri različita moda rada, i poseduju više capture/compare registara. Pri tom svaki capture/compare registar ima svoj konfigurabilni izlaz.

U ovom poglavlju je prikazano nekoliko najčešćih načina korišćenja tajmera A i B. Osim nekih egzotičnih dodatnih opcija tajmera B, ova dva tajmera su identična.

Ovi tajmeri poseduju velike mogućnosti za generisanje prekida.

3.1 Generisanje prekida pomoću tajmera B

Ukoliko je u sistemu potrebno da se neka radnja izvršava u tačno određenim vremenskim intervalima, za to se koristi compare mod, i tajmer se podešava da radi u Up brojačkom režimu, kao što je prikazano na slici 3.1. (dalji tekst se konkretno odnosi na tajmer B).

U registar TBCCR0 se upisuje gornja granica brojanja posle koje se brojač resetuje na nulu. U ostale registre TBCCR1, TBCCR2, ... se upisuju vrenemski trenuci kada treba da se desi neki događaj. Pri poklapanju vrednosti brojača sa TBCCR1, TBCCR2, ... setovaće se prekidni fleg TBCCR1 CCIFG,

TBCCR2 CCIFG, ... odnosno generisaće se prekidni zahtev. U vektorskoj tabeli prekida postoje dva vektora koja se odnose na tajmer B, a to su TIMERB0_VECTOR na adresi FFFAh, koji se odnosi na rutinu koja obrađuje prekidni zahtev tajmera B TBCCR0 CCIFG, i drugi TIMERB1_VECTOR na adresi FFF8h, za prekidnu rutinu u koju se ulazi setovanjem TBIFG, TBCCR1 CCIFG, TBCCR2 CCIFG,TBCCR3 CCIFG... bita.

Recimo da želimo da se u sistemu svakih 10 milisekundi povećava vrednost promenljive pom za jedan. Zarad uštede i lakšeg manipulisanja bitima inicijalizaciju ćemo uraditi u asembleru, a glavni program ćemo napisati u C-u. To ćemo postići na sledeći način:U IAR IDE razvojnom okruženju ćemo otvorićemo novi C projekat.

3.1 Tajmer u UP modu brojanja.

Slika 3.2 Tajmer B generisanje prekida pomoću TBCCR2.

Page 16: Diplomski+rad+Marko+Atanasievski+

Zatim ćemo otvoriti novi fajl, snimiti ga pod imenom inicijalizacija.s43, uključićemo ga u projekat(opcija Project -> Add Files) i u ovom asemblerskom fajlu ćemo inicijalizovati tajmer B. Fajl inicijalizacija će izgledati na sledeći način:

#include "msp430x44x.h"

NAME inicijalizacija ;modul za inicijalizaciju mikrokontrolera PUBLIC inicijalizacija

RSEG CODE

inicijalizacija: dint ;zabranjujemo prekide mov.w #WDTPW+WDTHOLD,&WDTCTL ; Zaustavlja se WDT

//SetupTB mov.w #TBSSEL_1+MC_1,&TBCTL ; ACLK, UP mode bis.w #CCIE,&TBCCTL2 ; dozvoljeni prekid za tajmerB CCR2 mov.w #0x147,&TBCCR0 ; inicijalizacija TBCCR0 registra mov.w #0x0A3,&TBCCR2 ; inicijalizacija TBCCR2 registra

eint ret END

Kod 3.1 Asemblerska rutina za inicijalizaciju mikrokontrolera za korišćenje tajmera B

Tajmer B se taktuje od strane eksternog oscilatora na 32768 Hz. Uzeli smo da je period brojanja posle koga se tajmer resetuje na nulu traje 327 taktova(jedan takt je i kad je brojač na nuli), dok se na polovini tog ciklusa brojanja javlja prekidni zahtev, kada se vrdnost brojačkog registra tajmera TBR poklopi sa vrednošću u TBCCR2 registru.

Prekidnu rutinu cemo napisati u fajlu gde je i main rutina. Glavni fajl projekta bi trebalo da izgleda sledeće:

#include "msp430x44x.h"

void inicijalizacija(void); //deklaracija rutine za inicijalizaciju

int pom=0; //globalna promenljiva koju treba da se inkrementira svakih 10 ms.

int main( void ){

inicijalizacija();while (1){} // sistem se stavlja u stanje cekanja na prekid return 0;

}

#pragma vector=TIMERB1_VECTOR__interrupt void tb_isr()

Page 17: Diplomski+rad+Marko+Atanasievski+

{

if (TBIV==0x04) // zakljucuje se iz TBIV da li je u pitanju TACCR2 CCIFG{ pom++;}

}

Kod 3.2 Glavni program sa prekidnom rutinom tajmera B.

Na približno svakih 10 milisekundi program će ući u prekidnu rutinu tajmera B i inkrementirati promenljivu pom za jedan. U IAR IDE okruženju pri simulaciji rada programa na mikrokontroleru prekidi zahtevi se podešavaju opcijom u meniju Simulator->Interrupt setup. U simulaciji ne postoje periferije, tako da tajmer B ne postoji i ne broji, ali se generiše prekidni zahtev TBCCR2 CCIFG. Iz toga proizilazi, takođe, da se registar TBIV mora ručno u toku debagovanja promeniti na 4h da bi se prekidna rutina pravilno izvršila.

3.2 Korišćenje compare moda tajmera B za generisanje PWM izlaza

Sledeća vrlo korisna osobina tajmera su konfigurabilni OUT izlazi. Na njima se može dobiti proizvoljan PWM signal odnosno takt. Ovaj signal se može voditi do drugih periferija u mikrokontroleru ili proslediti na izlazne pinove mikrokontrolera.

Slika 3.3 Podešavanje softverske simulacije prekida i IAR okruženju.

Page 18: Diplomski+rad+Marko+Atanasievski+

Na primeru je prikazan programčić koji u različitim trenucima pali LED diode koje su povezane na pinove P3.4 do P3.7 na razvojnoj ploči. Selektovanjem alternativne funkcije za ove pinove u registru P3SEL izlazi tajmera B se vode direktvno na ove pinove.

Fajl za inicijalizaciju:

#include "msp430x44x.h"

NAME inicijalizacija ;modul za inicijalizaciju mikrokontrolera PUBLIC inicijalizacija

RSEG CODE

inicijalizacija: dint mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT //SetupTB

Slika 3.4 Tajmer B out izlaz u SET/RESET modu.

Slika 3.5 Eksterni pinovi tajmera B na koje su povezane LED diode.

Page 19: Diplomski+rad+Marko+Atanasievski+

bis.b #0xF0,&P3DIR // stavlja output smer za P3.4 do P3.7 za PWM TB3 do TB6 bis.b #0xF0,&P3SEL // stavlja output smer za P3.4 do P3.7 za PWM

mov.w #TBSSEL_1+MC_1,&TBCTL ; ACLK, UP mode bis.w #OUTMOD_3,&TBCCTL1 ; set/reset mod za tajmerB CCR1 bis.w #OUTMOD_3,&TBCCTL3 ; set/reset mod za tajmerB CCR3 bis.w #OUTMOD_3,&TBCCTL4 ; set/reset mod za tajmerB CCR4 bis.w #OUTMOD_3,&TBCCTL5 ; set/reset mod za tajmerB CCR5 bis.w #OUTMOD_3,&TBCCTL6 ; set/reset mod za tajmerB CCR6 mov.w #0xFF0F,&TBCCR0 ; inicijalizacija TBCCR0 registra mov.w #0x6D6,&TBCCR1 ; inicijalizacija TBCCR1 registra mov.w #0x2000,&TBCCR3 ; inicijalizacija TBCCR3 registra mov.w #0x5000,&TBCCR4 ; inicijalizacija TBCCR4 registra mov.w #0x8000,&TBCCR5 ; inicijalizacija TBCCR5 registra mov.w #0xC000,&TBCCR6 ; inicijalizacija TBCCR6 registra eint ret END

Kod 3.3 Inicijalizacija tajmera B i njegovih izlaza na pinovima porta P3

Glavni program samo stavlja mikrokontroler u petlju, t.j. stanje čekanja. Tamer B će pritom nezavisno, ravnomerno da menja OUT3 do OUT6 signale, t.j. izlaze na pinovima P3.4 do P3.7. Glavni program:

#include "msp430x44x.h"

void inicijalizacija(void); //deklaracija rutine za inicijalizaciju

int main( void ){

inicijalizacija();

while (1){ } // sistem se stavlja u stanje cekanja return 0;}

Kod 3.4 Main rutina u u programu za paljenje LED dioda PWM izlazima tajmera B.

3.3 Korišćenje capture moda tajmera A

U nekim slučajevima potrebno je odrediti trenutak kada se neki događaj desio, ili vremensku razliku između dva događaja. Sledeći program demonstrira upotrebu TA0 ulaza (alternativna funkcija porta P1.1) tajmera A na koji je povezan PWM temperaturni senzor. Uzlazna ili silazna ivica prisutna na portu P1.1 će inicirati ulazak u prekidnu rutinu i očitavanje trenutnog stanja brojača.

Page 20: Diplomski+rad+Marko+Atanasievski+

Po uključenju napajanja takt procesora je 1 Mhz. Tajmeru A je sproveden SMCLK takt iz DCO petlje. Znači da tajmer A odbroji jedanput za jednu mikrosekundu.

Inicijalizaciona rutina izgleda na sledeći način:

#include "msp430x44x.h"

NAME inicijalizacija ;modul za inicijalizaciju mikrokontrolera PUBLIC inicijalizacija RSEG CODE

inicijalizacija: dint mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT

//SetupTA mov.w #TASSEL_2+MC_2,&TACTL ; SMCLK, kontinualni mod bis.w #CCIE+CM_3+SCS+CAP+CCIS0,&TACCTL0 ; // capture za CCR0, na obe ulaznu i

//silaznu ivicu, sa P1.1 porta bis.b #0x02,&P1SEL ; funkcija za TA0 na portu P1.1 bic.b #0x02,&P1DIR ; P1.1 je ulazni port eint ret END

Kod 3.5 Rutina za inicijalizaciju tajmera A za rad u capture režimu.

Glavni program posle inicijalizacije ide u stanje čekanja, dok tajmer A reaguje na svaku promenu signala na ulazu, i izvršava se prekidna rutina, koja izračunava broj taktova protekao između dva prekidna signala.

#include "msp430x44x.h"

void inicijalizacija(void); //deklaracija rutine za inicijalizaciju

long int vreme_dogadjaja=0;long int prosli_dogadjaj=0;long int razlika=0;

int main( void ){

inicijalizacija(); while (1) {} //mikrokontroler ide u stanje cekanja

}

#pragma vector=TIMERA0_VECTOR__interrupt void ta_isr()

Page 21: Diplomski+rad+Marko+Atanasievski+

{

vreme_dogadjaja=TACCR0; //ocitava se vrednost brojacah tajmera u trenutku //događaja koji je aktivirao capture

if (vreme_dogadjaja>prosli_dogadjaj) //posle FFFFh brojac se vraca na nulu, pa se to mora // uzeti u obzir razlika = vreme_dogadjaja-prosli_dogadjaj; else razlika = 0xFFFF+vreme_dogadjaja-prosli_dogadjaj; prosli_dogadjaj=vreme_dogadjaja;

}

Kod 3.6 Glavni program i prekidna rutina pri capture režimu korišćenja Tajmera A, u kojoj se izračunava broj taktova protekao između dva prekidna zahteva

Page 22: Diplomski+rad+Marko+Atanasievski+

4. A/D konvertor

Mikrokontoler MSP430F449 poseduje vrlo fleksibilan dvanaestobitni A/D konvertor [1], maksimalne brzine odabiranja 200 ksps. Šema povezivavanja analognih ulaza je prikazana na slici 4.1.

Konektori za dovođenje spoljašnjih analognih signala su raspoloživi na ploči. Na laboratorijskim vežbama kao simulacija analognih ulaza se koriste četiri potenciometra(koji su u središnjoj poziciji neutralni, ukoliko se dovodi eksterni na analogni ulaze razvojne ploče).

A/D konvertor ima raznovrsne opcije, detaljno opisane u dokumentaciji [1]. U daljem tekstu je dato softversko rešenje za najčešću primenu A/D konvertora. A/D

konvertor u ravnomernim vremenskim razmacija uzima uzorak i u prekidnoj rutini se vrši njegova obrada. Promenljiva rezultat u procentima prikazuje vrednost napona na analognom ulazu(0% za 0V, 100% za 3.3 V).

Slika 4.1 Šema vezivanja eksternih analognih ulaza sa mikrokontrolerom

Page 23: Diplomski+rad+Marko+Atanasievski+

A/D konvertor ćemo inicijalizovati da radi u repeat-single-channel režimu što znači da će svaki put rezultat biti upisan u isti ADC12MEM registar (u ovom slučaju registar ADC12MEM0). A/D konverzija će biti inicirana od strane OUT1 izlaza tajmera B, koji treba podesiti da radi u set/reset modu sa željenom učestanošću, kako je opisano u prethodnom poglavlju.

Inicijalizaciona rutina će izlgedati na sledeći način:

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

NAME inicijalizacija ;modul za inicijalizaciju mikrokontrolera PUBLIC inicijalizacija RSEG CODEinicijalizacija: dint mov.w #WDTPW+WDTHOLD,&WDTCTL // Stop WDT

// AD convertor

bis.b #AD_KANAL1PIN,&PADSEL // selektuje alternativnu funkciju za pin P6.4 (t.j. ulaz //AD konvertora)

bis.w #SHT0_1+REFON+REF2_5V+ADC12ON,&ADC12CTL0 bis.w #ADC12SSEL0+SHP+SHS_3+CONSEQ_2,&ADC12CTL1 //ack, Repeat-single- //channel, Timer_B.OUT1 ga taktuje, Pulse Sample Mode

bis.b #INCH_4,&ADC12MCTL0 // rezultat sa kanala A4, t.j. ANALOG1 se upisuje u //ADC12MEM0 bis.w #0x01,&ADC12IE //dozvoljen interupt za ADC12MEM0 registar

bis.w #ENC,&ADC12CTL0 // dozvoljena konverzija

//SetupTB, inicira konverziju svakih 100 ms mov.w #TBSSEL_1+MC_1,&TBCTL // ACLK, UP mode bis.w #OUTMOD_3,&TBCCTL1 // set/reset mod za tajmerB CCR1 mov.w #0xDAC,&TBCCR0 //inicijalizacija TBCCR0 registra mov.w #0x6D6,&TBCCR1 // inicijalizacija TBCCR1 registra

eint ret END

Kod 4.1 Inicijalizaciona rutina A/D konvertora za rad u repeat signe channel modu

Pravila lepog programiranja nalažu da se u radu sa sistemom, radi kasnijeg lakšeg održavanja ili prelaska na drugi srodan sistem, u radu sa portovima, memorijskim adresama, registrima itd. koriste simbolička imena kojima se u posebnom .h fajlu dodeljuju konkretne

Page 24: Diplomski+rad+Marko+Atanasievski+

adrese. Zato ćemo napisati razvojna_plocaMSP430.h fajl koji se odnosi na našu razvojnu ploču i tu ćemo definisati simboličke oznake za rad sa periferijama. Ceo fajl je dat u prilogu. Deo ovog fajla za rad sa A/D konvertorom će izgledati sledeće:

/************************************************************* A/D/************************************************************/

#define AD_KANAL1PIN (0x0010)#define AD_KANAL2PIN (0x0020)#define AD_KANAL3PIN (0x0040)#define AD_KANAL4PIN (0x0080)

#define PADIN_ (0x0034) /* AD Port 6 Input */READ_ONLY DEFC( PADIN , PADIN_)#define PADOUT_ (0x0035) /* AD Port 6 Output */DEFC( PADOUT , PADOUT_)#define PADDIR_ (0x0036) /* AD Port 6 Direction */DEFC( PADDIR , PADDIR_)#define PADSEL_ (0x0037) /* AD Port 6 Selection */DEFC( PADSEL , PADSEL_)

Kod 4.2 Definicije simboličkih imena korišćenih u radu sa A/D konvertorom

Kada u kodu naiđemo na neku simboličku oznaku, da bismo skočili na njenu definiciju, t.j. videli njenu vrednost dovoljno je da izaberemo opciju prikazanu na slici 4.2.

Glavni program, a takođe i prekidna rutina, su dati u nastavku:

#include "msp430x44x.h" void inicijalizacija(void); //deklaracija rutine za inicijalizacijulong int rezultat=0;

Slika 4.2 Skok na definiciju simboličke oznake

Page 25: Diplomski+rad+Marko+Atanasievski+

int main( void ){

inicijalizacija();while (1){} // sistem se stavlja u stanje cekanja na prekid

}

#pragma vector=ADC12_VECTOR__interrupt void adc12_prekidna_rutina(void){

if (ADC12IV==0x006) { rezultat=ADC12MEM0; //procitaj rezultat konverzije rezultat=rezultat*100/4095; //izraci rezultat konverzije u procentima punog opsega }

}

Kod 4.3 Glavni program i prekidna rutina za A/D konvertor u repeat-single-channel režimu

Ukoliko je potrebni uzimati uzorke sa nekoliko kanala, koristimo repeat-sequence-of-channels mod. Po konverziji vrednosti sa ANALOG1 kanala i upisa u ADC12MEM0, sledeći put kada tajmer B bude startovao konverziju vrednost sa kanala ANALOG2 će biti upisana u ADC12MEM1, treći put sa ANALOG3 u ADC12MEM2 i tako u krug.

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

NAME inicijalizacija ;modul za inicijalizaciju mikrokontrolera PUBLIC inicijalizacija RSEG CODE

inicijalizacija: dint mov.w #WDTPW+WDTHOLD,&WDTCTL // Stop WDT

// AD convertor

bis.b #AD_KANAL1PIN+AD_KANAL2PIN+AD_KANAL3PIN,&PADSEL //P6.4 P6.5 P6.6// ADC12 function

bis.w #SHT0_1+REFON+REF2_5V+ADC12ON,&ADC12CTL0 // 2.5 volti, sampling // period 8 taktova

bis.w #ADC12SSEL0+SHP+SHS_3+CONSEQ_3,&ADC12CTL1 //ack, Repeated-sequence of //channels, Timer_B.OUT1 ga taktuje, Pulse Sample Mode

bis.b #INCH_4,&ADC12MCTL0 // selektovan kanal A4 bis.b #INCH_5,&ADC12MCTL1 // selektovan kanal A5 bis.b #INCH_6+EOS,&ADC12MCTL2 // selektovan kanal A6 i kraj sekvence bis.w #0x07,&ADC12IE //dozvoljen interupt za

// ADC12MEM0,ADC12MEM1,ADC12MEM2 registre bis.w #ENC,&ADC12CTL0 //dozvoljena konverzija, A/D se stavlja u pogon

//SetupTB

Page 26: Diplomski+rad+Marko+Atanasievski+

mov.w #TBSSEL_1+MC_1,&TBCTL // ACLK, UP mode bis.w #OUTMOD_3,&TBCCTL1 // set/reset mod za tajmerB CCR1 mov.w #0xDAC,&TBCCR0 //inicijalizacija TBCCR0 registra mov.w #0x6D6,&TBCCR1 // inicijalizacija TBCCR1 registra

eint ret END

Kod 4.4 Inicijalizacija A/D konvertora za repeat-sequence-of-channels režim

Rezultat A/D konverzije sa kanala je raspoloživ u globalnim promenljivama rezultat_analog1, rezultat_analog2 i rezultat_analog3.

#include "msp430x44x.h" void inicijalizacija(void); //deklaracija rutine za inicijalizacijuunsigned long int rezultat_analog1=0;unsigned long int rezultat_analog2=0;unsigned long int rezultat_analog3=0;int main( void ){inicijalizacija();

while (1){ // sistem se stavlja u stanje cekanja na prekid }}

#pragma vector=ADC12_VECTOR__interrupt void adc12_prekidna_rutina(void){ unsigned long int kanal=0; //pomocna promenljiva if (ADC12IV==0x006) { kanal=ADC12MEM0; kanal=kanal*100/4095; rezultat_analog1=kanal; }

if (ADC12IV==0x008) { kanal=ADC12MEM1; kanal=kanal*100/4095; rezultat_analog2=kanal; }

if (ADC12IV==0x0A) { kanal=ADC12MEM2; kanal=kanal*100/4095; rezultat_analog3=kanal; }

Page 27: Diplomski+rad+Marko+Atanasievski+

}

Kod 4.5 Glavni program i prekidna rutina za A/D konvertor u repeat-sequence-of-channels režimu

Page 28: Diplomski+rad+Marko+Atanasievski+

5. Tasteri

Razvojna ploča sa MSP430F449 mikrokontrolerom poseduje četiri tastera opšte namene [8]. Tasteri S2, S3 i S4 su vezani na pinove porta P1 dok je dugme S1 vezano na pin P6.3, kao što je prikazano na slici 5.1. Pritisak tastera vezanih na port P1 se može obrađivati u prekidnoj rutini, dok je jedini način za opsluživanje tastera S1 poliranje u beskonačnoj petlji.

U nastavku je urađen primer programa u kome se u asemblerskoj prekidnoj rutini obrađuje pritisak na tastere S2, S3 i S4 dok se u glavnom programu u beskonačnoj while petlji polira taster S1. U promenljivu pritisnuto_dugme se kao obrada događaja pritiska na dugme smešta broj pritisnutog dugmeta.

Inicijalizacija mikrokontrolera za rad sa tasterima izgleda kao u nastavku:

Slika 5.1 Raspored vezivanja tastera S1 do S4 na mikrokontroler

Page 29: Diplomski+rad+Marko+Atanasievski+

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

NAME inicijalizacija ;modul za inicijalizaciju mikrokontrolera PUBLIC inicijalizacija RSEG CODE

inicijalizacija: dint mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT

///S4 i S3 i S2 dugmici bis.b #TASTS4PIN+TASTS3PIN+TASTS2PIN,&PTAST234IES //prekidi za

//dugmad se ukljucuju na silaznu ivicu bis.b #TASTS4PIN+TASTS3PI+TASTS2PIN,&PTAST234IE //dozvoljeni prekidi za

//dugmad

eint ret END

Kod 5.1 Inicijalizacija mikrokontrolera za rad sa tasterima

Linije sa tasterima su pull-up otpornikom vezane za napon napajanja, i po pritisku tastera signal na ulaznim portovima se spušta na nulu. Prekidna rutina se iz tog razloga mora aktivirati na silaznu ivicu, što se postiže setovanjem bita u P1IES registru.

Po pritisku tastera izvršavanje programa ulazi u prekidnu rutinu, gde se prvo ustanovljava za koje dugme je aktiviran prekidni fleg. Pritisak dugmeta se zatim softverski debaunsira, prolaskom dovoljan broj puta kroz petlju i stalnim očitavanjem signala sa ulaznog pina na koji je vezan taster. Ukoliko je kratkotrajni glič u pitanju, promena signala na portu za vreme vrtenja programa u rutini će se ustanoviti i preskočiće se izvršavanje funkcije dugmeta.

;Debaunsiranje dugmeta, da se vidi da li je lepo pritisnuto;****************************************************************************** mov.b PTAST234IN,R9 and.b #TASTS3PIN,R9 mov #0x00,R12 mov #0x00,R11 mov #0x00,R10 //brojac petlje petljaS3 mov.b PTAST234IN,R11 ;u R11 se smešta novo stanje na pinu and.b #TASTS3PIN,R11 mov.b R11,R12 ; u R12 se privremeno čuva novo stanje na pinu bis.b R11,R9 ; R11 or R9 -> R9 jnz ganckraj ; kraj, ukoliko je poskakivanje napona izazvalo prekidnu rutinu mov.b R12,R9 ; u R9 se čuva staro stanje pina, kad je pritisnuto dugme jednako nuli inc R10

Page 30: Diplomski+rad+Marko+Atanasievski+

cmp #0xFE,R10 ; dovoljan broj puta prolazi kroz ovu rutinu jeq funkcijaS3 jmp petljaS3

Kod 5.2 Softversko debaunsiranje tastera u asembleru

Po uspešnom prolasku debaunsiranja, izvršava se funkcija dugmeta. U našem slučaju u globalnu promenljivu definisanu u glavnom programu ćemo upisati redni broj tastera koji je pritisnut t.j. mov #3,&pritisnuto_dugme kao funkciju eksternog tastera S3.

Po završetku funkcije neophodno je neutralisati prekidne flegove u P1IFG registru. bic.b #TASTS3PIN,&PTAST234IFGProkidna rutina je ovim završena i restauriraju se sa steka svi registri i izlazi se iz

prekidne rutine.Kompletna prekidna rutina za eksterne tastere S2, S3 i S4 izgleda sledeće:

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

NAME PORT1_ISREXTERN pritisnuto_dugmeRSEG CODE

dugmad_isr push R6 push R7 push R8 push R9 push R10 push R11 push R12

;******************************************************************************** ; Prekidna rutina za drugo eksterno dugme S2;********************************************************************************;********************************************************************************

bit.b #TASTS2PIN,&PTAST234IFG ; Da li se aktivirao prekidni zahtev za dugme S2 jz daljeS4 ;Debaunsiranje pritiska tastera S2, da se vidi da li je pritisnuto ili je u pitanju glic;******************************************************************************

mov.b PTAST234IN,R9 and.b #TASTS2PIN,R9 mov #0x00,R12 mov #0x00,R11 mov #0x00,R10

petljaS2 mov.b PTAST234IN,R11

Page 31: Diplomski+rad+Marko+Atanasievski+

and.b #TASTS2PIN,R11 mov.b R11,R12 bis.b R11,R9 jnz daljeS4 ; kraj, ukoliko je poskakivanje napona izazvalo prekidnu rutinu mov.b R12,R9 inc R10 cmp #0xFE,R10 ; dovoljan broj puta prolazi kroz ovu rutinu jeq funkcijaS2 jmp petljaS2 ;Funkcija dugmeta S2;****************************************************************************** funkcijaS2

mov #2,&pritisnuto_dugme

funkcijaS2_kraj bic.b #TASTS2PIN,&PTAST234IFG jmp ganckraj;******************************************************************************

;******************************************************************************* ; Prekidna rutina za cetvrto eksterno dugme S4;*******************************************************************************

daljeS4 bit.b #TASTS4PIN,&PTAST234IFG ; Da li se aktivirao prekidni zahtev za dugme S4 jz daljeS3 ;Debaunsiranje pritiska tastera S4, da se vidi da li je pritisnuto ili je u pitanju glic;****************************************************************************** mov.b PTAST234IN,R9 and.b #TASTS4PIN,R9 mov #0x00,R12 mov #0x00,R11 mov #0x00,R10 petljaS4 mov.b PTAST234IN,R11 and.b #TASTS4PIN,R11 mov.b R11,R12 bis.b R11,R9 jnz daljeS3 ; kraj, ukoliko je poskakivanje napona izazvalo prekidnu rutinu mov.b R12,R9 inc R10 cmp #0xFE,R10 ; dovoljan broj puta prolazi kroz ovu rutinu jeq funkcijaS4 jmp petljaS4

;Funkcija dugmeta S4;****************************************************************************** funkcijaS4

mov #4,&pritisnuto_dugme

Page 32: Diplomski+rad+Marko+Atanasievski+

funkcijaS4_kraj bic.b #TASTS4PIN,&PTAST234IFG jmp ganckraj;******************************************************************************

;*******************************************************************************; Prekidna rutina za trece eksterno dugme S3;*******************************************************************************

daljeS3 bit.b #TASTS3PIN,&PTAST234IFG ; Da li se aktivirao prekidni zahtev za dugme S3 jz ganckraj ;Debaunsiranje pritiska tastera S3, da se vidi da li je pritisnuto ili je u pitanju glic;****************************************************************************** mov.b PTAST234IN,R9 and.b #TASTS3PIN,R9 mov #0x00,R12 mov #0x00,R11 mov #0x00,R10 petljaS3 mov.b PTAST234IN,R11 and.b #TASTS3PIN,R11 mov.b R11,R12 bis.b R11,R9 jnz ganckraj ; kraj, ukoliko je poskakivanje napona izazvalo prekidnu rutinu mov.b R12,R9 inc R10 cmp #0xFE,R10 ; dovoljan broj puta prolazi kroz ovu rutinu jeq funkcijaS3 jmp petljaS3 ;Funkcija dugmeta S3;****************************************************************************** funkcijaS3

mov #3,&pritisnuto_dugme

funkcijaS3_kraj bic.b #TASTS3PIN,&PTAST234IFG jmp ganckraj;****************************************************************************** ganckraj

bic.b #TASTS4PIN+TASTS3PIN+TASTS2PIN,&PTAST234IFG // ako je glic aktivirao rutinu i ne //prodje proveru debounsinga, skida za svaki slučaj prekidne flegove

pop R12 pop R11

Page 33: Diplomski+rad+Marko+Atanasievski+

pop R10 pop R9 pop R8 pop R7 pop R6

reti

;==========================================================================COMMON INTVEC(1) ; Interrupt vectors;==========================================================================

ORG PORT1_VECTORDW dugmad_isr

END

Kod 5.3 Prekidna rutina za tastere S2, S3 i S4

Glavni program posle inicijalizacije ulazi u beskonačnu petlju u kojoj polira pin P6.3. Ukoliko se uoči promena stanja izvršava se funkcija dugmeta S1.

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

void inicijalizacija(void); //deklaracija rutine za inicijalizacijuint pritisnuto_dugme=0; //cuva podatak koje je dugme poslednje pritisnutoint main( void ){inicijalizacija();while (1) { //u nastavku sledi petlja koja ispituje da li je pritisnuto dugme S1 unsigned int pauz=0; int novo=TASTS1PIN; int staro=TASTS1PIN; while (3<5)

{ novo=PTAST1IN; //ocitavalje stanja porta P6.3 novo&=TASTS1PIN; staro=~staro; staro=staro & novo; if (staro){ //ovde izvrsava funkcija dugmeta S1 pritisnuto_dugme=1; for (pauz=0;pauz<50000;pauz++){} // cekanje } staro=novo; }

}

}

Kod 5.4 Glavni program, petlja za poliranje dugmeta S1

Page 34: Diplomski+rad+Marko+Atanasievski+

6. PWM izlazi

Razvojna ploča sa MSP430F449 mikrokontrolerom poseduje četiri linije koje mogu da se koriste kao PWM izlazi [1]. Pinovi mikrokontrolera koji izlaze na ove linije imaju kao alternativnu funkciju izlaze OUT3 do OUT6 tajmera B, što omogućava veliku fleksibilnost u radu sa PWM signalima.

Kao demonstraciju rada sa PWM signalima, napisaćemo sledeći program. Napravićemo tabelu, koja se smešta u fleš memoriju kontrolera, sa uzastopnim vrednostima od nule do nekog broja (1275, t.j. FFh*5), a zatim opet do nule. Vrednosti iz tabele simuliraju testerastu funkciju. Tim vrednostima ćemo modulisati PWM signal što će biti vidljivo na LED diodama. Vrednosti iz tabele ćemo smeštati u compare registre tajmera B, koji će generisati signal na linijama.

Kao još jednu slobodnu opciju ubacićemo promenljivu faktor, vrednosti od 0 do 10, koja će se izračunavati na osnovu analognog ulaza, i koja će određivati brzinu kojom se odvija modulacija, t.j frekfrenciju testeraste funkcije.

Slika 6.1 Šema veza PWM linija sa LED diodama i eksternim konektorom

Page 35: Diplomski+rad+Marko+Atanasievski+

Za početak ćemo inicijalizovati sve potrebne periferije.Tajmer A koristimo za taktovanje A/D konvertora.Izlazi OUT3 do OUT6 tajmera B daju PWM signal, dok po vraćanju tajmera B na nulu,

posle odbrojanog ciklusa, t.j. kada se vrednost tajmera B poklopi sa vrednošću registra TBCCR0, generiše se TBIFG prekid. U prekidnoj rutini za ovaj prekid čitamo vrednosti iz tabele i upisujemo ih u TBCCR3 do TBCCR6 registre.

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

NAME inicijalizacija ;modul za inicijalizaciju mikrokontrolera PUBLIC initialisation RSEG CODE

initialisation: dint mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT

//SetupTA mov.w #TASSEL_1+MC_1,&TACTL ; ACLK, UP mode bis.w #OUTMOD_3,&TACCTL1 ; set/reset mod za tajmerA CCR1 mov.w #0xDAC,&TACCR0 ; inicijalizacija TACCR0 registra mov.w #0x6D6,&TACCR1 ; inicijalizacija TACCR1 registra

// AD convertor

bis.b #AD_KANAL1PIN,&PADSEL ; P6.4 ADC12 function bis.w #SHT0_1+REFON+REF2_5V+ADC12ON,&ADC12CTL0 // 2.5 volti bis.w #ADC12SSEL0+SHP+SHS_1+CONSEQ_2,&ADC12CTL1 //ack, Repeat-single-channel

// Timer_A.OUT1 ga taktuje, Pulse Sample Mode bis.b #INCH_4,&ADC12MCTL0 // selektovan kanal A4 za ADC12MEM0 bis.w #0x01,&ADC12IE //dozvoljen interupt za ADC12MEM0 registar bis.w #ENC,&ADC12CTL0 // startovanje u pogon A/D konvertora

//SetupTB

mov.w #TBSSEL_1+MC_1+TBIE,&TBCTL ; ACLK, UP mode, dozvoljen TBIFG prekid bis.w #OUTMOD_7,&TBCCTL3 ; reset/set mod za tajmerB CCR3 bis.w #OUTMOD_7,&TBCCTL4 ; reset/set mod za tajmerB CCR4 bis.w #OUTMOD_7,&TBCCTL5 ; reset/set mod za tajmerB CCR5 bis.w #OUTMOD_7,&TBCCTL6 ; reset/set mod za tajmerB CCR6 mov.w #0x9FF,&TBCCR0 ; inicijalizacija TBCCR0 registra mov.w #0x400,&TBCCR3 ; inicijalizacija TBCCR3 registra

Page 36: Diplomski+rad+Marko+Atanasievski+

mov.w #0x400,&TBCCR4 ; inicijalizacija TBCCR4 registra mov.w #0x400,&TBCCR5 ; inicijalizacija TBCCR5 registra mov.w #0x400,&TBCCR6 ; inicijalizacija TBCCR6 registra

//PWM izlazi bis.b #PWM1PIN+PWM2PIN+PWM3PIN+PWM4PIN,&PPWMDIR // stavlja output smer za

// P3.4 do P3.7 za PWM TB3 do TB6 bis.b #PWM1PIN+PWM2PIN+PWM3PIN+PWM4PIN,&PPWMSEL // stavlja alternativnu

// funkciju izlaza tajmera B na pinove P3.4 do P3.7

eint ret END

Kod 6.1 Inicijalizacija mikrokontrolera za korišćenje PWM izlaza

Page 37: Diplomski+rad+Marko+Atanasievski+

Tabelu ćemo napraviti koristeći asemblersku direktivu REPT..ENDR [9].Vrednosti od 0 do 1275 u koracima od po 5, a zatim opet od 1275 do 0, formiramo na

sledeći način:

NAME tabela PUBLIC tabela RSEG CODE

tabela ; Generise tabelu sa uzastopnim vrednostimasinvred SET 0 REPT 256 DC16 sinvredsinvred SET sinvred+5 ENDR

sinvred SET 1275 REPT 255 DC16 sinvredsinvred SET sinvred-5

ENDR

END tabela

Kod 6.2 Tabela sa vrednostima koje simuliraju testerastu funkciju

Prethodni kod će u memoriji formirati tabelu prikazanu na slici 6.2, kompajler je smestio tabelu počev od adrese 1292h.

Ukoliko zelimo da koristimo ovu tabelu u C kodu dovoljno je da definišemo eksterni niz integer vrednosti tabela.

extern int tabela[511];

Slika 6.2 Tabela sa vrednostima koje

simuliraju testerastu funkciju

Page 38: Diplomski+rad+Marko+Atanasievski+

Glavni program će posle inicijalizacije ući u beskonačnu petlju, a sva funkcionalnost će se obavljati u prekidnim rutinama. U prekidnoj rutini tajmera A izračunavanje faktora kojim će se množiti sve vrednosti pre upisa u registre tajmera B, a u prekidnoj rutini tajmera B ćemo menjati TBCCRx registre.

#include "msp430x44x.h"

unsigned long int faktor=1; //faktor (od 1 do 10) kojim se mnozi vrednosti u tajmeru B, podesava se analognim ulazom

extern int tabela[511]; //tabela vrednosti, testerasta funkcija, kojom se modulise pwm signal

void initialisation(void);int main( void ){

initialisation();

while (1) {}}

#pragma vector=ADC12_VECTOR__interrupt void adc12_prekidna_rutina(void){ unsigned long int pomocna; if (ADC12IV==0x006) { // procitaj bafer pomocna=ADC12MEM0; pomocna=pomocna*10/4095; faktor=pomocna; //novi faktor u rasponu od 0 do 10 kojim se mnoze vrednosti u tajmeru B TBCCR0=(0xFF*5)*faktor; //nova maksimalna vrednost do koje tajmer B broji }}

#pragma vector=TIMERB1_VECTOR__interrupt void TB_isr() { static unsigned int brojac=0; if (TBIV==0x0E) // zakljucuje iz TBIV da li je u pitanju TBIFG { //TBIFG prekid, cita se vrednost iz tabele i smesta u TBCCR regsitre TBCCR3=tabela[brojac]*faktor; //sledeca vrendost iz tabele pri kojoj se menja TB3 OUT izlaz TBCCR4=tabela[brojac]*faktor; //sledeca vrendost iz tabele pri kojoj se menja TB4 OUT izlaz TBCCR5=tabela[brojac]*faktor; //sledeca vrendost iz tabele pri kojoj se menja TB5 OUT izlaz TBCCR6=tabela[brojac]*faktor; //sledeca vrendost iz tabele pri kojoj se menja TB6 OUT izlaz brojac++; if (brojac>=511) brojac=0; //vracamo se na pocetak tabele }

Page 39: Diplomski+rad+Marko+Atanasievski+

}

Kod 6.3 Glavni program i prekidne rutine za generisanje PWM signala modulisanog testerastim signalom proizvoljne frekfrencije

Page 40: Diplomski+rad+Marko+Atanasievski+

7. LED displej

Razvojna ploča sa MSP430F449 mikrokontrolerom poseduje šestocifreni LED displej [8].

Selekcioni signali sel1 do sel6, kojima se selektuje, t.j. uključuje odnosno isključuje pojedinačna cifra led displeja su na pinovima porta P5, a signali SegA do SegG se preko drajvera LED displeja prosleđuju na svaku ćeliju, i visokim logičkim nivoom ovih signala uključuje se pojedinačna ćelija svake cifra. Šema povezivanja signala LED displeja sa mikrokontrolerom je prikazana na slici 7.3. Pinovi za kontrolu LED displeja se naravno moraju konfigurisati kao

izlazni.Budući da LED displej

zahteva relativno visoke vrednosti struje, selekcioni signali i signali SelA do SelG se do LED displeja vode preko pogonskih drajvera. Pri tom se drajver ULN2003A ponaša kao invertor, slika 7.2.

Isti selekcioni signali sel1 do sel6 se koriste i za selekciju na tastaturama T1 i T2, tako da se pri zajedničkom korišćenju tastature i LED displeja mora obratiti posebna pažnja na to.

Slika 7.1 Led displej

Slika 7.2 Drajveri za pogon LED displeja

Page 41: Diplomski+rad+Marko+Atanasievski+

Ispis broja, na primer, na poziciji 1 LED displeja obavlja se visokim naponskim nivoom samo na signalu ssel1, a da je pritom raspored paljenja LED ćelija a do g prisutan na pinovima porta P4, tako što je signal SelX ćelija koje se pale na visokom logičkom nivou.

Slika 7.2 Šema povezivanja mikrokontrolera sa LED displejem

Page 42: Diplomski+rad+Marko+Atanasievski+

Na početku programa pre korišćenja LED displeja neophodno je izvršiti inicijalizaciju.

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

NAME inicijalizacija ;modul za inicijalizaciju LED displeja PUBLIC inicijalizacija RSEG CODE

inicijalizacija: dint mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT // IO portovi

mov.b #SegA+SegB+SegC+SegD+SegE+SegF+SegG,&PSegDIR // stavlja output smer za P4.1 do P4.7, SegA do SegG signale mov.b #ssel1+ssel2+ssel3+ssel4+ssel5+ssel6,&PsselDIR // stavlja output smer za P5.1 do P5.7, ssel1 do ssel6 signale eint ret END

Kod 7.1 Inicijalizacija mikrokontrolera za korišćenje LED displeja

U fajlu razvojna_plocaMSP430.h definisaćemo simboličke oznake za ssel i SegX signale u skladu sa rasporedom na pinovima portova P4 i P5, radi lakšeg i preglednijeg pisanja koda za upotrebu LED displeja.

#define ssel1 (0x0080)#define ssel2 (0x0040)#define ssel3 (0x0020)#define ssel4 (0x0010)#define ssel5 (0x0008)#define ssel6 (0x0004)

#define SegA (0x0002)#define SegB (0x0004)#define SegC (0x0008)#define SegD (0x0010)#define SegE (0x0020)#define SegF (0x0040)#define SegG (0x0080)

Kod 7.2 Definicija simnoličkih promenljivi za lakši rad sa LED displejom

Page 43: Diplomski+rad+Marko+Atanasievski+

Registri portova P4 i P5 su takođe radi lakšeg portovanja programa na druge sisteme definisani kao Pseg i Pssel, respektivno.

Sad recimo da želimo da prikažemo broj 0 na mestu druge cifre LED displeja.

//isključujemo sve ssel i Seg signale za slučaj da je neki bio uključenbic.b #ssel1+ssel2+ssel3+ssel4+ssel5+ssel6,&PsselOUT

bic.b #SegA+SegB+SegC+SegD+SegE+SegF,&PSegOUT//uključujemo ćelije koje formiraju cifru 0

bis.b #SegA+SegB+SegC+SegD+SegE+SegF,&PSegOUT//uključujemo ssel2

bis.b #ssel2,&PsselOUT

Kod 7.3 Prikaz broja 0 kao drugu cifru na LED displeju

Da bismo prikazali višecifarski broj moramo vremenski multipleksirati uključivanje cifara LED displeja. Ukoliko se ovo multipleksiranje obavlja dovoljnom brzinom, usled osobine ljudskog oka da integrali svetlosni nadražaj, izgledaće kao da je na LED displeju fiksno ispisan broj.

Page 44: Diplomski+rad+Marko+Atanasievski+

U nastavku je prikazan program koji ispisuje šestocifreni broj na LED displeju. U tu svrhu se koristi prekidna rutina tajmera A. U goreprikazanu rutinu za inicijalizaciju ćemo ubaciti i inicijalizaciju tajmera A.

//SetupTA mov.w #TASSEL_1+MC_1,&TACTL ; ACLK, UP mode

bis.w #CCIE,&TACCTL2 ; omogucava TACCR2 prekidni zahtev mov.w #0x0B0,&TACCR0 ; inicijalizacija TACCR0 registra mov.w #0x008,&TACCR2 ; inicijalizacija TACCR2 registra

Kod 7.4 Inicijalizacija tajmera A

Brzina vremenskog multipleksiranja se lako podešava menjanjem vrednosti registra TACCR0.

Slika 7.3. Vremensko multipleksiranja led displeja

Page 45: Diplomski+rad+Marko+Atanasievski+

Napisaćemo jednu rutinu koja kao ulazni argument prima broj od 0 do 9 a kao izlaz vraća raspored paljenja bita, t.j. Seg linija na PSeg portu (portu P4).

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

NAME led_cifra ;glavni programski modul PUBLIC led_cifra RSEG CODE led_cifra: push R8 // svi korisceni registri se moraju sacuvati na steku push R9 mov R12, R8 // u R8 je broj cifra ciji se ispis zeli mov R8,&MPY // mnozenje u hardverskom mnozacu radi skakanja na kod za

// tu cifru mov #06,&OP2 //naredbe mov i jmp zauzimaju 6 bajtova, pa je //množilac 6 nop //ceka se da hardverski mnozac odradi posao mov &RESLO,R8 // ofset za skok je sada u R8 add R8,PC //skok mov #SegA+SegB+SegC+SegD+SegE+SegF,R9 ;0 jmp kraj mov #SegB+SegC,R9 ;1 jmp kraj mov #SegA+SegB+SegG+SegE+SegD,R9 ;2 jmp kraj mov #SegA+SegB+SegC+SegG+SegD,R9 ;3 jmp kraj mov #SegB+SegC+SegG+SegF,R9 ;4 jmp kraj mov #SegA+SegF+SegG+SegD+SegC,R9 ;5 jmp kraj mov #SegA+SegC+SegD+SegE+SegF+SegG,R9 ;6 jmp kraj mov #SegB+SegC+SegA,R9 ;7 jmp kraj mov #SegA+SegB+SegC+SegD+SegE+SegF+SegG,R9 ;8 jmp kraj mov #SegB+SegC+SegA+SegD+SegF+SegG,R9 ;9 kraj: mov R9,R12 // vracanje rasporeda uključivanja signala SegA..SegG glavnom programu pop R9 pop R8 ret END

Kod 7.5 Funkcija za računanje rasporeda paljenja Seg signala na osnovu broja koji treba ispisati

Page 46: Diplomski+rad+Marko+Atanasievski+

Broj koji se ispisuje na LED displeju je smešten u promenljivoj led_broj. Statička (ne gubi se sadržaj pri izlasku iz rutine) promenljiva cifra čuva podatak koja od šest cifara treba da se ispiše sledeća. Kada se ispiše cifra na mesru 6 LED displeja promenljiva cifra se vraća na 1.

Iz šestocifrenog broja smeštenog u promenljivu led_broj izračunava se cifra koja treba da se ispiše na tekućem mestu i privremeno smešta u promenljivu pom. Ta cifra se šalje rutini led_cifra koja u jednom bajtu vraća raspored koje od signala SegA do SegG porta P4 treba upaliti. Ovaj rezultat se smešta u binar_cifru. Da bi sačuvali tekuće stanje pina P4.0, koje nema funkciju vezanu za LED displej, nameštamo najniži bit promenljive binar_cifra da bude jednak ovome. Stanje portova P5.1 i P5.0 koji takođe nemaju funkciju vezanu za LED displej se takođe čuva, tako što se prilikom dodele nove vrednosti PsselOUT registru bitski množi stari sadržaj sa 3h.Glavni program i prekidna rutina tajmera A su dati u nastavku:

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

extern unsigned int led_cifra(unsigned int cifra); //vraca raspored segmenata Sega do SegG koji treba// da se ukljuce

void inicijalizacija(void); //deklaracija rutine za inicijalizacijuunsigned long int led_broj;

int main( void ){

inicijalizacija();led_broj=854621;

while (1){} // sistem se stavlja u stanje cekanja na prekid }

#pragma vector=TIMERA1_VECTOR__interrupt void ta_isr() { static int cifra=0; // koje mesto na LED displeju ce u ovom prolasku kroz prek. rutinu biti ukljuceno unsigned long int pom=0; // sluzi kao pomocna promenljiva, da bi se izvukla pojedinacna cifra

// iz led_broj-a unsigned int binar_cifra=0; // rasporeded signala SegA do SegG koji se šalje LED displeju if (TAIV==0x04) { // zakljucuje iz TAIV da li je u pitanju TACCR2 CCIFG cifra++; pom=0; switch (cifra) {

case 1: pom=led_broj%10; binar_cifra = led_cifra(pom); PsselOUT |= ssel1; PsselOUT &= ssel1+0x03; break; //ukljucuje LED displej cifru 1

case 2: pom=led_broj/10; pom%=10; binar_cifra = led_cifra(pom); PsselOUT |= ssel2; PsselOUT &= ssel2+0x03; break; //ukljucuje LED displej cifru 2

case 3: pom=led_broj/100; pom%=10; binar_cifra = led_cifra(pom); PsselOUT |= ssel3; PsselOUT &= ssel3+0x03; break; //ukljucuje LED displej cifru 3

case 4: pom=led_broj/1000; pom%=10; binar_cifra = led_cifra(pom); PsselOUT |= ssel4; PsselOUT &= ssel4+0x03; break; //ukljucuje LED displej cifru 4

case 5: pom=led_broj/10000; pom%=10; binar_cifra = led_cifra(pom); PsselOUT |= ssel5;

Page 47: Diplomski+rad+Marko+Atanasievski+

PsselOUT &= ssel5+0x03; break; //ukljucuje LED displej cifru 5 case 6: pom=led_broj/100000; pom%=10; binar_cifra = led_cifra(pom); PsselOUT |= ssel6; PsselOUT &= ssel6+0x03; break; //ukljucuje LED displej cifru 6 default: PsselOUT |= ssel1+ssel2+ssel3+ssel4+ssel5+ssel6; pom=0; binar_cifra = led_cifra(pom); //uključuje sve LED cifre, na kojima ce se // ispisati 0

} PSegOUT = binar_cifra + (PSegOUT&0x01); //pali potrebne signale SegA do SegG porta P4 cifra%=6; //ukoliko je ispisana sesta cifra sledeca se ispisuje opet prva } }

Kod 7.6 Glavni program i prekidna rutina programa koji na LED displej ispisuje šestocifreni broj

Page 48: Diplomski+rad+Marko+Atanasievski+

8. Tastatura

Razvojni sistem sa MSP430F449 mikrokontrolerom poseduje dve numeričke tastature, povezane tako da mogu da se koriste kao celina [8]. Kao selekcioni signali koriste se u poglavlju LED displeja već korišćeni ssel1 do ssel6 signali, dok su TAST1 do TAST4 signali, koji se vode na pinove portova P1 i P2, ulazni za mikrokontroler i na osnovu njihove promene mikrokontroler dobija informaciju da je pritisnuto dugme.

Način povezivanja tastatura T1 i T2 u sistemu je dat na sledećoj šemi:

Diode D1 do D6 predstavljaju zaštitu od istovremenog pritiska više tastara.Na početku rada sa tastaturom na ssel signale se dovodi logička jedinica. TAST signali su

pull-down otpornikom vezani na masu, tako da će stanje na ovim ulaznim portovima mikrokontrolera u ustaljenom režimu biti logička nula. U trenutku pritiska tastera na jednom od

Slika 8.1 Šema povezivanja tastatura T1 i T2 u sistemu

Page 49: Diplomski+rad+Marko+Atanasievski+

TAST linija se pojavljuje uzlazna ivica, koja biva registrovana od strane mikrokontrolera i on ulazi u prekidnu rutinu. Da bi se ustanovilo koji je taster tačno pritisnut, u jednom vremenskom trenutku mora samo jedan ssel signal da bude uključen i zatim očitavanjem signala TAST1 do TAST4 zaključuje se o kom tasteru je reč.

Na početku prekidne rutine se obavlja softversko debaunsiranje pritisnutog tastera, sa ciljem da se ustanovi da li su kratkotrajni glič ili oscilacije na liniji uzrokovane pritiskom dugmeta aktivirale prekidnu rutinu.

Po ustanovljavanju koje je dugme pritisnuto, prekidna rutina izvršava događaj u skladu sa pritisnutim dugmetom. U datom primeru to je dodela vrednosti pritisnutog dugmeta promenljivoj pritisnuti_broj. Zgodno je u slučaju ovakve prekidne rutine pozvati drugu funkciju koja izvršava događaj vezan za pritisak, i kao argument joj preneti pritisnuti_broj.

U daljem tekstu je prikazan program koji koristi tastaturu T1 i u promenljivoj pritisnuti_broj čuva podatak koji je taster poslednji pritisnut.

Potprogram za inicijalizaciju:

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h" NAME inicijalizacija ;modul za inicijalizaciju tastature T1 PUBLIC inicijalizacija RSEG CODE

inicijalizacija: dint mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT // Tastatura T1

mov.b #ssel1+ssel2+ssel3+ssel4+ssel5+ssel6,&PsselDIR // stavlja output smer za P5.1 do P5.7,// ssel1 do ssel6 signale

bis.b #TAST3+TAST4,&PTAST34IE // dozvoljava prekidne zahteve tastature za signale// TAST3 i TAST4

bis.b #TAST1+TAST2,&PTAST12IE // dozvoljava prekidne zahteve tastature za signale// TAST1 i TAST2

bis.b #ssel1+ssel2+ssel3,&PsselOUT // ukljucuje sve ssel signale za T1 bic.b #TAST3+TAST4,&PTAST34IES //prekidna rutina inicirana TAST3 i TAST4 signalima

//se startuje pri uzlaznoj ivici bic.b #TAST1+TAST2,&PTAST12IES //prekidna rutina inicirana TAST1 i TAST2 signalima

// se startuje pri uzlaznoj ivici eint ret END

Kod 8.1 Inicijalizacija mikrokontrolera za korišćenje tastature T1

Prekidna rutina koja obrađuje događaj pritiska dugmeta na tastaturi T1, pisana u asembleru, je data u nastavku.

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

Page 50: Diplomski+rad+Marko+Atanasievski+

NAME PORT1_ISREXTERN pritisnuti_brojEXTERN waitPUBLIC tastatura_isrRSEG CODE

;************************************************************************************* ; Prekidna rutina za pritisak tastera na tastaturi T1;*************************************************************************************

tastatura_isr:

push R6 push R7 push R8 push R9 push R10 push R11 push R12

bit.b #TAST3+TAST4,&PTAST34IFG // da li je pritisak tastature pokrenuo prekidnu rutinu jnz tastdebouncing //ako jeste skoci na tastdebouncing bit.b #TAST1+TAST2,&PTAST12IFG // da li je pritisak tastature pokrenuo prekidnu rutinu jz ganckraj

; Debaunsiranje pritisnutog dugmeta. Vrsi se ocitavanjem u petlji prvo dva krajnja bita porta P1, zatim dva ; krajnja bita porta P2. Ukoliko se uoci razlika u stanju portova u toku uzastopnog prolaska kroz petlju i ; ocitavanja porta preskace se prekidna rutina za tastaturu.;************************************************************************************

tastdebouncing: ;za port P1 mov.b PTAST34IN,R9 //citamo stanje porta P1 and.b #TAST3+TAST4,R9 // u R9 ostaju samo nama od interesa linije TAST3 i TAST4 mov #0x00,R12 mov #0x00,R11 mov #0x0,R10 //brojac

petlja mov.b PTAST34IN,R11 //ocitava se stanje porta P1 and.b #TAST3+TAST4,R11 //ostavljaju se kao relevantni samo biti P1.6 i P1.7 mov.b R11,R12 //cuva se procitano stanje za kasnije u R12 inv.b R11 //invertuje se sadrzaj R11 and.b R11,R9 //ukoliko je nepromenjen sadrzaj porta iz prethodnog prolaza

// kroz petlju rezultat ce biti 0 jnz zavrsavaj // kraj, ukoliko je poskakivanje napona izazvalo prekidnu

// rutinu mov.b R12,R9 //u R9 se cuva stanje porta za naredni prolazak kroz petlju inc R10 //povecava brojac petlje cmp #0x00FE,R10 //dovoljan broj puta se prolazi kroz petlju jeq daljedebounce //ukoliko je uspesno je zavrseno debaunsiranje, program ide dalje jmp petlja

Page 51: Diplomski+rad+Marko+Atanasievski+

daljedebounce: ;za port P2 mov.b PTAST12IN,R9 and.b #TAST1+TAST2,R9 mov #0x00,R12 mov #0x00,R11 mov #0x0,R10 petlja2 mov.b PTAST12IN,R11 //ocitava se stanje porta P2 and.b #TAST1+TAST2,R11 //ostavljaju se kao relevantni samo biti P2.6 i P2.7 mov.b R11,R12 //cuva se procitano stanje u R12 za kasnije inv.b R11 //invertuje se sadrzaj R11 and.b R11,R9 //ukoliko je nepromenjen sadrzaj porta iz prethodnog

//prolaza kroz petlju rezultat ce biti 0 jnz zavrsavaj // kraj, ukoliko je poskakivanje napona izazvalo prekidnu rutinu mov.b R12,R9 //u R9 se cuva stanje porta radi poredjenja prilikom narednog

// prolaska kroz petlju inc R10 //povecava brojac cmp #0x00FE,R10 //dovoljan broj puta se prolazi kroz petlju jeq zavrsidebounce jmp petlja2

; Debaunsiranje je uspešno završeno. Sledi uključivanje jednog po jednog ssel signala i čitanjem TAST ;linija zaključivanje o tome koji je taster pritisnut.;************************************************************************************ zavrsidebounce

mov #0x0,R12 bic.b #ssel1+ssel2+ssel3,&PsselOUT // iskljucuje selekcione linije tastature T1 bic.b #ssel4+ssel5+ssel6,&PsselOUT // iskljucuje selekcione linije tastature T2 bis.b #ssel1,&PsselOUT //ukljucuje se ispitivanje prve kolone tastature T1 mov #0x0FF,R12 call #wait //ceka se dovoljno vremena da se ustali stanje na linijama mov.b &PTAST12IN,R7 // na bit P2.7 porta dolazi TAST1 signal za

//dugme "1" tastature and #TAST1,R7 // brise sve druge bite, osim stanja bita ocitanog sa P2.7 cmp #TAST1,R7 // uporedjuje ga da vidi da li je bit porta P2.7 1, t.j.

//dugme "1" je pritisnuto jne dalje4 // ako nije ide se dalje na proveru ocitavanja drugih dugmica mov #0x1,R12 // pritisnut je taster 1, smesta se ovaj broj u R12 jmp kraj //skace na obadu dogadjaja pritiska dalje4 mov.b &PTAST12IN,R7 // na bit P2.6 porta dolazi TAST2 signal za dugme "4"

// tastature and #TAST2,R7 // brise sve druge bite, osim stanja bita ocitanog sa P2.6

Page 52: Diplomski+rad+Marko+Atanasievski+

cmp #TAST2,R7 // uporedjuje ga da vidi da li je bit porta P2.6 logicko 1, t.j.// dugme "4" je pritisnuto

jne dalje7 // ako nije ide se dalje na proveru ocitavanja drugih dugmica mov #0x4,R12 // pritisnut je taster 4, smesta se ovaj broj u R12 jmp kraj dalje7 mov.b &PTAST34IN,R7 and #TAST3,R7 cmp #TAST3,R7 jne daljezv mov #0x7,R12 // pritisnut je taster 7, smesta se ovaj broj u R12 jmp kraj daljezv mov.b &PTAST34IN,R7 and #TAST4,R7 cmp #TAST4,R7 jne dalje2 mov #0xB,R12 // pritisnut je taster "*", smesta broj B u R12 jmp kraj dalje2 bic.b #ssel1,&PsselOUT //iskljucuje se ispitivanje prve kolone bis.b #ssel2,&PsselOUT //ukljucuje se ispitivanje druge kolone mov #0x0FF,R12 call #wait //ceka se dovoljno vremena da se ustali stanje na linijama

mov.b &PTAST12IN,R7 and #TAST1,R7 cmp #TAST1,R7 jne dalje5 mov #0x2,R12 // pritisnut je taster 2, smesta se ovaj broj u R12 jmp kraj dalje5 mov.b &PTAST12IN,R7 and #TAST2,R7 cmp #TAST2,R7 jne dalje8 mov #0x5,R12 // pritisnut je taster 5, smesta se ovaj broj u R12 jmp kraj dalje8 mov.b &PTAST34IN,R7 and #TAST3,R7 cmp #TAST3,R7 jne dalje0 mov #0x8,R12 // pritisnut je taster 8, smesta se ovaj broj u R12 jmp kraj dalje0 mov.b &PTAST34IN,R7

Page 53: Diplomski+rad+Marko+Atanasievski+

and #TAST4,R7 cmp #TAST4,R7 jne dalje3 mov #0x0,R12 // pritisnut je taster 0, smesta se ovaj broj u R12 jmp kraj dalje3 bic.b #ssel2,&PsselOUT //iskljucuje se ispitivanje druge kolone bis.b #ssel3,&PsselOUT //ukljucuje se ispitivanje trece kolone mov #0x0FF,R12 call #wait //ceka se dovoljno vremena da se ustali stanje na linijama

mov.b &PTAST12IN,R7 and #TAST1,R7 cmp #0x80,R7 jne dalje6 mov #0x3,R12 // pritisnut je taster 3, smesta se ovaj broj u R12 jmp kraj dalje6 mov.b &PTAST12IN,R7 and #TAST2,R7 cmp #0x40,R7 jne dalje9 mov #0x6,R12 // pritisnut je taster 6, smesta se ovaj broj u R12 jmp kraj dalje9 mov.b &PTAST34IN,R7 and #TAST3,R7 cmp #TAST3,R7 jne daljetar mov #0x9,R12 // pritisnut je taster 9, smesta se ovaj broj u R12 jmp kraj daljetar mov.b &PTAST34IN,R7 and #TAST4,R7 cmp #TAST4,R7 jne kraj mov #0xA,R12 // pritisnut je taster #, smesta se ovaj broj u R12 jmp kraj kraj: //izvrsenje desavanja vezanih za pritisnuti taster cmp #0xC,R12 // dobijeni broj pritiskom na tastaturu mora da bude u rasponu

// od 0x0 do 0xB jge zavrsavaj

Page 54: Diplomski+rad+Marko+Atanasievski+

; Ovde idu desavanja po pritisku tastera sa tastature T1 ;*********************************************************************************

mov R12,&pritisnuti_broj

zavrsavaj bic.b #TAST3+TAST4,&PTAST34IFG // skida prekidne flegove za tastaturu bic.b #TAST1+TAST2,&PTAST12IFG // skida prekidne flegove za tastaturu bis.b #ssel1+ssel2+ssel3,&PsselOUT // ukljucuje sve ssel signale za T1 ;*********************************************************************************; zavrsetak debounciranja tastature T1;*********************************************************************************

ganckraj:

bic.b #TAST3+TAST4,&PTAST34IFG // za svaki slucaj skida prekidne flegove, bic.b #TAST1+TAST2,&PTAST12IFG // da program ne bi zaglavio, ako bi se

// zbog glica,t.j neuspesnog debaunsiranja skocilo odmah na ganckraj pop R12 pop R11 pop R10 pop R9 pop R8 pop R7 pop R6

reti

;=========================================================================COMMON INTVEC(1) ; Interrupt vectors;=========================================================================

ORG PORT1_VECTORDW tastatura_isr

ORG PORT2_VECTORDW tastatura_isr //isti je prekidna rutina za prvi i drugi port zato sto tastatura koristi

// bitove oba ova brojaEND

Kod 8.2 Asemblerska prekidna rutina koja obrađuje pritisak tastera na T1 tastaturi

Ukoliko se želi upotreba tastature T2 umesto T1 u programu dovoljno je promeniti korišćenje ssel signale.

Page 55: Diplomski+rad+Marko+Atanasievski+

U nastavku je data funkcija za veštačko kašnjenje u programu. U ovom slučaju za definisanje funkcije smo upotrebili umesto NAME asemblersku direktivu MODULE. Ukoliko imamo više funkcija u istom fajlu definišemo ih asemblerskom direktivom MODULE. Pri tom poslednja funkcija u fajlu se završava direktivom END, o funkcije koje joj predhode sa ENDMOD.

;******************************************************************************; Funkcija za cekanje. Otprilike ce trajati 3 puta vise taktova od parametra tipa integer koji joj je poslat.;******************************************************************************

MODULE wait_func PUBLIC wait RSEG CODE

wait noppetlja

dec R12 jnz petlja ret END

Kod 8.3 Fajl sa asemblerskom funkcijom za kašnjenje

Glavni program stavlja sistem u stanje čekanja na pritisak dugmeta.

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

void inicijalizacija(void); //deklaracija rutine za inicijalizaciju

unsigned int pritisnuti_broj;

int main( void ){inicijalizacija();while (1){} // sistem se stavlja u stanje cekanja na prekid}

Kod 8.4 Main rutina programa za rad sa tastaturom T1

Page 56: Diplomski+rad+Marko+Atanasievski+

9. LCD displej pogonjen od strane mikrokontolera

Razvojna ploča sa MSP430F449 mikrokontrolerom poseduje dva displeja za komunikaciju sa korisnikom [8]. Od toga, jednostavniji lcd displej je namenjen za prikaz četvoricifrenog broja, i pogonjen je direktno od strane mikrokontrolera koji ima integrisan kontroler lcd displeja. Integrisani kontroler omogućava automatsko generisanje signala za kontrolu lcd ćelija, softversko podšavanje učestanosti osvežavanja i automatsko blinkanje prikaza.

Lcd displej ima 32 segmenta, i od mikrokontrolera se vode 32 linije za pogon ovih ćelija. 33. - jedina zajednička referentna linija za sve ćelije je linija sa porta COM0. Budući da postoji dovoljno linija za pogon lcd displeja predviđen je statički režim rada.

Načim povezivanja lcd displeja sa mikrokontrolerom je prikazan na slici 9.1.

Raspored memorijskih lokacija u mikrokontroleru za kontrolu linija S0 do S31, kao i način njihovog povezivanja sa lcd displejom je dat na slici 9.2. Upisom logičke jedinice u bit dodeljen lcd ćeliji pali se ćelija lcd displeja koja je povezana na tu liniju.

Slika 9.1 Povezivanje lcd displeja pogonjenog od strane mikrokontrolera

Page 57: Diplomski+rad+Marko+Atanasievski+

U nastavku je prikazan primer programa koji koristi lcd displej. U glavnom programu, u promenljivoj broj_za_LCD, sadržan je broj koji se ispisuje na lcd displej. U glavnoj petlji programa, ovaj broj se otprilike na svaku sekundu uvećava za jedan, a zatim ispisuje na lcd displeju. Za ispis se koristi rutina lcd_ispis, koja ispisuje broj (od 0 do 9) na jednom od četiri cifarskih mesta lcd displeja.

Za inicijalizaciju mikrokontrolera, da bi se koristio lcd displej, neophodni su sledeći redovi:

#include "msp430x44x.h"

Slika 9.2 Raspored memorijskih lokacija za kontrolu S0-S31 linija mikrokontrolera i njihova povezanost sa ćelijama LCD displeja

Page 58: Diplomski+rad+Marko+Atanasievski+

NAME inicijalizacija ;modul za inicijalizaciju mikrokontolera PUBLIC inicijalizacija

RSEG CODE

inicijalizacija: dint mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT //LCD pogonjen od strane mikrokontrolera bis.b #LCDP0+LCDP2+LCDON,&LCDCTL // mikrokontroler koristi od S0 do do S31, ukljucuje

//omogucava se koriscenje ovih linija bis.b #LCDSON,&LCDCTL // iskljucuje bit za kontrolu blinkanja lcd-a

eint ret END

Kod 9.1 Inicijalizacija mikrokontrolera za korišćenje lcd displeja

Rutina koja ispisuje jednu cifru na lcd displeju je data u nastavku. Ispod nje je funkcija koja briše sadržaj lcd displeja, t.j. upisuje nule na sve lokacije u memoriji mikrokontrolera koje kontrolišu stanje ćelija lcd displeja.

Fajl koji je izložen je organizovan kao biblioteka funkcija, pa se segmenti koda definišu sa MODUL, a završavaju sa ENDMOD, osim poslednjeg modula u fajlu koji se završava sa END.

#include "msp430x44x.h"

;***********************************************************************************; funkcija koja ispisuje na lcd-u pogonjenom od strane mikrokontrolera broj koji joj se prosledi, ; i na jednu od raspolozive 4 cifre na displeju, sto se takodje prosledjuje kao drugi parametar;; void lcd_ispis(unsigned int broj, unsigned int mesto);;; Druga fukcija koja brise sve sto je ispisano na ovom LCD displeju:; void lcd_clr(void);;**********************************************************************************

MODULE lcd_ispisPUBLIC lcd_ispisRSEG CODE

// simbolicka definicija pozicija bitova u bajtu koji se cita iz tabeleg EQU 001hf EQU 002ha EQU 004hb EQU 008he EQU 010hd EQU 020hc EQU 040hT EQU 080h //tacka

Page 59: Diplomski+rad+Marko+Atanasievski+

lcd_ispis:// svi korisceni registri se moraju sacuvati na steku push R6 push R7 // pomocni registar push R8 push R9 mov R12, R8 // u R8 je cifra 0-9 koji se ispisuje cmp #0xB,R8 jge kraj // cifra koja se ispisuje mora da bude u rasponu od 0 do 9 mov R14, R9 // u R9 je mesto(od cetiri na LCD-u) na kome se ispisuje, krajnje desno je pozicija 1 cmp #4,R9 // da li se ispisuje cifra na mestu 4? jne dalje mov #LCDMEM,R9 // pocetna adresa memorije u mikrokontroleru predvidjene

//za LCD se smesta u R9, za MSP430F449 91h jmp nastavakdalje: cmp #3,R9 // da li se ispisuje cifra na mestu 3? jne dalje1 mov #LCDMEM,R9 // pocetna adresa memorije u mikrokontroleru predvidjene

// za LCD se smesta u R9 add #4,R9 // na pocetnu adresu se dodaje pomeraj, u ovom slucaju za

//cetiri bajta na 095h jmp nastavakdalje1: cmp #2,R9 // da li se ispisuje cifra na mestu 2? jne dalje2 mov #LCDMEM,R9 add #8,R9 // na pocetnu adresu se dodaje pomeraj, u ovom slucaju

//za osam bajtova na 099h jmp nastavak dalje2: cmp #1,R9 // da li se ispisuje cifra na mestu 1? jne dalje3 mov #LCDMEM,R9 add #12,R9 // na pocetnu adresu se dodaje pomeraj, u ovom slucaju za

//12 bajtova na 09Dh jmp nastavakdalje3: mov #LCDMEM,R9

nastavak: // brise ono sto je bilo ispisano na cifri koja se namerava ispisati na lcd-u bic.b #0x11,0(R9) bic.b #0x11,1(R9) bic.b #0x11,2(R9) bic.b #0x11,3(R9) mov.b Tabela(R8),R7 // u R7 su sad biti za paljenje DPcde bafg celija, respektivno mov R7, R6 and #0x01,R6 bis.b R6,0(R9) // setuje bit za g, ako ovog treba setovati

Page 60: Diplomski+rad+Marko+Atanasievski+

rra R7 //siftuje za jedan udesno tako da ce sad podatak o paljenju za f //bit biti na najnizem mestu u R7 mov R7, R6 and #0x01,R6 bis.b R6,1(R9) // setuje bit za f, ako ovog treba setovati rra R7 mov R7, R6 and #0x01,R6 bis.b R6,2(R9) // setuje bit za a, ako ovog treba setovati

rra R7 mov R7, R6 and #0x01,R6 bis.b R6,3(R9) // setuje bit za b, ako ovog treba setovati

mov.b Tabela(R8),R7 // u R7 su sad biti za paljenje DPcde bafg celija, respektivno

mov R7, R6 and #0x10,R6 bis.b R6,0(R9) // setuje bit za e, ako ovog treba setovati

rra R7 mov R7, R6 and #0x10,R6 bis.b R6,1(R9) // setuje bit za d, ako ovog treba setovati

rra R7 mov R7, R6 and #0x10,R6 bis.b R6,2(R9) // setuje bit za c, ako ovog treba setovati

rra R7 mov R7, R6 and #0x10,R6 bis.b R6,3(R9) // setuje bit za tacku, ako ovog treba setovati

// eventualno ukjucivanje tacke na drugoj cifri// mov #LCDMEM,R9// add #0x8,R9// bis.b #0x10,3(R9) // ukljucuje tacku na drugoj cifri

kraj: pop R9 pop R8 pop R7 pop R6 retTabela DB a+b+c+d+e+f ; ispisuje "0" DB b+c ; ispisuje "1" DB a+b+g+e+d ; ispisuje "2" DB a+b+c+d+g ; ispisuje "3" DB b+c+f+g ; ispisuje "4"

Page 61: Diplomski+rad+Marko+Atanasievski+

DB a+f+g+c+d ; ispisuje "5" DB a+f+g+e+c+d ; ispisuje "6" DB a+b+c ; ispisuje "7" DB a+b+c+d+e+f+g ; ispisuje "8" DB a+b+g+f+c+d ; ispisuje "9" DB g ; ispisuje crticu ENDMOD

;*********************************************************************************; brisanje LCD displeja pogonjenog od strane mikrokontrolera;*********************************************************************************

MODULE lcd_clr

PUBLIC lcd_clrRSEG CODE

lcd_clr: push R9 mov #LCDMEM,R9 //pocetak memorije koja se odnosi na lcd displej je sada u R9petlja// iskljucuje sve segmente na LCD-u, cetiri puta prolazi kroz petlju za cetiri cifre na LCD displeju bic.b #0x11,0(R9) bic.b #0x11,1(R9) bic.b #0x11,2(R9) bic.b #0x11,3(R9) add #0x4,R9 cmp #0xA1,R9 jne petlja pop R9 ret

END

Kod 9.2 Rutine za ispis jedne cifre na lcd displeju kao i za brisanje lcd displeja

Glavni program, koji koristi ove rutine izgleda na sledeći način:

#include "msp430x44x.h"

void inicijalizacija(void); //deklaracija rutine za inicijalizacijuvoid lcd_ispis(unsigned int broj, unsigned int mesto); // ispisuje broj na jednoj od cetiri cifre lcd

//displeja pogonjenom od strane mikrokontroleravoid lcd_clr(void); //brise sadrzaj lcd displeja int main( void ){

Page 62: Diplomski+rad+Marko+Atanasievski+

unsigned long int i=0; //brojac unsigned int pomLCD=0; //promenljiva koja sluzi za izvlacenje pojedinacnih cifara iz lcd_broj; unsigned int broj_za_LCD; //broj koji se ispisuje na lcd-u

inicijalizacija();lcd_clr(); //brise sadrzaj na lcd displeju koji je po ukljucivanju napajanja slucajanbroj_za_LCD=0;while (1){ for(i=0;i<163000;i++){} // pauza otprilike oko 1 s, pri taktu mikrokontrolera od 1 Mhz

pomLCD=0; pomLCD=broj_za_LCD%10; lcd_ispis(pomLCD,1); //ispis cifre na mestu jedinica pomLCD=broj_za_LCD/10; pomLCD%=10; lcd_ispis(pomLCD,2); //ispis cifre na mestu desetica pomLCD=broj_za_LCD/100; pomLCD%=10; lcd_ispis(pomLCD,3); //ispis cifre na mestu stotina pomLCD=broj_za_LCD/1000;pomLCD%=10; lcd_ispis(pomLCD,4); //ispis cifre na mestu hiljada broj_za_LCD++; } }

Kod 9.3 Glavni program koji svake sekunde ispisuje broj na lcd displeju

Page 63: Diplomski+rad+Marko+Atanasievski+

10. Inteligentni LCD displej

Razvojna ploča sa MSP430F449 mikrokontrolerom poseduje inteligentni lcd displej AC-162B firme Ampire sa KS0066U lcd drajverom i kontrolerom [2]. Poseduje dva reda sa po šestnaest karaktera. Mogućnosti ovog lcd displeja su detaljno predstavljene u dokumentaciji datoj na kraju ovog dokumenta [2].

Šema veza mikrokontrolera sa inteligentnim lcd displejom je data na slici 10.1.

Inicijalizacija mikrokontrolera za rad sa lcd displejom se sastoji od nameštanja smera portova da budu izlazni. Takođe, linije komunikacije sa inteligentnim lcd displejom se drže na logičkoj nuli kada nema komunikacije.

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

Slika 10.1 Šema vezivanja inteligentnog lcd displeja sa mikrokontrolerom

Page 64: Diplomski+rad+Marko+Atanasievski+

NAME inicijalizacija ;modul za inicijalizaciju mikrokontolera za koriscenje intelig. lcd-a PUBLIC inicijalizacija

RSEG CODEinicijalizacija: dint mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT //LCD inteligentni

bis.b #DB7+DB6+DB5+DB4+STE+SIMO+UCLK,&PLCDDIR // stavlja output smer za P3.0 do P3.7 // bez P3.2 bic.b #DB7+DB6+DB5+DB4+STE+SIMO+UCLK,&PLCDOUT //stavlja nule na svim bitovima //porta 3 koriscenim za inteligentni LCD eint ret END

Kod 10.1 Inicijalizacija mikrokontolera za rad sa inteligentnim lcd displejom

Linije STE, SIMO, UCLK su povezane na ulaze E, RW i RS inteligentnog lcd displeja. Signal izbora tipa podataka RS (bira se podatak ili instrukcija), signal izbora smera komunikacije RW (čitanje ili upis u inteligentni lcd displej) i signal dozvole E (enable) su kontrolni signali u komunikacionom protokolu sa lcd displejem.

Po uključenju napajanja, inteligentni lcd displej zahteva precizan postupak inicijalizacije, rukovođen od strane mikrokontolera, prikazan na sledećem dijagramu:

Page 65: Diplomski+rad+Marko+Atanasievski+

Na dijagramu 10.3 је dat vremenski dijagram u radu sa inteligentnim lcd displejom, koji se mora softverski implementirati na linijama za komunikaciju. U našem slučaju, budući da koristimo samo linije DB4 do DB7, prvo se šalju viša četiri bita a zatim u novom ciklusu na magitstrali niža četiri bita bajta komande.

Slika 10.2 Postupak inicijalizacije inteligentnog lcd displeja

Page 66: Diplomski+rad+Marko+Atanasievski+

Mikrokontoler po uključenju napajanja radi na 1 Mhz. U skladu sa ovim taktom, dat je primer koda za inicijalizaciju inteligentnog lcd displeja.

Zbog primećenih problema sa simboličkim labelama kada se koriste u fajlu sa više modula, simboličke oznake korišćene u fajlu sa rutinama za rad sa inteligentnim lcd displejom su definisane direktno u asemblerskom kodu a ne u razvojna_plocaMSP430.h fajlu.

// deklaracije simbolickih labela koriscenih u programu, koje se odnose na mikrokontroler MSP430F449

PLCDIN DEFINE 0x0018 PLCDOUT DEFINE 0x0019PLCDDIR DEFINE 0x001APLCDSEL DEFINE 0x001B

//oznaka signala koriscenih u komunikaciji sa pametnim lcd displejom, ovo je prakticno njihov polozaj u odnosu na druge bite porta P3

en DEFINE 0x01rw DEFINE 0x02rs DEFINE 0x08

// simbolicke definicije linija komunikacije izmedju mikrokontrolera i inteligentnog lcd displeja

DB7 DEFINE 0x0080DB6 DEFINE 0x0040DB5 DEFINE 0x0020DB4 DEFINE 0x0010UCLK DEFINE 0x0008SIMO DEFINE 0x0002STE DEFINE 0x0001

//drugi bajt inicijalizacije

//gornji deo drugog bajta, na DB7-4 daje 0000 bic.b #rs,&PLCDOUT //RS=0 bic.b #rw,&PLCDOUT //RW=0 nop bis.b #en,&PLCDOUT //EN=1 nop bic.b #DB7+DB6+DB5+DB4,&PLCDOUT // stavlja nule na DB7 do DB4 nop bic.b #en,&PLCDOUT // EN ide dole, upis nop //donji deo bajta nop bic.b #rs,&PLCDOUT //RS=0 bic.b #rw,&PLCDOUT //RW=0 nop bis.b #en,&PLCDOUT //EN=1 nop bis.b #DB7+DB6+DB5+DB4,&PLCDOUT // display On, cursor ON, blinking on nop bic.b #en,&PLCDOUT // EN ide dole, upis nop nop bic.b #DB7+DB6+DB5+DB4,&PLCDOUT // stavlja nule na

Slika 10.3 Vremenski dijagrami slanja komande inteligentnom lcd displeju

Page 67: Diplomski+rad+Marko+Atanasievski+

;**************************************************; Rutina za inicijalizaciju inteligentnog LCD dipleja AC-162B; Po specifikacijama mikrokontrolera primenjena je inicijalizacija pomocu cetvorobitne magistrale;**************************************************

MODULE lcd_startovanje PUBLIC lcd_start EXTERN wait EXTERN command_write RSEG CODE

lcd_start mov #0xCFFF,R12 call #wait // ceka se za svaki slucaj da prodje dovoljno vremena od kad je mikrokontroler dobio napajanje //inicijalizacija, prvi bajt bic.b #rs,&PLCDOUT //RS=0 bic.b #rw,&PLCDOUT //RW=0 nop bis.b #en,&PLCDOUT //EN=1 nop//na DB7-4 , se salje 0010 bis.b #DB5,&PLCDOUT // postavljaju se jedinice na linije komunikacije sa LCD displejom DB7-4 t.j. P3.4 do P3.7

bic.b #DB7+DB6+DB4,&PLCDOUT // postavljaju se nule na linije komunikacije sa LCD displejom DB7-4 t.j. P3.4 do P3.7 nop bic.b #en,&PLCDOUT // EN ide dole, upis nop nop bic.b #DB7+DB6+DB5+DB4,&PLCDOUT // stavlja nule na linije podataka P3.4 do P3.7 //inicijalizacija, na DB7-4 , drugi put se salje 0010 nop bis.b #en,&PLCDOUT //EN=1 nop bis.b #DB5,&PLCDOUT // postavljaju se jedinice na linije komunikacije sa LCD displejom DB7-4 t.j. P3.4 do P3.7

bic.b #DB7+DB6+DB4,&PLCDOUT // postavljaju se nule na linije komunikacije sa LCD displejom DB7-4 t.j. P3.4 do P3.7 nop bic.b #en,&PLCDOUT // EN ide dole, upis nop nop bic.b #DB7+DB6+DB5+DB4,&PLCDOUT // stavlja nule na linije podataka P3.4 do P3.7 //na DB7-4 se stavlja NFXX, ovde konkretno N=1 two line mod, F=0 5x8 tacaka nop bis.b #en,&PLCDOUT //EN=1 nop bis.b #DB7+DB6,PLCDOUT // display on, 5x8 tacaka nop bic.b #en,&PLCDOUT // EN ide dole, upis nop nop bic.b #DB7+DB6+DB5+DB4,&PLCDOUT // stavlja nule na linije podataka mov #0x0FF,R12

linije podataka P3.4 do P3.7 mov #0x0FF,R12 call #wait //treci bajt//gornji deotreceg bajta bic.b #rs,&PLCDOUT //RS=0 bic.b #rw,&PLCDOUT //RW=0 nop bis.b #en,&PLCDOUT //EN=1 nop bic.b #DB7+DB6+DB5+DB4,&PLCDOUT // stavlja nule na DB7 do DB4 nop bic.b #en,&PLCDOUT // EN ide dole, upis nop //donji deo treceg bajta nop bic.b #rs,&PLCDOUT //RS=0 bic.b #rw,&PLCDOUT //RW=0 nop bis.b #en,&PLCDOUT //EN=1 nop bis.b #DB4,&PLCDOUT // display clear nop bic.b #en,&PLCDOUT // EN ide dole, upis nop nop bic.b #DB7+DB6+DB5+DB4,&PLCDOUT // stavlja nule na linije podataka mov #0xFFF,R12 call #wait

//cetvrti bajt

//gornji deo cevtrtog bajta bic.b #rs,&PLCDOUT //RS=0 bic.b #rw,&PLCDOUT //RW=0 nop bis.b #en,&PLCDOUT //EN=1 nop bic.b #DB7+DB6+DB5+DB4,&PLCDOUT // stavlja nule na DB7 do DB4 nop bic.b #en,&PLCDOUT // EN ide dole, upis nop //donji deo cetvrtog bajta nop bic.b #rs,&PLCDOUT //RS=0 bic.b #rw,&PLCDOUT //RW=0 nop bis.b #en,&PLCDOUT //EN=1 nop bis.b #DB6+DB5,&PLCDOUT // increment mode, entire shift off nop bic.b #en,&PLCDOUT // EN ide dole, upis nop nop bic.b #DB7+DB6+DB5+DB4,&PLCDOUT // stavlja nule na linije podataka mov #0x0FF,R12 call #wait

Page 68: Diplomski+rad+Marko+Atanasievski+

call #wait // aktivira se prikaz u oba reda displeja

mov #0x28,R12 call #command_write //poziva funkciju za upis komande command_write, sa komandom koja se salje lcd-u u R12 //zavrsena inicijalizacija LCD-a ret ENDMOD

Kod 10.2 Inicijalizacija inteligentnog lcd displeja

U gornjoj rutini za inicijalizaciju se koriste i neke još nenapisane funkcije, npr. rutina za kašnjenje i rutina za slanje komande lcd displeju. Napravićemo jedan fajl, biblioteku, sa svim funkcijama za rad sa inteligentnim lcd displejom.

Tabela sa naredbama kojima se komunicira sa inteligentnim lcd displejom data je u sledećoj tabeli:

Page 69: Diplomski+rad+Marko+Atanasievski+

U fajl u koji smo već stavili rutinu za inicijalizaciju, dodaćemo i sledeću rutinu koja šalje komandu lcd displeju. Pri davanju komadni inteligentnom lcd displeju linije RS i RW su na logičkoj nuli. Kao parametar funkciji za slanje komande dajemo jedan bajt sa sadržajem linija DB7-DB0 koje čitamo iz tabele 10.1. Funkcija će ovu komandu poslati iz dva magistralna ciklusa, prvo viši deo komande, zatim niži.

;*****************************************************************************; Funkcija koja salje komandu AC-162B inteligentnom displeju.

Tabela 10.1 Naredbe inteligentnog lcd displeja

Page 70: Diplomski+rad+Marko+Atanasievski+

;******************************************************************************

MODULE comm_write_func PUBLIC command_write EXTERN wait RSEG CODE command_write push R9 push R8 mov R12,R9 //u R12 je ulazni parametar funkcije, t.j. komanda za slanje mov R12,R8 bic.b #0x0F,R9 // ostaje samo gornji deo bajta prenetog funkciji u R9 bic.b #0xF0,R8 // ostaje samo donji deo bajta prenetog funkciji U R8 rla R8 rla R8 rla R8 rla R8 bic.b #0x0F,R8 // na bitima 7-4 u R8 ostaju niza cetiri bita komande. mov #0x0FF,R12 call #wait //ceka se neko vreme nop //gornji deo bajta naredbe bic.b #rs,&PLCDOUT //RS=0 bic.b #rw,&PLCDOUT //RW=0 nop bis.b #en,&PLCDOUT //EN=1 nop bis.b R9,&PLCDOUT // namesta jedinice gornjeg dela ulaznog koda naredbe //koja se salje na izlaznim linijama P3.4 do P3.7 inv.b R9 bic.b #0x0F,R9 // ostaju samo visi biti u R9, da se ne poremete ostali //izlazni biti porta P3 bic.b R9,&PLCDOUT // namesta nule gornja cetiri bita komande koja se salje

//naredbe na izlaznim linijama P3.4 do P3.7 nop nop bic.b #en,&PLCDOUT // EN ide dole, upis nop nop bic.b #DB7+DB6+DB5+DB4,&PLCDOUT // stavlja nule na linije podataka

// P3.4 do P3.7 //donji deo bajta naredbe nop bis.b #en,&PLCDOUT //EN=1 nop bis.b R8,&PLCDOUT // namesta jedinice donjeg dela ulaznog koda

//naredbe koja se salje na izlaznim linijama P3.4 do P3.7 inv.b R8

Page 71: Diplomski+rad+Marko+Atanasievski+

bic.b #0x0F,R8 // ostaju samo visi biti u R8, da se ne poremet ostali// izlazni biti porta P3

bic.b R8,&PLCDOUT // namesta nule donjeg dela ulaznog koda naredbe //koja se salje na izlaznim linijama P3.4 do P3.7

nop nop bic.b #en,&PLCDOUT // EN ide dole, upis nop nop bic.b #DB7+DB6+DB5+DB4,&PLCDOUT // stavlja nule na linije podataka

// P3.4 do P3.7 mov #0x0FF,R12 call #wait pop R8 pop R9 ret ENDMOD

Kod 10.3 Funkcija za slanje komande inteligentnom lcd displeju

Budući da je u implementiranju vremenski osetljivih rasporeda signala na magistrali neophodno veštačko kašnjenje, njega ćemo realizovati sledećom rutinom.

;*******************************************************************************; Funkcija za cekanje, dosta koriscena u programu. Otprilike ce trajati 3 puta vise taktova od parametra tipa integer koji joj je poslat.;*******************************************************************************

MODULE wait_func PUBLIC wait RSEG CODE

wait noppetlja dec R12 jnz petlja ret ENDMOD

Kod 10.4 Rutina za kašnjenje

Za pozicioniranje kursora, odnosno memorijske lokacije u LCD displeju u koju će upisom biti ispisan na ekranu sledeći karakter, koristimo rutinu set_adress.

;*************************************************************************; Funkcija koja postavlja pokazivac adrese na zeljeno mesto, radi upisa uli citanja memorije AC-162B inteligentnog displeja. Kao parametar ovoj funkciji se prosledjuje adresa.;************************************************************************* MODULE set_adress PUBLIC set_adress EXTERN wait EXTERN command_write

Page 72: Diplomski+rad+Marko+Atanasievski+

RSEG CODEset_adress bis.b #0x80,R12 call #command_write // poziva funkciju za upis komande sa potrebnim parametrom u R12 ret ENDMOD

Kod 10.5 Pozicioniranje pointera na lokaciju u memoriji lcd displeja, t.j. kursora na ekranu

Konačno, ispis karaktera na lcd displeju, na poziciji na kojoj je trenutno kursor, ćemo izvršiti sledećom funkcijom, kojoj kao parametar prosleđujemo ASCII kod karaktera koji se ispisuje.

;********************************************************************; Funkcija za ispisivanje karaktera na displeju. Karakter ce biti ispisan na tekucoj poziciji kursora.; Ulazni parametar funkcije je ASCII kod karaktera koji se zeli ispisati.;********************************************************************

MODULE ispisi_karakter_func PUBLIC ispisi_karakter EXTERN wait RSEG CODE

ispisi_karakter push R9 push R8 mov R12,R9 //u R12 je ASCII kod karaktera koji se šalje lcd displeju mov R12,R8 bic.b #0x0F,R9 // ostaje samo gornji deo bajta prenetog funkciji u R9 bic.b #0xF0,R8 // ostaje samo donji deo bajta prenetog funkciji U R8 rla R8 rla R8 rla R8 rla R8 bic.b #0x0F,R8 // na bitima 7-4 u R8 ostaje nizih cetiri bita ulaznog ASCII koda. // Ovo je radi slanja. mov #0x0FF,R12 call #wait //kasnjenje nop //slanje gornjeg dela ASCII koda bis.b #rs,&PLCDOUT //RS=1 bic.b #rw,&PLCDOUT //RW=0 nop bis.b #en,&PLCDOUT //EN=1 nop bis.b R9,&PLCDOUT // namesta jedinice gornjeg dela ulaznog ASCII koda na

Page 73: Diplomski+rad+Marko+Atanasievski+

// izlaznim linijama P3.4 do P3.7 inv.b R9 bic.b #0x0F,R9 // ostaje samo gornji deo bajta u R9 bic.b R9,&PLCDOUT //namestaju se nule prisutne u ASCII kodu na izlaznim linijama nop nop bic.b #en,&PLCDOUT // EN ide dole, upis nop nop bic.b #DB7+DB6+DB5+DB4,&PLCDOUT // stavlja nule linije podataka //donji deo prvog bajta nop bis.b #en,&PLCDOUT //EN=1 nop bis.b R8,&PLCDOUT // namesta jedinice donjeg dela ulaznog ASCII koda

// na izlaznim linijama P3.4 do P3.7 inv.b R8 bic.b #0x0F,R8 // ostaju samo biti 7-4, t.j. Invert. donji deo ASCII koda u R8 bic.b R8,&PLCDOUT // namesta nule donjeg dela ulaznog ASCII koda

// na izlaznim linijama P3.4 do P3.7 nop nop bic.b #en,&PLCDOUT // EN ide dole, upis nop nop bic.b #DB7+DB6+DB5+DB4,&PLCDOUT // stavlja nule linije mov #0x0FF,R12 call #wait bic.b #rs,&PLCDOUT //RS=0 pop R8 pop R9 ret ENDMOD

Kod 10.6 Funkcija za ispis karaktera na tekuću lokaciju na lcd displeju

Takođe nam je potrebna funkcija koja briše lcd displej i vraća kursor na početak ekrana.

;**********************************************************************; Funkcija koja brise displej i postavlja kursor u gornji desni ugao ekrana.;**********************************************************************

MODULE clr_displej PUBLIC clr_displej EXTERN wait EXTERN command_write RSEG CODE

clr_displej mov.b #0x01,R12

Page 74: Diplomski+rad+Marko+Atanasievski+

call #command_write ret END

Kod 10.7 Funkcija za brisanje sadržaja ekrana i vraćanje kursora u gornji desnu ugao

U glavnom programu ćemo pozvati funkcije za inicijalizovanje portova mikrokontrolera, zatim ćemo proći kroz postupak inicijalizacije inteligentnog lcd displeja. Brišemo lcd ekran potom, a zatim isključujemo pojavu kursora.

Sledi ispis stringova na lcd displeju, uz upotrebu rutine ispisi_str u kojoj se prolazi kroz petlju i za svaki karakter stringa poziva asemblersku funkciju za ispis karaktera ispisi_karakter.

#include "msp430x44x.h"

void inicijalizacija(void);void ispisi_karakter(char slovo);void command_write(char komanda);void clr_displej(void);void lcd_start(void);void ispisi_str(char*);void set_adress(int);void wait(int);

char poruka[]="Proba displeja"; //string koji se ispisuje u gornjem reduchar poruka2[]="Donji red"; //string koji se ispisuje u donjem redu

int main( void ){ inicijalizacija(); //rutina za inicijalizaciju mikrokontroleralcd_start(); //funkcija za inicijalizaciju A162b displejaclr_displej(); //brise inteligentni displej

command_write(0x0C); // iskljucuje kursor

ispisi_str(poruka); //ispisuje prvi string u gornjem reduset_adress((0x40)); //postavlja kursor na pocetak drugog redaispisi_str(poruka2); //ispisuje string u donjem redu

while (1){} }

void ispisi_str(char pom[]) //funkcija koja ispisuje na inteligentnom displeju//prosledjeni joj string

{ int i=0; for (i=0;pom[i]!='\0';i++) { ispisi_karakter(pom[i]); }

Page 75: Diplomski+rad+Marko+Atanasievski+

}

Kod 10.8 Glavni program koji ispisuje poruku na lcd displeju

Page 76: Diplomski+rad+Marko+Atanasievski+

11. Temperaturni PWM senzor

Razvojna ploča sa MSP430F449 mikrokontolerom poseduje jedan PWM (pulse width modulation) tepmeraturni senzor, oznake SMT16030 [5] . U zavisnosti od veličine temperature, on moduliše pwm signal od 4 KHz koji šalje mikrokontroleru.

Šema povezivanja temperaturnog pwm senzora sa mikrokontrolerom je data u nastavku.

Izlazni pin pwm temperaturnog senzora je povezan na ulaz TA0 tajmera A, tako da je najzgodnije u očitavanju ovog senzora koristiti capture režim tajmera A.

Napisaćemo program koji očitava temperaturu i smešta je u promentljivu temp.Da bismo inicijalizovali kontroler i tajmer A za korišćenje pišemo sledeću

inicijalizacionu rutinu:

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

NAME inicijalizacija ;modul za inicijalizaciju mikrokontrolera PUBLIC inicijalizacija

Slika 11.1 Šema povezivanja temperaturnog PWM senzora sa mikrokontrolerom

Page 77: Diplomski+rad+Marko+Atanasievski+

RSEG CODE

inicijalizacija: dint mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT //SetupTA mov.w #TASSEL_2+MC_2,&TACTL ; SCLK, kontinualni mod bis.w #CCIE+CM_3+SCS+CAP+CCIS0,&TACCTL0 ; // capture za CCR1

// sistemski klok

mov.b #0x3C,&SCFQCTL //N=60, frekfrencija 61*Fkristala=2 MHZ bic.b #FLLD0,&SCFI0 bis.b #FLLD1+FN_3,&SCFI0 //2MHZ mnozi sa 4 = 8 MHZ frekfrencija

//mikrokontrolera bis.b #DCOPLUS,&FLL_CTL0

// PWM temperaturni senzor bis.b #PWMTSPIN ,&PPWMTSSEL ; funkcija za TA0 na portu P1.1 bic.b #PWMTSPIN ,&PPWMTSDIR ; smer ulazni port eint ret END

Kod 11.1 Inicijalizacija mikrokontrolera za korišćenje PWM temperaturnog senzora

Tajmer A će po registrovanju promene ivice na ulazu TA0 ući u prekidnu rutinu. U prekidnoj rutini ćemo proveriti da li je ulazak prouzrokovala ulazna ili silazna ivica signala poslatog od temperaturnog senzora. Ukoliko je to uzlazna ivica, taj vremenski trenutak uzimamo kao početni trenutak, a ukoliko je o silazna ivica, to je vremenski trenutak završetka visokog dela PWM signala koji se šalje mikrokontoleru. Na osnovu razlike ova dva trenutka, a u skladu sa prenosnom funkcijom temperaturnog senzora opisanog u njegovoj dokumentaciji, u globalnu promenljivu rezultat smeštamo temperaturu.

#include "msp430x44x.h"#include "razvojna_plocaMSP430.h"

unsigned long int pocetni=0; //broj taktova na pocetku visoke vrednosti pwm signalaunsigned long int krajnji=0; //broj taktova na kraju visoke vrednosti pwm signalaunsigned long int rezultat=0; //temperatura u C stepenima

#pragma vector=TIMERA0_VECTOR__interrupt void ta_isr() {

Page 78: Diplomski+rad+Marko+Atanasievski+

if ((PPWMTSIN&PWMTSPIN)==0x02) //usli smo u prekidnu rutinu na uzlaznu ivicu {pocetni=TACCR0;} //prvi put se ocitava vrednost capture registra

if ((PPWMTSIN&PWMTSPIN)==0x00) //usli smo u prekidnu rutinu na silaznu ivicu {krajnji=TACCR0; //drugi put se ocitava vrednost capture registra

//na osnovu ocitanih vrednosti capture registara, u skladu sa prenosnom funkcijom TS, izracunava se //temperatura if (krajnji>pocetni) //posle FFFFh brojac se vraca na nulu, pa se to mora uzeti u obzir { rezultat=(100000*(krajnji-pocetni))/1999; rezultat=rezultat-32000; rezultat=rezultat/970;} else { rezultat=(100000*(0xFFFF+krajnji-pocetni))/1999; rezultat=rezultat-32000; rezultat=rezultat/970;} }

}

Kod 11.2 Prekidna rutina tajmera A u kojoj se očitava trajanje visokog dela pwm signala i izračunava temperatura u stepenima celzijusa

U glavnom programu ćemo posle inicijalizacije ući u petlju u kojoj ćemo povremeno dodeljivati izračunatu temperaturu promenljivoj temp. Pri tom, ta dodela će se desiti samo ukoliko je izračunata temperatura između 0 i 100 stepeni.

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

extern void inicijalizacija(void);extern unsigned long int rezultat; //temperatura u C stepenima

unsigned int temp;

int main( void ){ int i=0;inicijalizacija();while(1) { if ((rezultat<100)&&(rezultat>0)) //softverski debouncing {temp=rezultat;} for (i=0;i<30000;i++){} //cekanje }

}

Kod 11.3 Glavni program u primeru temperaturnog PWM senzora

Page 79: Diplomski+rad+Marko+Atanasievski+

Vrlo je lako dodati inicijalizaciju i rutine za korišćenje lcd displeja pogonjenog od strane mikrokontrolera (što je prikazano u poglavlju 8) pa u petlji glavnog programa ispisati sadržaj temp promenljive na ekranu.

Page 80: Diplomski+rad+Marko+Atanasievski+

12. 1-wire temperaturni senzor

Pored pwm temperaturnog senzora, na razvojnu ploču sa MSP430F449 mikrokontrolerom se može dodati i temperaturni senzor DS1820 [4], preko 1-wire magistrale razvijene od strane firme DALLAS SEMICONDUCTORS. To je niskobudžetna magsitrala, koja se sastoji od samo dve linije, mase i linije podataka. Periferni uređaji priključeni na ovu magistralu, ukoliko nemaju sopstveno napajanje, mogu se napajati sa linije podataka. U trenucima kada nema prenosa podataka, linija podataka je na visokom logičkom nivou, pa u našem slučaju temperaturni senzor DS1820 dopunjava kondenzator koji obezbeđuje dovoljno energije da senzor autonomno deluje kada se vrši komunikacija preko linije podataka.

1-wire magistrala dozvoljava samo jednog mastera i više slave uređaja. Značajna osobina 1-wire uređaja je da svaki od njih ima laserki odštampanu ROM sekciju, sa jednistvenim 64-bitnim kodom koji se koristi kao adresa uređaja u komunikaciji.

Početak komunikacije inicira master uređaj, t.j. mikrokontoler, koji šalje reset signal spuštanjem linije podataka na nizak logički nivo minimum 480 us. Ovim se svi periferni urađaju inicijalizuju za komunikaciju. U našem slučaju postoji samo jedna periferija, pa po slanju reseta od strane mikrokontrolera temperaturni senzor šalje potvrdu svog prisustva, kao što je prikazano na slici.

Mikrokontroler zatim šalje temperaturnom senzoru komandu skip ROM kojom se preskače dalja identifikacija i provera ROM adrese temperaturnog senzora budući da je on jedini na magistrali. Komanda je bajt sadržaja CCh.

Napisaćemo za ovu priliku rutinu za slanje bajta temperaturnom senzoru poštujući 1-wire protokol. Rutina je predviđena da radi na originalnoj učestanosti mikrokontrolera, budući da su vremenski dijagrami signala vremenski kritični.

Slika 12.1 Reset temperaturnog senzora

Page 81: Diplomski+rad+Marko+Atanasievski+

Za početak u projekat ćemo uključiti fajl sa definicijama promenljivih koje sadrže dužinu kašnjenja, za slučaj da menjamo frekfrenciju mikrokontrolera ili da su potrebna menjanja vremenskih dijagrama na magistrali. Sledeći asemblerski kod ima istu svrhu kao definisanje globalnih promenljivih u C kodu. Salji_0 i salji_1 i primi se inicijalizuju na početku glavnog programa.

NAME podaci PUBLIC salji_0 PUBLIC salji_1 PUBLIC primi RSEG DATA16_I

salji_0 DS16 1 // kasnjenje pri slanju logicke 0salji_1 DS16 1 // kasnjenje pri slanju logicke 1primi DS16 1 // kasnjenje pri primanju END

Kod 12.1 Definicija globalnih promenljivih u projektu, sa podacima o trajanju kašnjenja na magistrali

Simboličke oznake porta i pina koji se koriste za komunikaciju sa temperaturnim senzorom su date na početku. Prvo se šalje bit najmanje težine. Rutina za slanje bajta temperaturnom senzoru izgleda na sledeći način:

PDS1820OUT DEFINE 0x0029PDS1820DIR DEFINE 0x002APDS1820IN DEFINE 0x0028DS1820PIN DEFINE 0x0004

MODULE upisi_bajt PUBLIC upisi_bajt

Slika 12.2 Dijagram slanja temperaturnom senzoru logičke nule i jedinice

Page 82: Diplomski+rad+Marko+Atanasievski+

EXTERN salji_0 EXTERN salji_1 EXTERN primi RSEG CODE upisi_bajt //rutina za slanje bajta temperaturnom senzoru 1-wire protokolom push R8 push R9 push R10 push R11 push R7 mov #8,R8 // brojac, koliko je jos bita ostalo da se posalje mov R12,R10 //u R10 je bajt koji se salje temperaturnom senzoru

petlja_up mov &salji_0,R7 //u R7 je duzina kasnjenja pri slanju logicke nule mov &salji_1,R11 //u R11 je duzina kasnjenja pri slanju logicke jedinice cmp #0x0,R8 //ukoliko su svih 8 bita poslati skace na kraj jeq kraj dec R8 mov R10,R9 and #0x01,R9 // dobija se sledeci bit koji se salje magistralom, sadrzaj R9 ce biti jednak tom bitu rra R10 //siftujemo udesno da bismo u sledecem prolasku kroz petlju

// poslali magistralom bit najmanje tezine u R10 cmp #0x0,R9 jz salji0 //uslovno skace na deo koda za slanje logicke nule magistralom salji1 //deo koda za slanje logicke jedinice temp. senzoru bic.b #DS1820PIN,&PDS1820OUTdalje_salj1 //petlja za kasnjenje dec R11 jnz dalje_salj1 bis.b #DS1820PIN,&PDS1820OUT //vraca logicku jednicu na magistralu jmp petlja_up salji0 //deo koda za slanje logicke nule temp. senzoru bic.b #DS1820PIN,&PDS1820OUTdalje_salj0 //petlja za kasnjenje dec R7 jnz dalje_salj0

bis.b #DS1820PIN,&PDS1820OUT //vraca logicku jednicu na magistralu jmp petlja_upkraj pop R7 pop R11 pop R10 pop R9 pop R8 ret ENDMOD

Page 83: Diplomski+rad+Marko+Atanasievski+

Kod 12.2 Rutina za slanje bajta (komande) temperaturnom senzoru preko 1-wire magistrale

Čitanje podataka koji su poslazi od starane temperatrunog senzora se obavljaju u skladu sa vremenskim dijagramima na narednoj slici.

Mikrokontroler čitanje bajta koji se šalje od strane temperaturnog senzora obavlja u sledećoj rutini. U nastavku ove rutine je i rutina za veštačko kašnjenje u programu wait.

MODULE citaj_bajt PUBLIC citaj_bajt EXTERN wait EXTERN salji_0 EXTERN salji_1 EXTERN primi

RSEG CODE citaj_bajt push R8 push R9 push R10 push R11 mov #8,R8 // brojac, koliko je jos bita ostalo da se procita clr R10 clr R9

petljacit mov &primi,R11 //duzina kasnjenja pri primanju bajta se smesta u R11 clr R9 dec R8 bic.b #DS1820PIN,&PDS1820OUT //mikrokontroler inicira citanje bita, spusta

Slika 12.3 Vremenski dijagrami citanja bitova iz temperaturnog senzora preko 1-wire magistrale

Page 84: Diplomski+rad+Marko+Atanasievski+

magistralu na logicku nulu bic.b #DS1820PIN,&PDS1820DIR //menja smer pina linije podataka ka ulaznom

dalje_cek //petlja za kasnjenje dec R11 jnz dalje_cek

mov.b PDS1820IN,R9 //ocitava sadrzaj porta na na koji je vezan temperaturni senzor mov #10,R12 call #wait // ceka jos malo bis.b #DS1820PIN,&PDS1820OUT //stavlja logicku jedinicu na pin na kome je magistrala 1wire bis.b #DS1820PIN,&PDS1820DIR //menja smer pina linije podataka ka izlaznom, zavrsava //se ciklus citanja bita and.b #DS1820PIN,R9 //vrednost R9 je jednaka procitanom bitu jz daljecit0 //ako je ocitana logicka nula na magistrali skace na deo koda koji to obradjuje daljecit1 //deo koda koji obradjuje ocitanu logicku jedinicu bis.b #0x80,R10 //procitani logicka jedinica se smesta na najvise mesto u R10 cmp #0x0,R8 //da li je ovo bio poslednji bit koji treba da se procita jeq kraj rra R10 //siftuju se svi procitani biti u desno(DS1820 prvo salje bit najmanje tezine) jmp petljacit

daljecit0 //deo koda koji obradjuje ocitanu logicku nulu bic.b #0x80,R10 //procitani logicka nula se smesta na najvise mesto u R10 cmp #0x0,R8 //da li je ovo bio poslednji bit koji treba da se procita jeq kraj rra R10 //siftuju se svi procitani biti u desno(DS1820 prvo salje bit najmanje tezine) jmp petljacit kraj clr R12 mov.b R10,R12 pop R11 pop R10 pop R9 pop R8 ret ENDMOD MODULE wait_func PUBLIC wait RSEG CODE

wait petlja dec R12 jnz petlja ret ENDMOD

Kod 12.3 Rutina za čitanje bajta sa 1-wire magistrale

Page 85: Diplomski+rad+Marko+Atanasievski+

Koristeći napisane rutine za komunikaciju preko 1-wire magistrale, napisaćemo rutinu čijim se pozivom šalje temperaturnom senzoru komanda za merenje temperature.

MODULE meri PUBLIC meri EXTERN wait EXTERN upisi_bajt RSEG CODE meri push R6 clr R6 bic.b #DS1820PIN,&PDS1820OUT //reset signal na magistrali mov #200,R12 call #wait // ceka oko 600 us bis.b #DS1820PIN,&PDS1820OUT nop nop bic.b #DS1820PIN,&PDS1820DIR //menja se smer na ulazni za mikrokontroler mov #6,R12 call #wait // DS1820 malo ceka mov.b &PDS1820IN,R6 //ocitava se port, radi provere da li ima periferije mov #200,R12 call #wait // master Rx vreme, min 480 us bis.b #DS1820PIN,&PDS1820DIR //menja se smer za mikrokontroler na izlazni bis.b #DS1820PIN,&PDS1820OUT //mikrokontroler vraca magistralu na visok logicki nivo mov #0xCC,R12 call #upisi_bajt //skip ROM komanda mov #0x44,R12 call #upisi_bajt //convert temp komanda pop R6 ret ENDMOD

Kod 12.4 Rutina koja šalje komandu temperaturnom senzoru da izvrši merenje

Temperaturni senzor zahteva po dokumentaciji oko 500 ms. za merenje temperature. Eksperimentalno je utvrđeno da je to vreme ipak znatno duže. Po završetku konverzije obavljamo čitanje temperature iz scratchpad registra.

MODULE citaj_temp PUBLIC citaj_temp EXTERN wait EXTERN upisi_bajt

Page 86: Diplomski+rad+Marko+Atanasievski+

EXTERN citaj_bajt RSEG CODE citaj_temp push R6 push R7 bic.b #DS1820PIN,&PDS1820OUT //reset signal na magistralu podataka mov #200,R12 call #wait // ceka oko 600 us bis.b #DS1820PIN,&PDS1820OUT nop nop bic.b #DS1820PIN,&PDS1820DIR //menja se smer na ulazni za mikrokontroler mov #6,R12 call #wait // DS1820 ceka mov.b &PDS1820IN,R6 //ocitava se port, radi provere da li ima periferije preskacemo mov #200,R12 call #wait // master Rx vreme, min 480 us bis.b #DS1820PIN,&PDS1820DIR //menja se smer za mikrokontroler na izlazni bis.b #DS1820PIN,&PDS1820OUT //mikrokontroler vraca liniju podataka na

//visoku logicku vrednost

mov #0xCC,R12 call #upisi_bajt //skip ROM mov #0xBE,R12 call #upisi_bajt //citaj scratchpad call #citaj_bajt //cita TEMPERATURE LSB mov.b R12,R6 swpb R6 call #citaj_bajt //cita TEMPERATURE MSB bis R12,R6 swpb R6 call #citaj_bajt //cita TH/USER BYTE 1 mov.b R12,R7 call #citaj_bajt //cita TH/USER BYTE 2 mov.b R12,R7 call #citaj_bajt //cita bajt sa lokacije 4 mov.b R12,R7 call #citaj_bajt //cita bajt sa lokacije 5 mov.b R12,R7 call #citaj_bajt //cita bajt COUNT REMAIN mov.b R12,R7 call #citaj_bajt //cita bajt COUNT PER °C mov.b R12,R7

Page 87: Diplomski+rad+Marko+Atanasievski+

call #citaj_bajt //cita bajt CRC mov.b R12,R7 mov R6,R12 //u R12 funkcija vraca procitnu temperaturu pop R7 pop R6 ret END

Kod 12.5 Rutina koja po izvršenoj konverziji čita temperaturu iz temperaturnog senzora

Sve prethodne rutine, osim definicije globalnih promenljivih za kašnjenje, su smeštene u jednom fajlu, kao biblioteci funkcija za rad sa temperaturnim 1-wire senzorom. Glavni program je napisan u C-u. Program u promenljivu temp smešta izmerenu temperaturu, koja se periodično meri i očitava.

#include "msp430x44x.h"

void inicijalizacija(void); //rutina za inicijalizaciju mikrokontroleravoid wait(int);void upisi_bajt(char);int citaj_temp(void);void meri(void);

// u toku razvoja bilo je potrebno mnogo eksperimentisati sa razlicitim vremenskim dijagramima// magistrale, pa su sledece promenljive sluzile za debagovanje i menjanje vremenskih dijagrama slanja i// primanja podatakaextern int salji_0; extern int salji_1;extern int primi;

int temp=0;

int main( void ){

inicijalizacija();wait(0xFFFE);wait(0xFFFE);wait(0xFFFE); // ceka min 500 ms

while (1){ salji_0=15; salji_1=3; primi=3; meri(); wait(0xFFFE); wait(0xFFFE); wait(0xFFFE); wait(0xFFFE); wait(0xFFFE); wait(0xFFFE); wait(0xFFFE); wait(0xFFFE); wait(0xFFFE); wait(0xFFFE); wait(0xFFFE); // ceka dovoljno dugo da DS1820 izvrsi merenje temp=citaj_temp(); temp=temp>>1; //izracunava celobrojnu temperaturu, u temp je sada temperatura

// u stepenima celzijusa

Page 88: Diplomski+rad+Marko+Atanasievski+

}}

Kod 12.6 Glavni program za merenje temperature DS1820 temperaturnim senzorom

Page 89: Diplomski+rad+Marko+Atanasievski+

13. SPI digitalni potenciometar

Na razvojnoj ploči postoje SPI periferije digitalni potenciometar MCP41010 [3], kao i EEPROM 25C320 [7] kompanije Microchip, uz mogućnost dodavanja još jedne SPI periferije, A/D konvertora. Svaki od navedenih uređaja poseduje chip select signal, koji pre korišćenja periferije mora biti postavljen na aktivnu vrednost.

Chip select signali se do uređaja vode preko dekodera 74HC13, sa izlazima aktivnim na niskom logičkom nivou. Šema povezivanja mikrokontrolera sa dekoderom, t.j. način formiranja chip select signala su prikazani na sledećoj šemi.

Mikrokontoler MSP430F449 poseduje hardversku podršku za SPI protokol, odnosno USART jedinice mikrokontrolera se jednostavno mogu podesiti da rade sa SPI protokolom, kao što će biti prikazanu u daljem tekstu. O vremenskom rasporedu signala na magistrali brine USART jedinica, a za njeno podešavanje dovoljno je podesiti nekoliko bitova u kontrolnim registrima.

Za komunikaciju sa digitalnim potenciometrom dovoljne su, uz CS signal, dve linije, t.j. SIMO (serial input master output) i UCLK t.j. clock signal magistrale. Vremenski dijagram SPI protokola je dat na sledećoj slici. Podatak se od strane mikrokontrolera izbacuje na magistralu na silaznu ivicu takta.

Slika 13.1 Chip select signali za SPI periferije

Page 90: Diplomski+rad+Marko+Atanasievski+

Šema povezivanja digitalnog potenciometra sa mikrokontrolerom je data na sledećoj slici.

Izlaz digitalnog potenciomtera je povezan na led diodu, koja će jače ili slabije sijati u zavisnosti od napona.

Napravićemo program koji će očitavati napon sa analognog ulaza i zatim veličinu tog napona preko SPI magittrale upisati u digitalni potenciomter.

Slika 13.3 Šema povezivanja digitalnog potenciometra sa mikrokontrolerom

Slika 13.2 Vremenski dijagram protokola korišćenog sa komunikaciju sa digitalnim potenciomternom

Page 91: Diplomski+rad+Marko+Atanasievski+

Sledeća inicijalizaciona rutina je za promenu pisana u C-u. Inicijalizuju se A/D konvertor, tajmer B i USART jedinica.

#include "msp430x44x.h"

void initialisation(void){ __disable_interrupt(); //onemogucava bit GIE, kompajlerska funkcija. WDTCTL = WDTPW + WDTHOLD; //zaustavlja WDT

// AD convertor P6SEL=P6SEL|0x10; //P6.4 ADC12 function ADC12CTL0=ADC12CTL0|(SHT0_1+REFON+REF2_5V+ADC12ON); ADC12CTL1=ADC12CTL1|(ADC12SSEL0+SHP+SHS_3+CONSEQ_2); //ack, Repeat-

//-single-channel, Timer_B.OUT1 ga taktuje, Pulse Sample Mode ADC12MCTL0=ADC12MCTL0|INCH_4; // selektovan kanal A4 ADC12IE=ADC12IE|0x01; //dozvoljen interupt za ADC12MEM0 registar ADC12CTL0=ADC12CTL0|ENC; // startovanje u pogon AD konvertora

//SetupTB TBCTL=TBCTL|(TBSSEL_1+MC_1); // ACLK, UP mode TBCCTL1=TBCCTL1|OUTMOD_3; // set/reset mod za tajmerB CCR1 TBCCR0=0xDAC; //inicijalizacija TBCCR0 registra TBCCR1=0x6D6; //inicijalizacija TBCCR1 registra

//digitalni potenciometar P6DIR=P6DIR|0x07; // output za DIO4 i DIO5 i DIO6, radi CS signala P6OUT=P6OUT|0x04; // decoder 74HC178 E3 signal enable P6OUT=P6OUT|0x01; // CS1 selektovan za digitalni potenciometar

//setup USRT U0CTL=SWRST; //pocetak procedure inicijalizacije USART

// jedinice U0CTL=U0CTL|(CHAR+SYNC+MM); // SPI, master, 8 bita data length U0TCTL=U0TCTL|(SSEL0+SSEL1+STC+CKPL); // salje na silaznu ivicu, smclk

//(po defaultu 1 Mhz), 3 pin SPI mode U0BR0=0x0A; //delitelj takta za baud rate-a, uzeli smo da je 10, //znaci takt kojim radi magistrala je 1MHz/10

U0BR1=0x00; //delitelj takta visi bajt U0MCTL=0x00; //po preporuci proizvodjacha ME1=ME1|USPIE0; //Enable SPI USART module U0CTL=U0CTL&(~SWRST); //clear SWRST, USART je spreman za rad P3DIR=P3DIR|0x0A; // output za SIMO,UCLK P3SEL=P3SEL|0x0E; //funkcija za SIMO,SOMI, UCLK na

// pinovima porta P3

Page 92: Diplomski+rad+Marko+Atanasievski+

__enable_interrupt(); //dozvoljava prekide, kompajlerska funkcija.

}

Kod 13.1 Inicijalizaciona rutina Digitalnog potenciometra, USART jedinice za SPI mod, A/D konvertora i tajmera B

Komande za komunikaciju sa digitalnim potenciometrom su vrlo jednostavne:

Slika 13.4 Komande digitalnog potenciomtera

Page 93: Diplomski+rad+Marko+Atanasievski+

Glavni program će inicijalizovati mikrokontroler za upotrebu digitalnog potenciomtera. Zatim poslati digitalnom potenciomteru 0xFE, t.j. upaliće diodu na najaču vrednost. Program zatim ulazi u beskonačnu petlju, gde se digitalnom potenciomteru stalno šalje vrednost promenljive pot_otpornost. Povremeno se ulazi u prekidnu rutinu, što inicira tajmer B, u kojoj se očitava vrednost analognog ulaza i skalira na vrednost od 0 do 255, t.j. raspon vrednosti digitalnog potenciomtera. Takođe, da bismo ispoštovali vreme potrebno za slanje i primanje preko magistrale, koristimo funkciju za veštačko kašnjenje wait_c.

//=================================================================// Program koji na osnovu ulaza AD konvertora salje vrednost od 0 255 SPI// digitalnom potenciometru//=================================================================

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

void inicijalizacija(void); //rutina za inicijalizaciju mikrokontroleravoid wait_c(int broj); //rutina za kasnjenje

int pot_otpornost=0x80; //vrednost koja se upisuje u digitalni potenciomtar

int main( void ){inicijalizacija();

PSPIDECODOUT=PSPIDECODOUT|(CS1); // CS1 ide dole,novi ciklusU0TXBUF=0x11; // salje se komanda digitalnom potenciometruwait_c(1000); // ceka se da se posaljeU0TXBUF=0xFE; // nova vrednost za digitalni potenciometar, maksimalno svetlo diodewait_c(1000);PSPIDECODOUT=PSPIDECODOUT&(~CS1); // CS1 se penje gore, komanda u

//digitalnom potenciometru se izvrsava while (1) //petlja koja stalno salje vrednosti digitalnom potenciometru { PSPIDECODOUT=PSPIDECODOUT|(CS1); // CS1 ide dole,novi ciklus U0TXBUF=0x11; //salje se komanda digitalnom potenciomteru wait_c(1000); U0TXBUF=pot_otpornost; //vrednost koja se salje je sadrzana u promenljivoj pot_otpornost wait_c(1000); PSPIDECODOUT=PSPIDECODOUT&(~CS1); // CS1 se penje gore, komanda u digitalnom

// potenciometru se izvrsava }

}

Page 94: Diplomski+rad+Marko+Atanasievski+

void wait_c(int broj) //C rutina za vestacko kasnjenje u programu {int i=0; int proba=0; for (i=1;i<broj;i++){proba=proba+1;} }

#pragma vector=ADC12_VECTOR__interrupt void adc12_prekidna_rutina(void){ unsigned long int otpornost;

if (ADC12IV==0x006)

{ otpornost=ADC12MEM0; // procitaj bafer otpornost=otpornost*256/4095; pot_otpornost=otpornost; //nova vrednost za slanje digitalnom potenciometru

}}

Kod 13.2 Glavni program, rutina za kašnjenje i prekidna rutina tajmera B, koje sa analognog ulaza stalno šalju novu vrednost digitalnom potenciomteru

Page 95: Diplomski+rad+Marko+Atanasievski+

14. SPI EEPROM memorija

Sistem poseduje jednu SPI EEPROM 25C320 memoriju [7], od 32 Kbita memorijskog prostora. Memorija naravno zahteva dvosmernu komunikaciju, pa su nam pored chip selecta potrebne još tri linije.

Na sledećoj slici je za primer izgleda SPI komunikacionog protokola prikazana inicijalizaciona komanda koju mikrokontroler mora poslati SPI memoriji pre upisa podatka u nju, tzv. Write enable sequence.

Slika 14.1 Šema vezivanja SPI EEPROM memorije sa mikrokontrolerom

Slika 14.2 Dijagram inicijalizacione

Page 96: Diplomski+rad+Marko+Atanasievski+

Podatak se od strane slejva i mastera postavlja na magistralu na silaznu ivicu takta, a čita na uzlaznu.

Napisaćemo program koji upisuje i čita nekoliko bajtova iz SPI EEPROM memorije.Najpre inicijalizacija mikrokontrolera za korišćenje memorije:

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

NAME inicijalizacija ;modul za inicijalizaciju mikrokontrolera PUBLIC inicijalizacija RSEG CODE

inicijalizacija: dint mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT

//USART 0 SPI

bis.b #SWRST,&U0CTL bis.b #CHAR+SYNC+MM,&U0CTL // SPI, master, 8 bita data length bis.b #SSEL0+SSEL1+STC+CKPL,&U0TCTL // salje se na silaznu ivicu takta, prima na //uzlaznu, smclk, 3 pin SPI mode

mov.b #0x0A, &U0BR0 //takt magistrale 1Mhz/10 mov.b #0x00, &U0BR1 //visi bajt delitelja frekfrencije mov.b #0x00, &U0MCTL //po preporuci proizvodjaca bis.b #USPIE0,&ME1 // enable SPI bic.b #SWRST,&U0CTL // clear SWRST bic.b #UTXIE0,IE1 //zabranjeni prekidi bic.b #URXIE0,IE1 //zabranjeni prekidi bis.b #0x0A,&PSPIDIR // output za SIMO,UCLK bis.b #0xE,&PSPISEL //funkcija za SIMO,SOMI, UCLK na pinovima porta P3

//SPI EEPROM bis.b #DIO4+DIO5+DIO6,&PSPIDECODDIR// output za DIO4 i DIO5 i DIO6 bis.b #DIO6,&PSPIDECODOUT // decoder 74HC178 E3 signal enable bic.b #DIO4,&PSPIDECODOUT bic.b #DIO5,&PSPIDECODOUT //CS2 na visokom logickom nivou, memorija nije

// selektovana za rad eint ret END

Kod 14.1 Inicijalizacija mikrokontrolera za rad sa SPI EEPROM memorijom

Da bismo automatizovali rad sa SPI EEPROM memorijom, napisaćemo rutine koje upisuju i čitaju bajt sa date adrese.

Protokol na magistrali koji se koristi pri upisu bajta podatka u memoriju, je dat na sledećoj slici.

Page 97: Diplomski+rad+Marko+Atanasievski+

Rutina koja ovo realizuje je napisana u C kodu. Kao parametre uzima adresu i podatak koji mora biti od 0 do 255. Prvo se memoriji šalje write enable komanda, a zatim se realizuje protokol sa slike 14.3.

void upisi_spi_eeprom(int adresa, int pod_za_upis){ int MSB_adr=0; //visi bajt adrese za upis int LSB_adr=0; //nizi bajt adrese za upis MSB_adr=adresa/256; LSB_adr=adresa%256;

//write enable sequence PSPIDECODOUT=PSPIDECODOUT|(CS2);// CS2 ide dole,novi ciklus wait_c(20); U0TXBUF=0x06; // WREN, write enable, komanda wait_c(1000); // ceka se da se posalje PSPIDECODOUT=PSPIDECODOUT&(~CS2);// CS2 se ide gore,sad je omogucen //upis u memoriju wait_c(1000); //write sequence PSPIDECODOUT=PSPIDECODOUT|(CS2);// CS2 ide dole,novi ciklus wait_c(20); U0TXBUF=CS2; //write command wait_c(1000); U0TXBUF=MSB_adr; //MSbajt adrese wait_c(1000); U0TXBUF=LSB_adr; //LSBajt adrese wait_c(1000); U0TXBUF=pod_za_upis; //bajt podatka za upis wait_c(1000); PSPIDECODOUT=PSPIDECODOUT&(~CS2);// CS2 se penje gore, zavrsen ciklus upisa wait_c(1000); }

Kod 14.2 Rutina za upis podatka na željenu adresu u EEPROMU

Slika 14.3 Protokol na SPI magistrali pri uspisu bajta podatka u EEPROM

Page 98: Diplomski+rad+Marko+Atanasievski+

Protokol na magistrali koji se koristi pri čitanju bajta podatka u memoriju, je dat na sledećoj slici.

Rutina koja realizuje čitanje podatka iz memorije je data u nastavku. Kao parametar joj se prosleđuje adresa. Takođe, po izbacivanju adrese na magistralu, mikrokontroler šalje jedan don't care bajt, samo sa ciljem da taktuje magistralu, da bi po SOMI liniji EEPROM memorija poslala bajt podatka.

int citaj_spi_eeprom(int adresa){ int MSB_adr=0; //visi bajt adrese za citanje int LSB_adr=0; //nizi bajt adrese za citanje int procitaj_pom; //promenljiva u koju se smesta procitani bajt MSB_adr=adresa/256; LSB_adr=adresa%256; wait_c(2000); PSPIDECODOUT=PSPIDECODOUT|(CS2);// CS2 ide dole,novi ciklus wait_c(20); U0TXBUF=0x03; //read command wait_c(1000); U0TXBUF=MSB_adr; //MSbajt adrese wait_c(1000); U0TXBUF=LSB_adr; //LSBajt adrese wait_c(1000); wait_c(1000); U0TXBUF=0x00; //dont care bajt wait_c(1000); procitaj_pom=U0RXBUF; //cita se podatak PSPIDECODOUT=PSPIDECODOUT&(~CS2);// CS2 se penje gore, zavrsen ciklus citanja return procitaj_pom; }

Kod 14.3 Rutina za čitanje podatka sa željene adrese u EEPROMU

Glavni program koji upisuje, a zatim čita nekoliko bajtova, je dat u nastavku.

//====================================================================// Program koji upisuje bajt u SPI EEPROM MEMORIJU a zatim ga opet cita//====================================================================

Kod 14.3 Rutina za čitanje podatka sa željene adrese iz EEPROM memorije

Page 99: Diplomski+rad+Marko+Atanasievski+

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

void inicijalizacija(void); //rutina za inicijalizaciju mikrokontroleravoid wait_c(int broj); //rutina za kasnjenjeint citaj_spi_eeprom(int adresa); //funkcija za citanje bajta iz SPI EEPROM memorijevoid upisi_spi_eeprom(int adresa, int pod_za_upis); //funkcija za upis bajta u SPI EEPROM memoriju

int pod_za_upis[5];int pod_procitan=0;int adresa=0x00;

int main( void ){inicijalizacija();pod_za_upis[0]=23;pod_za_upis[1]=43;adresa=0x0A;

//upis dva bajtaupisi_spi_eeprom(adresa, pod_za_upis[0]);adresa++;upisi_spi_eeprom(adresa, pod_za_upis[1]);

//citanje dva bajtaadresa=0x0A;pod_procitan=citaj_spi_eeprom(adresa);adresa=0x0B;pod_procitan=citaj_spi_eeprom(adresa); while (1){}}

void wait_c(int broj) //funkcija za vestacko kasnjenje u programu {int i=0; int proba=0; for (i=1;i<broj;i++){proba=proba+1;} }

Kod 14.4 Glavni program koji upisuje u EEPROM i zatim čita nekoliko bajtova, kao i funkcija za veštačko kašnjenje u programu

Page 100: Diplomski+rad+Marko+Atanasievski+

15. I2C EEPROM memorija

Razvojna ploča sa MSP430F449 poseduje i I2C EEPROM memoriju 24C04 firme Atmel [6].

I2C protokol je razvijen od strane kompanije Philips i ima široku primenu u mikrokontrolerskim sistemima. Komunikacija se obavlja preko dve linije, SCL (serial clock) i SDA (serial data). Uređaji priključeni na ovu magistralu mogu da primaju i da šalju podatke. Takođe, na magistrali može da bude više master uređaja. Izlaz na magistralu se realizuje preko otvorenog kolektora (odnosno drejna za CMOS tehnologiju), i u ustaljenom stanju, kada nema komunikacije, linije su na visokom logičkom nivou, što obezbeđuju pull-up otpornici. Mikrokontoler MSP430F449 ne poseduje hardversku podršku za I2C protokol pa ćemo ga softverski realizovati.

Slika 15.1 Šema povezivanja mikrokontrolera sa I2C EEPROM memorijom

Page 101: Diplomski+rad+Marko+Atanasievski+

Početak komunikacije se signalizira obaranjem na nulti logički nivo SDA linije, dok je SCL linija još na jedinici. Mikrokontroler, kao master uređaj na magistrali, diktira takt. Prvi podatak koji sledi je adresa praćena R/W bitom. Pri slanju bajta prvo se šalje MSB bit. Zatim sledi slanje i primanje bajtova komandi i podataka, i komunikacija se završava stop uslovom, što je uzlazna ivica na SDA liniji dok je SCL linija na logičkoj jedinici. Na liniji podataka se za vreme rada magistrale podaci menjaju samo kada je takt linija SCL na logičkoj nuli.

Pri upisu podatka u I2C EEPROM memoriju, mora se poštovati sledeći protokol:

Budući da je realizacija I2C protokola na magistrali vremenski kritična, potrebne rutine moraju biti napisane u asembleru.

Najpre rutina za inicijalizaciju:

Slika 15.2 Vremenksi dijagrami na I2C magistrali

Slika 15.3 Protokol za upis podatka u I2C EEPROM memoriju

Page 102: Diplomski+rad+Marko+Atanasievski+

#include "msp430x44x.h" #include "razvojna_plocaMSP430.h"

NAME inicijalizacija ;modul za inicijalizaciju mikrokontrolera PUBLIC initialisation EXTERN DATAI2C EXTERN ADDRI2C EXTERN BITI2C EXTERN RXTXI2C RSEG CODE

initialisation: dint mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT // I2C EEPROM

bis.b #SDAPIN,&PSDAOUT ; SDA=1 bis.b #SDAPIN,&PSDADIR ; P2.1 OUTPUT, SDA bis.b #SCLPIN,&PSCLOUT ; SCL=1 bis.b #SCLPIN,&PSCLDIR ; P1.0 OUTPUT, SCL clr &DATAI2C clr &ADDRI2C clr &BITI2C clr &RXTXI2C eint ret END

Kod 15.1 Inicijalizacija mikrokontrolera za komunikaciju sa I2C memorijom

Registre, t.j. globalne promenljive koje ćemo koristiti u radu sa I2C magistralom ćemo definisatina sledeći način:

:***************************************************************************; Ovde se definisu registri koji se koriste u komunikaciji sa I2C eepromom;************************************************************************** MODULE podaci

PUBLIC RXTXI2C ; I2C Receive/Transmit Register PUBLIC ADDRI2C ; I2C Address Register PUBLIC DATAI2C ; I2C Data Register PUBLIC BITI2C ; I2C Bit Counter Register

Page 103: Diplomski+rad+Marko+Atanasievski+

RSEG DATA16_I RXTXI2C DS8 2ADDRI2C DS8 2 DATAI2C DS8 2 BITI2C DS8 2 ENDMOD

Kod 15.2 Registri korišćeni u radu sa I2C magistralom

Da bismo poslali bajt memoriji preko I2C magistrale, upotrebićemo sledeći kod 15.3.Simboličke promenljive koje se koriste u kodu su definisane na početku modula, i sve

rutine za realizovanje I2C protokola su stavljene u ovaj jedan modul, njihov početak je označen labelom a kraj ret direktivom.

MODULE I2C_rutine EXTERN RXTXI2C ; I2C Receive/Transmit Register EXTERN ADDRI2C ; I2C Address Register EXTERN DATAI2C ; I2C Data Register EXTERN BITI2C ; I2C Bit Counter Register EXTERN wait ; funkcija za kasnjenje PUBLIC write_i2c ; funkcija salje 1 bajt memoriji PUBLIC read_i2c ; funkcija cita bajt iz memorije

EEPROM24C04 EQU 0xA0 ; 24C04 HW Address (A0=A1=A2=0)SCL EQU 001h ; P1.0 controls SCL line , vezan pull up otpornik na nju od 3.3 KSDA EQU 002h ; P2.1 controls SDA line , vezan pull up otpornik na nju od 3.3 KTRIG EQU 001h ; Trigger pointPSCLOUT EQU 0x0021PSDAOUT EQU 0x0029PSCLDIR EQU 0x0022PSDADIR EQU 0x002APSDAIN EQU 0x0028

RSEG CODE

;------------------------------------------------------------------------------I2C_TX;------------------------------------------------------------------------------ mov #08,&BITI2C ; brojac, 8 bita treba da se posalje bic.b #SCL,&PSCLOUT ; SCL=0, sledi promena linije podataka mov #0xFF,R12

Page 104: Diplomski+rad+Marko+Atanasievski+

call #wait ; delay

I2C_TX_Bit rla.b &RXTXI2C ; data bit -> carry jc I2C_TX1 ; test carry for 1 or 0, skokI2C_TX0 bic.b #SDA,&PSDAOUT ; SDA=0 jmp I2C_TXx I2C_TX1 bis.b #SDA,&PSDAOUT ; SDA=1 jmp I2C_TXxI2C_TXx mov #0xFF,R12 call #wait ; delay bis.b #SCL,&PSCLOUT ; SCL=1, upis bita mov #0xFF,R12 call #wait ; delay bic.b #SCL,&PSCLOUT ; SCL=0 mov #0xFF,R12 call #wait ; delay dec BITI2C ; svi biti poslani? jnz I2C_TX_Bit ; ako nisu skaci nazad u petljuTX_Ackn bic.b #SDA,&PSDADIR ; SDA=0, release SDA line for acknowledge bis.b #SCL,&PSCLOUT ; SCL=1, ACK bit na SDA mov #0xFF,R12 call #wait ; delay bic.b #SCL,&PSCLOUT ; kraj ACK bita, SCL=0 bic.b #SDA,&PSDAOUT ; kad se zavrsi ack bit ostaje i dalje 0 na magistrali bis.b #SDA,&PSDADIR ; SDA=0, opet se daje kontrola masteru mov #0xFF,R12 call #wait ; delay ret ; Return from subroutine

Kod 15.3 Početak modula sa rutinama za rad sa I2C magistralom, kao i rutina za slanje bajta

Slično ćemo relazovati i rutinu za primanje bajta poslanog od EEPROM memorije:

;------------------------------------------------------------------------------I2C_RX;------------------------------------------------------------------------------ mov #08,&BITI2C ; brojac, 8 bita treba da se primi clr &DATAI2C bic.b #SCL,&PSCLOUT ; SCL=0, sledi promena linije podataka bic.b #SDA,&PSDADIR ; master postavlja pin SDA na ulazni mov #0xFF,R12 call #wait ; kasnjenje da bi se potrefile I2C specifikacije

I2C_RX_Bit mov #0xFF,R12 call #wait ; delay bis.b #SCL,&PSCLOUT ; SCL=1, sad sledi ocitavanje bita koji je periferija stavila na SDA mov #0xFF,R12 call #wait ; delay

Page 105: Diplomski+rad+Marko+Atanasievski+

mov.b PSDAIN,&RXTXI2C ; cita ceo P2 port bic.b #0xFD,&RXTXI2C ; RXTXI2C=RXTXI2C & 0x02; ostaje samo bit na

;SDA magistrali u RXTXI2C cmp #0,&RXTXI2C ; test RXTXI2C for 0 or 1, skok jnz I2C_RX1 I2C_RX0 bic.b #0x01,&DATAI2C ; nula je najnizi bit u DATAI2C rla &DATAI2C jmp I2C_RXx ; pa se siftuje u levo, jer prvo dolazi MSB bitI2C_RX1 bis.b #0x01,&DATAI2C ;setuje se najnizi bit u DATAI2C rla &DATAI2C ; pa se siftuje u levo, jer prvo dolazi MSB bit jmp I2C_RXxI2C_RXx mov #0xFF,R12 call #wait ; kasnjenje bic.b #SCL,&PSCLOUT ; SCL=0 mov #0xFF,R12 call #wait ; kasnjenje da bi se potrefile I2C specifikacije dec BITI2C ; svi biti poslani? jnz I2C_RX_Bit ; ako nisu skaci nazad u petljuRX_end bis.b #SDA,&PSDADIR ; SDA=0, opet se daje kontrola masteru rra &DATAI2C ; jedanput vise nego sto treba je siftovan u petlji pa se vraca za taj jedan bit mov #0xFF,R12 call #wait ret ; Return from subroutine

Kod 15.4 Rutina za primanje bajta poslatog od strane I2C memorije

Pošto raspolažemo rutinama koji šalju i primaju bajt I2C magistralom, sad možemo realizovati protokol za upis i čitanje podatka u I2C EEPROM memoriju.

Prvo ćemo napisati rutinu koja na I2C magistrali postavlja start uslov, prikazan na slici 15.2.

;------------------------------------------------------------------------------I2C_Start ;------------------------------------------------------------------------------ bic.b #SCL,&PSCLOUT ; CLK ide na nulu bis.b #SDA,&PSDAOUT ; namestaja se i SDA na 1, u polozaj za start signal mov #0xFF,R12 call #wait ; delay bis.b #SCL,&PSCLOUT ; SCL ide na kec mov #0xFF,R12 call #wait bic.b #SDA,&PSDAOUT ; start uslov mov #0xFF,R12 call #wait bic.b #SCL,&PSCLOUT ; spusta se SCL, magistrala je spremna za dalji rad, t.j. slanje

;hardverske adrese mov #0xFF,R12 call #wait ; vremenski okvir starta mora da bude min 5 us sirok ret

Page 106: Diplomski+rad+Marko+Atanasievski+

Kod 15.5 Start contition na I2C magistrali

Na sličan način se implementira i rutina za stop condition na I2C magistrali.

;------------------------------------------------------------------------------I2C_Stop;------------------------------------------------------------------------------ bic.b #SDA,&PSDAOUT ; SDA=0 mov #0xFF,R12 call #wait ; kasnjenje jedno 40 us bis.b #SCL,&PSCLOUT ; SCL=1 mov #0xFF,R12 call #wait ; delay to meet I2C spetifications bis.b #SDA,&PSDAOUT ; SDA = 1, stop uslov mov #0xFF,R12 call #wait ; delay to meet I2C spetifications ret ; Vraca se u glavni program

Kod 15.6 Stop contition na I2C magistrali

Za upis podatka u I2C memoriju, t.j. realizacija protokola sa slike 15.3, se vrši u sledećoj rutini. Kao prvi parametar funkciji prosleđujemo bajt podatka za upis, a kao drugi parametar adresu na koju se upisuje u memoriju.

;------------------------------------------------------------------------------write_i2c;------------------------------------------------------------------------------ push R8 push R9 push R10 mov.b R12, &DATAI2C ; prenosi se iz glavnog programa bajt za slanje mov.b R14, &ADDRI2C ; prenosi se iz glavnog programa adresa upis call #I2C_Start mov.b #0xA0 , &RXTXI2C ; Puni se Receive/Transmit registar adresom i R/W=0 call #I2C_TX ; Send hardware adress and R/W bit mov.b &ADDRI2C, &RXTXI2C ; puni se Receive/Transmit registar adresom memorijske lokacije call #I2C_TX ; Upisuje se adresa u adress counter I2C memorije

mov.b &DATAI2C, &RXTXI2C ; puni se Receive/Transmit registar podatkom za upis u memoriju call #I2C_TX ; Salje bajt podatka call #I2C_Stop ; zavrsetak prenosa pop R10 pop R9 pop R8

Page 107: Diplomski+rad+Marko+Atanasievski+

ret ; vraca se iz procedure

Kod 15.7 Upis bajta podatka u I2C EEPROM memoriju

Protokol za čitanje podatka iz I2C memorije je sledeći:

Ovo se realizuje sledećom rutinom, koja je ujedino poslednja u modulu sa I2C rutinama:

;------------------------------------------------------------------------------read_i2c ; u ovoj ulazni parametar je adresa, izlazni procitani bajt;------------------------------------------------------------------------------ push R8 push R9 push R10 mov.b R12,&ADDRI2C call #I2C_Start mov.b #0xA0 , &RXTXI2C ; Puni se Receive/Transmit registar adresom uredjaja i R/W=0, call #I2C_TX ; Send hardware adress and R/W bit mov.b &ADDRI2C,&RXTXI2C ; Puni se Receive/Transmit adresom memorijske lokacije

; za citanje call #I2C_TX ; Upisuje se memorijska lokacija u adress counter I2C memorije call #I2C_Start mov.b #0xA1 , &RXTXI2C ; Puni se Receive/Transmit registar adresom uredjaja i R/W=1, call #I2C_TX ; Send hardware adress and R/W bit call #I2C_RX ; prima podatak, smesta ga u RXTXI2C call #I2C_Stop ; zavrsetak prenosa mov.b &DATAI2C,R12 ; funkcija vraca glavnom programu procitani bajt pop R10 pop R9 pop R8I2C_End ret ; Vraca se u glavni program

ENDMOD

Kod 15.8 Čitanje bajta podatka iz I2C EEPROM memorije

Slika 15.4 Protokol za upis bajta podatka u I2C EEPROM memoriju

Page 108: Diplomski+rad+Marko+Atanasievski+

Rutina wait je prikazana na nekoliko mesta u prethodnim poglavljima.

U glavnom programu ćemo prvo upisati jedan string, iz niza upisani_string u I2C memoriju, a zatim ga pročitati i smestiti u niz ocitani_string.

#include "msp430x44x.h"#include "string.h"

void initialisation(void);extern void wait(int broj_taktova_podeljen_sa_tri);extern void write_i2c(int podatak, int adresa);extern int read_i2c(int adresa);

char upisani_string[32];char ocitani_string[32]="";

int adresa=0;int podatak=0;int kasnjenje=1;

int main( void ){ int i=0; initialisation(); strcpy(upisani_string,"Proba I2C EEPROMA"); //string koji ce biti upisan u memoriju

//se smesta u upisani_string adresa=0x00; //pocetna adresa upisa

for (i=0;i<strlen(upisani_string);i++) //petlja koja upisuje karakter po karakter// u I2C memoriju

{ podatak=upisani_string[i]; write_i2c(podatak,adresa); adresa++; } adresa=0x00; //pocetna adresa citanja

for (i=0;i<strlen(upisani_string);i++) //petlja koja cita karakter po karakter i smesta //u ocitani_string

{ ocitani_string[i]=read_i2c(adresa); adresa++; }

while (1) {}

}

Page 109: Diplomski+rad+Marko+Atanasievski+

Kod 15.9 Glavni program koji upisuje u i čiza string iz I2C EEPROM memorije

Page 110: Diplomski+rad+Marko+Atanasievski+

PRILOG A Fajl sa definicijama simboličkih oznaka korišćenih u

radu sa razvojnom pločom

/************************************************************* Fajl sa definicijama simbolickih oznaka za razvojnu plocu saMSP430F449 mikrokontrolerom. ETF Beograd, 2008. god.***********************************************************/

/************************************************************* A/D***********************************************************/

#define AD_KANAL1PIN (0x0010)#define AD_KANAL2PIN (0x0020)#define AD_KANAL3PIN (0x0040)#define AD_KANAL4PIN (0x0080)

#define PADIN_ (0x0034) /* AD Port 6 Input */READ_ONLY DEFC( PADIN , PADIN_)#define PADOUT_ (0x0035) /* AD Port 6 Output */DEFC( PADOUT , PADOUT_)#define PADDIR_ (0x0036) /* AD Port 6 Direction */DEFC( PADDIR , PADDIR_)#define PADSEL_ (0x0037) /* AD Port 6 Selection */DEFC( PADSEL , PADSEL_)

/************************************************************* Eksterni tasteri***********************************************************/

#define TASTS4PIN (0x0004)#define TASTS3PIN (0x0010)#define TASTS2PIN (0x0020)#define TASTS1PIN (0x0008)

#define PTAST234IN_ (0x0020) /* Port 1 Input */READ_ONLY DEFC( PTAST234IN , PTAST234IN_)#define PTAST234OUT_ (0x0021) /* Port 1 Output */DEFC( PTAST234OUT , PTAST234OUT_)#define PTAST234DIR_ (0x0022) /* Port 1 Direction */DEFC( PTAST234DIR , PTAST234DIR_)#define PTAST234IFG_ (0x0023) /* Port 1 Interrupt Flag */DEFC( PTAST234IFG , PTAST234IFG_)#define PTAST234IES_ (0x0024) /* Port 1 Interrupt Edge Select */DEFC( PTAST234IES , PTAST234IES_)#define PTAST234IE_ (0x0025) /* Port 1 Interrupt Enable */DEFC( PTAST234IE , PTAST234IE_)#define PTAST234SEL_ (0x0026) /* Port 1 Selection */DEFC( PTAST234SEL , PTAST234SEL_)

Page 111: Diplomski+rad+Marko+Atanasievski+

#define PTAST1IN_ (0x0034) /* Port 6 Input */READ_ONLY DEFC( PTAST1IN , PTAST1IN_)#define PTAST1OUT_ (0x0035) /* Port 6 Output */DEFC( PTAST1OUT , PTAST1OUT_)#define PTAST1DIR_ (0x0036) /* Port 6 Direction */DEFC( PTAST1DIR , PTAST1DIR_)#define PTAST1SEL_ (0x0037) /* Port 6 Selection */DEFC( PTAST1SEL , PTAST1SEL_)

/************************************************************* LED displej***********************************************************/

#define ssel1 (0x0080)#define ssel2 (0x0040)#define ssel3 (0x0020)#define ssel4 (0x0010)#define ssel5 (0x0008)#define ssel6 (0x0004)

#define PsselIN_ (0x0030) /* Port 5 Input */READ_ONLY DEFC( PsselIN , PsselIN_)#define PsselOUT_ (0x0031) /* Port 5 Output */DEFC( PsselOUT , PsselOUT_)#define PsselDIR_ (0x0032) /* Port 5 Direction */DEFC( PsselDIR , PsselDIR_)#define PsselSEL_ (0x0033) /* Port 5 Selection */DEFC( PsselSEL , PsselSEL_)

#define SegA (0x0002)#define SegB (0x0004)#define SegC (0x0008)#define SegD (0x0010)#define SegE (0x0020)#define SegF (0x0040)#define SegG (0x0080)

#define PSegIN_ (0x001C) /* Port 4 Input */READ_ONLY DEFC( PSegIN , PSegIN_)#define PSegOUT_ (0x001D) /* Port 4 Output */DEFC( PSegOUT , PSegOUT_)#define PSegDIR_ (0x001E) /* Port 4 Direction */DEFC( PSegDIR , PSegDIR_)#define PSegSEL_ (0x001F) /* Port 4 Selection */DEFC( PSegSEL , PSegSEL_)

/************************************************************* Tastature T1 i T2***********************************************************/

/* ssel signali i Pssel port su definisani u delu koda za led displej*/

#define TAST1 (0x0080)#define TAST2 (0x0040)#define TAST3 (0x0080)#define TAST4 (0x0040)

#define PTAST34IN_ (0x0020) /* Port 1 Input */READ_ONLY DEFC( PTAST34IN , PTAST34IN_)#define PTAST34OUT_ (0x0021) /* Port 1 Output */DEFC( PTAST34OUT , PTAST34OUT_)

Page 112: Diplomski+rad+Marko+Atanasievski+

#define PTAST34DIR_ (0x0022) /* Port 1 Direction */DEFC( PTAST34DIR , PTAST34DIR_)#define PTAST34IFG_ (0x0023) /* Port 1 Interrupt Flag */DEFC( PTAST34IFG , PTAST34IFG_)#define PTAST34IES_ (0x0024) /* Port 1 Interrupt Edge Select */DEFC( PTAST34IES , PTAST34IES_)#define PTAST34IE_ (0x0025) /* Port 1 Interrupt Enable */DEFC( PTAST34IE , PTAST34IE_)#define PTAST34SEL_ (0x0026) /* Port 1 Selection */DEFC( PTAST34SEL , PTAST34SEL_)

#define PTAST12IN_ (0x0028) /* Port 2 Input */READ_ONLY DEFC( PTAST12IN , PTAST12IN_)#define PTAST12OUT_ (0x0029) /* Port 2 Output */DEFC( PTAST12OUT , PTAST12OUT_)#define PTAST12DIR_ (0x002A) /* Port 2 Direction */DEFC( PTAST12DIR , PTAST12DIR_)#define PTAST12IFG_ (0x002B) /* Port 2 Interrupt Flag */DEFC( PTAST12IFG , PTAST12IFG_)#define PTAST12IES_ (0x002C) /* Port 2 Interrupt Edge Select */DEFC( PTAST12IES , PTAST12IES_)#define PTAST12IE_ (0x002D) /* Port 2 Interrupt Enable */DEFC( PTAST12IE , PTAST12IE_)#define PTAST12SEL_ (0x002E) /* Port 2 Selection */DEFC( PTAST12SEL , PTAST12SEL_)

/************************************************************* Inteligentni lcd displej***********************************************************/

#define PLCDIN_ (0x0018) /* Port 3 Input */READ_ONLY DEFC( PLCDIN , PLCDIN_)#define PLCDOUT_ (0x0019) /* Port 3 Output */DEFC( PLCDOUT , PLCDOUT_)#define PLCDDIR_ (0x001A) /* Port 3 Direction */DEFC( PLCDDIR , PLCDDIR_)#define PLCDSEL_ (0x001B) /* Port 3 Selection */DEFC( PLCDSEL , PLCDSEL_)

#define DB7 (0x0080)#define DB6 (0x0040)#define DB5 (0x0020)#define DB4 (0x0010)#define UCLK (0x0008)#define SIMO (0x0002)#define STE (0x0001)

#define en (0x0001)#define rw (0x0002)#define rs (0x0008)

/************************************************************* PWM temperaturni senzor***********************************************************/

#define PPWMTSIN_ (0x0020) /* Port 1 Input */READ_ONLY DEFC( PPWMTSIN , PPWMTSIN_)#define PPWMTSOUT_ (0x0021) /* Port 1 Output */DEFC( PPWMTSOUT , PPWMTSOUT_)#define PPWMTSDIR_ (0x0022) /* Port 1 Direction */DEFC( PPWMTSDIR , PPWMTSDIR_)#define PPWMTSIFG_ (0x0023) /* Port 1 Interrupt Flag */DEFC( PPWMTSIFG , PPWMTSIFG_)#define PPWMTSIES_ (0x0024) /* Port 1 Interrupt Edge Select */DEFC( PPWMTSIES , PPWMTSIES_)

Page 113: Diplomski+rad+Marko+Atanasievski+

#define PPWMTSIE_ (0x0025) /* Port 1 Interrupt Enable */DEFC( PPWMTSIE , PPWMTSIE_)#define PPWMTSSEL_ (0x0026) /* Port 1 Selection */DEFC( PPWMTSSEL , PPWMTSSEL_)

#define PWMTSPIN (0x0002)

/************************************************************* 1 WIRE DS1820***********************************************************/

#define PDS1820IN_ (0x0028) /* Port 2 Input */READ_ONLY DEFC( PDS1820IN , PDS1820IN_)#define PDS1820OUT_ (0x0029) /* Port 2 Output */DEFC( PDS1820OUT , PDS1820OUT_)#define PDS1820DIR_ (0x002A) /* Port 2 Direction */DEFC( PDS1820DIR , PDS1820DIR_)#define PDS1820IFG_ (0x002B) /* Port 2 Interrupt Flag */DEFC( PDS1820IFG , PDS1820IFG_)#define PDS1820IES_ (0x002C) /* Port 2 Interrupt Edge Select */DEFC( PDS1820IES , PDS1820IES_)#define PDS1820IE_ (0x002D) /* Port 2 Interrupt Enable */DEFC( PDS1820IE , PDS1820IE_)#define PDS1820SEL_ (0x002E) /* Port 2 Selection */DEFC( PDS1820SEL , PDS1820SEL_)

#define DS1820PIN (0x0004)

/************************************************************* SPI periferije***********************************************************/

#define DIO4 (0x0001)#define DIO5 (0x0002)#define DIO6 (0x0004)

#define PSPIDECODIN_ (0x0034) /* Port 6 Input */READ_ONLY DEFC( PSPIDECODIN , PSPIDECODIN_)#define PSPIDECODOUT_ (0x0035) /* Port 6 Output */DEFC( PSPIDECODOUT , PSPIDECODOUT_)#define PSPIDECODDIR_ (0x0036) /* Port 6 Direction */DEFC( PSPIDECODDIR , PSPIDECODDIR_)#define PSPIDECODSEL_ (0x0037) /* Port 6 Selection */DEFC( PSPIDECODSEL , PSPIDECODSEL_)

#define PSPIIN_ (0x0018) /* Port 3 Input */READ_ONLY DEFC( PSPIIN , PSPIIN_)#define PSPIOUT_ (0x0019) /* Port 3 Output */DEFC( PSPIOUT , PSPIOUT_)#define PSPIDIR_ (0x001A) /* Port 3 Direction */DEFC( PSPIDIR , PSPIDIR_)#define PSPISEL_ (0x001B) /* Port 3 Selection */DEFC( PSPISEL , PSPISEL_)

#define CS1 (0x0001)#define CS2 (0x0002)

/************************************************************

Page 114: Diplomski+rad+Marko+Atanasievski+

*I2C periferije***********************************************************/#define PSDAIN_ (0x0028) /* Port 2 Input */READ_ONLY DEFC( PSDAIN , PSDAIN_)#define PSDAOUT_ (0x0029) /* Port 2 Output */DEFC( PSDAOUT , PSDAOUT_)#define PSDADIR_ (0x002A) /* Port 2 Direction */DEFC( PSDADIR , PSDADIR_)#define PSDAIFG_ (0x002B) /* Port 2 Interrupt Flag */DEFC( PSDAIFG , PSDAIFG_)#define PSDAIES_ (0x002C) /* Port 2 Interrupt Edge Select */DEFC( PSDAIES , PSDAIES_)#define PSDAIE_ (0x002D) /* Port 2 Interrupt Enable */DEFC( PSDAIE , PSDAIE_)#define PSDASEL_ (0x002E) /* Port 2 Selection */DEFC( PSDASEL , PSDASEL_)

#define PSCLIN_ (0x0020) /* Port 1 Input */READ_ONLY DEFC( PSCLIN , PSCLIN_)#define PSCLOUT_ (0x0021) /* Port 1 Output */DEFC( PSCLOUT , PSCLOUT_)#define PSCLDIR_ (0x0022) /* Port 1 Direction */DEFC( PSCLDIR , PSCLDIR_)#define PSCLIFG_ (0x0023) /* Port 1 Interrupt Flag */DEFC( PSCLIFG , PSCLIFG_)#define PSCLIES_ (0x0024) /* Port 1 Interrupt Edge Select */DEFC( PSCLIES , PSCLIES_)#define PSCLIE_ (0x0025) /* Port 1 Interrupt Enable */DEFC( PSCLIE , PSCLIE_)#define PSCLSEL_ (0x0026) /* Port 1 Selection */DEFC( PSCLSEL , PSCLSEL_)

#define SCLPIN (0x01)#define SDAPIN (0x02)

/************************************************************* PWM izlazi***********************************************************/

#define PPWMIN_ (0x0018) /* Port 3 Input */READ_ONLY DEFC( PPWMIN , PPWMIN_)#define PPWMOUT_ (0x0019) /* Port 3 Output */DEFC( PPWMOUT , PPWMOUT_)#define PPWMDIR_ (0x001A) /* Port 3 Direction */DEFC( PPWMDIR , PPWMDIR_)#define PPWMSEL_ (0x001B) /* Port 3 Selection */DEFC( PPWMSEL , PPWMSEL_)

#define PWM1PIN (0x0010)#define PWM2PIN (0x0020)#define PWM3PIN (0x0040)#define PWM4PIN (0x0080)

Page 115: Diplomski+rad+Marko+Atanasievski+

LITERATURA

[1] MSP430x4xx Family User's Guide (Rev. E)http://focus.ti.com/lit/ug/slau056e/slau056e.pdf

[2] KS0066U 16COM / 40SEG DRIVER & CONTROLLER FOR DOT MATRIX LCDwww.topwaydisplay.com/Pub/IC_DataSheet/Ks0066u.pdf

[3] MCP41XXX/42XXX Single/Dual Digital Potentiometer with SPI™ Interfacewww.e-1.pk.edu.pl/materialy/MCP41xxx%20Single%20Digital%20Potentiometer%20with%20SPI.pdf

[4] DS1820 1–Wire Digital Thermometerwww.systronix.com/Resource/ds1820.pdf

[5] SMT16030 DIGITAL TEMPERATURE SENSORwww.smartec.nl/pdf/DSSMT16030.PDF

[6] ST24C04, ST25C04, ST24W04, ST25W04 4 Kbit Serial I2C Bus EEPROM with User-Defined Block Write Protectionhttp://www.elenota.pl/d.php?pid=61347&pdf=2435

[7] 25C320 32K 5.0V SPI Bus Serial EEPROMwww.gaw.ru/doc/Microchip/21159B.PDF

[8] Razvojni sistem za mikrokontroler MSP430, D. Skorković, diplomski rad, ETF u Beogradu

[9] Interfacing the DAC8574 to the MSP430F449focus.ti.com.cn/cn/lit/an/slaa189/slaa189.pdf

[10] MSP430 IAR Assembler Reference Guide for Texas Instruments MSP430 Microcontroller Family

Page 116: Diplomski+rad+Marko+Atanasievski+