K U R S
Mikrokontrolery z rdzeniem ARM,
część 18
Interfejsy szeregowe: UART (dokończenie) i I2C
Program z list. 8, chociaż jest W każdym systemie mikroprocesorowym zachodzi
w pełni funkcjonalny. ma pewną
potrzeba wymiany informacji z otoczeniem na
wadÄ™: mianowicie port szerego-
przykład z innymi komputerami, czy urządzeniami
wy mikrokontrolera obsługiwany
peryferyjnymi podłączanymi do systemu.
jest w programie głównym poprzez
Najbardziej naturalnym sposobem przesyłania
sprawdzanie rejestru LSR. W przy-
padku, gdy współpracuje on z ter- danych są magistrale równoległe, w których dane przesyłane są
minalem nie jest to szczególnie
jednocześnie w porcjach odpowiadających długości słowa maszynowego
uciążliwe, jednak gdy potrzebna
mikroprocesora. Jednak taki sposób przesyłania danych jest kłopotliwy
jest komunikacja z wykorzystaniem
ze względu na dużą liczbę połączeń, gdzie już nawet w przypadku
jakiegoś protokołu (pomimo istnie-
prostego 8 bitowego systemu mikroprocesorowego musimy podłączyć
nia 15 znakowego bufora FIFO)
8 linii danych, 16 linii adresowych i kilkanaście linii sterujących.
istnieje duże prawdopodobieństwo
utraty danych, gdy mikroprocesor
W przypadku połączenia równoległego z innymi urządzeniami
będzie zajęty jakąś pracochłonną
zewnętrznymi na przykład dwoma systemami mikroprocesorowymi
protokołową czynnością oblicze-
znajdującymi się na przeciwnych końcach pomieszczenia wiązałoby
niowÄ…. Z tego powodu porty sze-
się z koniecznością użycia drogich wielożyłowych przewodów.
regowe w mikrokontrolerach LPC
mają możliwość zgłaszania prze-
rwań. Port szeregowy możemy za- Odczytując zawartość rejestru MSR_EN Flaga aktywacji prze-
programować tak, aby wysyłanie IIR w procedurze obsługi przerwania rwania informującego o zmianie reje-
i odbieranie danych odbywało się możemy określić powód wystąpie- stru statusu linii modemu (MSR).
za pomocÄ… procedury przerwania nia przerwania. Zmiana statusu linii CTS_EN Flaga aktywacji prze-
natomiast samo wysyłanie danych (011), mówi nam że zawartość reje- rwania od linii CTS (tylko drugi
w programie głównym sprowadzać stru LSR zmieniła się czego przy- UART układów 21x4/6/8).
się będzie do zapisania lub odczy- czyną mogło być wystąpienie jakie- Oprócz aktywacji generowania
tania bufora. W układzie 16550 do goś błędu. Zdarzenie Timeout (110) przerwania w samym układzie portu
dyspozycji mamy dodatkowy rejestr informuje nas, że zakończono od- szeregowego, musimy odpowiednio
IIR (Interrupt Information Register), bieranie danych, ale bufor FIFO od- skonfigurować wektoryzowany kontro-
który pozwala określić przyczynę biornika nie zapełnił się. Zdarzenie ler przerwań (VIC). Na list. 9 przed-
wystąpienia przerwania: przerwania od linii modemowych stawiono procedury obsługi portu
występuje tylko w przypadku drugie- szeregowego wysyłające i odbierające
FIFO_EN IDENT INT
go portu szeregowego w mikrokontro- informacjÄ™ z terminala ale tym razem
7 6 5 4 3 2 1 0
lerach 21x4/21x6/21x8. Aby przerwa- z wykorzystaniem systemu przerwań.
Rys. 44. Rejestr U1IIR (0xE0010008) nia w ogóle zostały wygenerowane Podobnie jak poprzednio funk-
U0IIR (0xE000C008) należy je wcześniej włączyć w reje- cja Uart0Init() inicjalizuje port sze-
strze IER (Interrupt Enable Register), regowy z prędkością przekazaną jako
INT flaga zgłoszenia przerwa- który pozwala nam na aktywację argument. Procedura ta jest prawie
nia, aktywna w stanie 0 pożądanego rodzaju przerwania: identyczna jak poprzednio, różni się
IDENT określa przyczynę wy- jedynie ustawieniem rejestru U0IER
CTS_ MSR_ RLS_ THRE_ RBR_
stąpienia przerwania: tak aby zgłaszane było przerwanie od
EN EN EN EN EN
011 zmiana statusu linii nadanych oraz odebranych znaków,
7 6 5 4 3 2 1 0
010 odebrano nowe dane oraz inicjalizacją kontrolera przerwań
110 timeout. Przez okres Rys. 45. Rejestr U1IER (0xE0010004) VIC. Przerwanie od portu szerego-
3,5 4,5 znaku nie odebrano U0IER (0xE000C004) wego zostało w VIC ustawione jako
żadnych danych wektoryzowane. W momencie zgłosze-
001 bufor nadajnika jest RBR_EN Flaga aktywacji prze- nia przerwania od portu szeregowego
wolny rwania od odebranych znaków oraz mikroprocesor rozpoczyna wykony-
000 przerwanie od linii od przeterminowania znaku (timeout). wanie funkcji Uart0Int, która stano-
modemowych (Tylko LPC THRE_EN Flaga aktywacji wi procedurę jego obsługi. Najpierw
2134/2136/2138/2144/2146/ przerwania informującego o pustym określana jest przyczyna wystąpienia
2148) buforze nadajnika. przerwania poprzez odczytanie reje-
FIFO_EN załączenie kolejki RLS_EN Flaga aktywacji prze- stru IIR. W przypadku gdy okaże się,
FIFO są to odpowiedniki bitu EN rwania informującego o zmianie re- że jest to przerwanie od przetermino-
z rejestru FCR. jestru statusu (RLS). wania lub odbioru znaku, wówczas
Elektronika Praktyczna 5/2007
105
K U R S
wszystkie odebrane znaki są przepi- List. 9. Procedury obsługi portu szeregowego wysyłające i odbierające dane
sywane w pętli while() z kolejki FIFO z wykorzystaniem przerwań
#include lpc213x.h
portu do bufora. Natomiast, gdy wy-
#include uart.h
stÄ…pi przerwanie od pustego bufora
#include armint.h
nadajnika, wówczas dane z bufora
//Bufor odbiornika
przesyłane są do kolejki FIFO nadaj- static unsigned char rxbuf[TXBUF_SIZE +10];
//Bufor nadajnika
nika Na zakończenie procedury ob-
static unsigned char txbuf[RXBUF_SIZE+10];
sługi zerujemy rejestr VICVectAddr in- //Liczniki nadajnika i odbiornika
volatile static unsigned short txcnt, rxpos, txpos, rxcnt;
formując kontroler przerwań o zakoń-
//Znacznik zajetosci nadajnika
volatile static unsigned char busy;
czeniu procedury obsługi. Wysłanie
znaku w programie głównym wyko-
//Definicje ustawien pinow RXD i TXD
//Ustawienia kontrolera VIC
nujemy za pomocÄ… funkcji Uart0Put-
#define TXD0_P00_SEL (1<<0)
Char(), która albo umieszcza znak
#define RXD0_P01_SEL (1<<2)
//Zapelnienie bufora fifo odbiornika
do nadania w buforze, jeżeli nadajnik
#define U0IIR_RDA_INT 0x04
portu szeregowego jest uruchomiony, //Przez 3,5 znaku nie odebrano danych
#define U0IIR_CTI_INT 0x0C
lub rozpoczyna nadawanie wpisujÄ…c
//Bufor fifo nadajnika pusty
pierwszy znak do rejestru U0THR. #define U0IIR_THRE_INT 0x02
//8 bitow danych
Przed operacjÄ… na buforze oraz jego
#define U0LCR_8Bit_Data 3
wskaznikach musimy pamiętać o wy- //1 bit stopu
#define U0LCR_1Bit_Stop 0
Å‚Ä…czeniu przerwania od portu sze-
//Brak bitu parzystosci
#define U0LCR_No_Parity 0
regowego. W przeciwnym przypadku
//Bufor FIFO na 14 znakow
w momencie zmiany jakiejÅ› zmiennej
#define U0FCR_14Char_Fifo (3<<6)
#define U0_VIC (1<<6)
związanej z buforem mogło by wejść
#define U0_VIC_BIT 6
przerwanie, a ponieważ pozostałe #define VIC_IRQSLOT_EN (1<<5)
//Definicja naglowku przerwania
zmienne związane z obsługą bufora
static void Uart0Int(void) __attribute__ ((interrupt( IRQ )));
nie były by jeszcze zaktualizowane
groziło by to błędnym działaniem
//Funkcja przerwania
void Uart0Int(void)
programu. Funkcja Uart0GetChar()
{
służy do odebrania znaków z portu
unsigned char irqstat = U0IIR & 0x0F;
unsigned char tmp;
szeregowego, w której najpierw jest
if(irqstat==U0IIR_RDA_INT || irqstat==U0IIR_CTI_INT)
sprawdzana ilość odebranych zna- {
//odczytuj dane z fifo dopuki sa
ków i jeżeli jest ona większa od zera
while(U0LSR & U0LSR_RDR)
wówczas wyłączane są przerwania {
if(rxcnt < RXBUF_SIZE)
pobierany jest znak z bufora a następ-
{
nie przerwania włączane są ponow- rxbuf [(rxpos + rxcnt++) % RXBUF_SIZE] = U0RBR;
}
nie. W pliku ep8b.zip znajduje siÄ™
else
{
cały kod programu wykorzystujący
tmp = U0RBR;
powyższe funkcje. Po uruchomieniu
break;
}
wysyła on napis powitalny, a następ-
}
nie na czeka na komendy z termi- }
if(irqstat==U0IIR_THRE_INT)
nala. Zaimplementowano tutaj jednÄ…
{
komendÄ™ SET=n (gdzie n=0& 255), //Mozna nadawac nowy znak
if(txcnt)
której wywołanie powoduje zapalenie
{
busy = 1;
diod D0& D7 zgodnie z reprezentacjÄ…
txcnt ;
bitowÄ… wpisanej liczby.
U0THR = txbuf[txpos++];
if(txpos >= TXBUF_SIZE) txpos = 0;
Mikrokontrolery LPC214x oprócz
}
wspomnianego tutaj dodatkowego re- else
{
jestru dzielnika, posiadajÄ… dodatko-
tmp = U0IIR;
wy układ sprzętowy pozwalający na busy = 0;
}
automatyczne wykrywanie prędkości
}
transmisji, jednak z uwagi na ogra- //Informacja dla kontrolera przerwan
VICVectAddr = 0;
niczone łamy tego artykułu oraz to,
}
że jest to rozszerzeniem standardu
/* Inicjalizacja Uart0 */
16550 nie występującym w mikrokon-
void Uart0Init(unsigned short BaudRate)
{
trolerach LPC213x zostanie on w tym
//Funkcje wyjsciowe UART
miejscu omówiony.
PINSEL0 |= TXD0_P00_SEL | RXD0_P01_SEL;
//DLAB = 1
U0LCR = U0LCR_Divisor_Latch_Access_Bit;
Interfejs I2C //Ustaw predkosci transmisji
U0DLL = (unsigned char)BaudRate;
Kolejnym bardzo popularnym in-
U0DLM = (unsigned char)(BaudRate>>8);
terfejsem szeregowym jest I2C. In- //Ustawienie 8,n,1
U0LCR = U0LCR_8Bit_Data | U0LCR_1Bit_Stop | U0LCR_No_Parity;
terfejs RS232, najczęściej wykorzy-
//Wlacz FIFO na 14 znakow
U0FCR = U0FCR_14Char_Fifo | U0FCR_FIFO_Enable;
stywany był do podłączenia syste-
//Funkcja przerwania wektora 1
mu mikroprocesorowego z odległymi
VICVectAddr1 = (int)Uart0Int;
//Zalaczenie slotu 1
komputerami lub innymi systema-
Elektronika Praktyczna 5/2007
106
K U R S
List. 9. c.d.
niskiego stanu na linii SCL. Sygnał
VICVectCntl1 = U0_VIC_BIT | VIC_IRQSLOT_EN;
START służy do identyfikacji po-
//Kasuj ewentualne znaczniki odbioru nadania znaku
U0LSR = U0IIR = 0; czÄ…tku transmisji po pojawieniu
//Wlaczenie przerwan od RX TX
się tego stanu szyna uważana jest
U0IER = U0IER_RBR_Interrupt_Enable | U0IER_THRE_Interrupt_Enable;
//Zalaczenie przerwania od UART0
za zajętą aż do momentu wystąpie-
VICIntEnable = U0_VIC;
nia sygnału STOP, czyli po stwier-
//Odblokuj przerwania
enable_irq();
dzeniu pojawienia siÄ™ narastajÄ…cego
}
zbocza na linii SDA przy wysokim
stanie linii SCL (rys. 46).
//Nadawanie znaku
Każdy bajt danych przesyłanych
void Uart0PutChar(char c)
{
po szynie I2C musi składać się
//Gdy wszystkie bajty, czekaj na zwolnienie
while(txcnt >= TXBUF_SIZE); z 8 bitów, przy czym dane nada-
//Wylacz na moment przerwanie od RS
wane sÄ… poczÄ…wszy od bitu naj-
cpu_t irqs = disable_irq();
U0IER = 0;
bardziej znaczącego. Liczba bajtów
restore_irq(irqs);
danych przesyłanych w ramach je-
if(busy)
{
den transmisji nie jest ograniczo-
txbuf[(txpos + txcnt++) % TXBUF_SIZE] = c;
na. Każda operacja przesłania bajtu
}
else
danych powinna się zakończyć bi-
{
tem potwierdzenia. Impuls taktujÄ…-
U0THR = c;
busy = 1;
cy zwiÄ…zany z bitem potwierdzenia
}
//Wlaczenie przerwan od RX TX jest generowany przez urzÄ…dzenie
irqs = disable_irq();
nadrzędne. Do magistrali I2C może
U0IER = U0IER_RBR_Interrupt_Enable | U0IER_THRE_Interrupt_Enable;
restore_irq(irqs);
być podłączonych wiele układów
}
nadrzędnych i podrzędnych, jed-
//Odebranie znaku
nak najczęściej spotykaną sytuacją
char Uart0GetChar(void)
będzie mikrokontroler, który pełni
{
int c;
rolę nadrzędną oraz od jednego do
while (!rxcnt); //Czekaj az bedzie znak
//Wylacz na moment przerwanie od RS kilkunastu urządzeń podrzędnych.
cpu_t irqs = disable_irq();
Każde urządzenie na magistrali I2C
U0IER = 0;
restore_irq(irqs);
ma swój 7 bitowy adres (najmłod-
rxcnt ;
szy 8 bit adresu określa kierunek
c = rxbuf[rxpos++];
if (rxpos >= RXBUF_SIZE) rxpos = 0;
przepływu danych) Nie wdając się
//Wlaczenie przerwan od RX TX
w dalsze szczegóły na rys. 47 przed-
irqs = disable_irq();
U0IER = U0IER_RBR_Interrupt_Enable | U0IER_THRE_Interrupt_Enable;
stawiono przebiegi podczas odczytu
restore_irq(irqs);
i zapisu pamięci AT24C128, którą
return c;
}
będziemy wykorzystywać w dalszej
części kursu.
mi mikroprocesorowymi, natomiast transmisji danych impulsy taktujące Gdy do magistrali będzie podłą-
interfejs I2C wykorzystujemy do na szynie SCL wysyłane są w ilości czone tylko jedno urządzenie nad-
podłączenia dodatkowych układów jeden impuls na każdy bit przesy- rzędne będące mikrokontrolerem,
peryferyjnych do mikrokontrolera łanych danych. Podczas wysokiego cały protokół I2C ulega znacznemu
w ramach tego samego systemu. SÄ… stanu na linii SCL stan linii SDA uproszczeniu i jest Å‚atwy do zre-
to różnego rodzaju małe pamięci musi być stabilny stan tej linii alizowania na drodze programowej.
szeregowe, przetworniki A/C i C/A, może ulegać zmianie tylko podczas Większość prostych mikrokontro-
klawiatury wyświetlacze itp. Komu-
nikacja standardzie I2C odbywa siÄ™
szeregowo synchronicznie z zastoso-
waniem dwóch linii SDA oraz SCL.
Są to linie dwukierunkowe podłą-
czone do dodatniej szyny zasila-
jącej za pośrednictwem rezystorów
podciągających o wartości kilkuna-
stu kV. Jeżeli szyna jest zwolniona
(brak transmisji) obie linie znajdu-
jÄ… siÄ™ w stanie wysokim. Podczas
Rys. 47. Zapis jednego bajtu danych do pamięci AT24C128 a), odczyt 1 bajtu
Rys. 46. Definicja bitów start i stop danych z pamięci AT24C128 b)
Elektronika Praktyczna 5/2007
107
K U R S
Tab. 6. Zdarzenia/stany na magistrali
Tab. 5. Przypisania linii I2C do por- kontroler śledzi magistralę I2C
tów I/O mikrokontrolerów LPC213x I2C dla kontrolera pracującego w try-
i w momencie zmiany stanu ma-
bie master
Linia Linia gistrali w rejestrze STAT wystawia
Sygnał Opis
(I2C0) (I2C1)
Kod Zdarzenie
kod zdarzenia jednocześnie zgła-
Linia danych magi- 0x08 Bit START został nadany
szając przerwanie. Program obsługi
SDA P0.3 P0.14
strali I2C
0x10 Powtórzony bit startu został nadany
możemy napisać albo jako proce-
Linia zegarowa magi-
Adres urzÄ…dzenia I2C (kierunek zapis)
durę obsługi przerwania (zalecane),
SCL P0.2 P0.11
0x18
strali I2C
został nadany z potwierdzeniem (ACK)
albo możemy w pętli śledzić jego
Adres urzÄ…dzenia I2C (kierunek zapis)
zawartość.
0x20 został wysłany brak potwierdzenia
lerów 8 bitowych nie ma w ogóle
(ACK)
STAT
wbudowanych sprzętowych kontro-
Dane zostały wysłane z potwierdzeniem
7 6 5 4 3 2 1 0
0x28
lerów I2C. Mikrokontrolery LPC213x/
(ACK)
214x posiadajÄ… wbudowane dwa Rys. 50. Rejestr I2C0STAT (0xE001C004)
Dane zostały wysłane brak potwierdze-
0x30
sprzętowe kontrolery magistrali I2C, I2C1STAT (0xE005C004)
nia (ACK)
które mogą pracować w trybie nad-
Utrata magistrali (inne urzÄ…dzenie ma-
0x38
ster przejęło magistralę)
rzędnym (master) lub podrzędnym W tab. 6 zebrano poszczególne
Adres urzÄ…dzenia I2C (kierunek odczyt)
(slave) Posiadają także wbudowany zdarzenia/stany na magistrali I2C
0x40
został nadany z potwierdzeniem (ACK)
układ pozwalający sterować prędko- dla kontrolera pracującego w trybie
Adres urzÄ…dzenia I2C (kierunek odczyt)
ścią transmisji, oraz układ arbitra- nadrzędnym.
0x48 został wysłany brak potwierdzenia
żu magistrali pozwalający na pracę W momencie zgłoszenia prze-
(ACK)
wielu układów nadrzędnych na jed- rwania procedura obsługi powinna
Dane zostały odebrane i wysłano po-
0x50
nej magistrali. W tab. 5 przedsta- sprawdzić jakie zdarzenie miało
twierdzenie (ACK)
wiono linie magistral I2C mikrokon- miejsce i podjąć odpowiednie czyn-
Dane zostały odebrane i nie wysłano
0x58
trolerów LPC213x. ności. Na przykład jeżeli adres do
potwierdzenia (ACK)
Protokół I2C posługuje się trans- zapisu został nadany, wówczas
Stan jałowy na magistrali nic się nie
0xF8
dzieje
misją synchroniczną, ale z uwagi wywołana zostaje procedura obsłu-
na duże możliwości konfiguracji gi przerwania, która powinna nadać
częstotliwości taktowania układów dane, czego można dokonać poprzez przez wpisanie jedynki do rejestru
peryferyjnych (PCLK), oraz na róż- wydanie odpowiedniego polecenia CONCLR zaraz po jego nadaniu.
ne maksymalne prędkości trans- kontrolerowi I2C. Do wydawania STO ustawienie tego bitu powo-
misji magistrali I2C (Tryb standar- poleceń kontrolerowi służą rejestry duje nadanie bitu stopu na magistrali
dowy 100 kHz lub tryb szybki CONCLR i CONSET wpisanie jedyn- I2C, jest on zerowany automatycznie
400 kHz) wprowadzono specjalne ki do rejestru CONSET powoduje gdy zostanie nadany.
rejestry SCLL SCLH, które pozwala- ustawienie wybranego bitu, nato- SI Bit ten jest ustawiany w mo-
ją na swobodne ustalenie częstotli- miast wpisanie jedynki do rejestru mencie zmiany stanu na magistrali,
wości taktowania magistrali (rys. 48 CONCLR powoduje skasowanie od- czyli jest to flaga zgłoszenia przerwa-
i rys. 49). powiedniego bitu. nia od kontrolera I2C. Aby kontroler
podjÄ…Å‚ wykonywanie kolejnej akcji bit
SCLL
I2EN STA STO SI AA
ten należy wyzerować.
7 6 5 4 3 2 1 0
AA ustawienie tego bitu powodu-
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Rys. 51. Rejestr I2C0NSET (0xE- je, wysłanie bitu potwierdzenia ACK,
Rys. 48. Rejestr I2C0SCLL (E001C014) 001C000) I2C1CONSET (0xE005C000) natomiast jego wyzerowanie powoduje
oraz I2C1SCLL (E005C014) brak nadawania bitu potwierdzenia.
I2ENC STAC STOC SIC AAC
Do rejestru DAT przesyłane są
SCLH
7 6 5 4 3 2 1 0
dane w trybie odczytu, oraz w trybie
Rys. 52. Rejestr I2C0NSET (0xE- zapisu należy umieścić tam dane do
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
001C018) I2C1CONSET (0xE005C018) wysłania:
Rys. 49. Rejestr I2C0SCLH (E001C010)
DAT
oraz I2C1SCLH (E005C010) I2EN ustawienie tego bitu
7 6 5 4 3 2 1 0
powoduje włączenie interfejsu I2C,
Częstotliwość taktowania magi- w przeciwnym wypadku jest on wy- Rys. 53. Rejestr I2C0DAT (0xE001C008)
strali I2C możemy wyznaczyć we- łączony i zmiany na liniach SDA I2C1DAT (0xE005C008)
dług następującego wzoru: i SCL nie są śledzone.
STA ustawienie tego bitu po- Lucjan Bryndza, EP
Pclk
F12 c żÿ
woduje przejście kontrolera w tryb lucjan.bryndza@ep.com.pl
SCLH żÿ SCLL
master i nadanie bitu STARTU, lub
UWAGA! pliki do kursu zostanÄ… zamieszczone
Obsługa sprzętowego interfej- wysłanie bitu ponownego startu.
na CD-EP6/2007B
su I2C oparta jest na zdarzeniach, Bit ten musi być skasowany po-
arm.ep.com.pl
Elektronika Praktyczna 5/2007
108
Wyszukiwarka
Podobne podstrony:
Mikrokontrolery ARM cz1Mikrokontrolery ARM cz10Mikrokontrolery ARM cz14Mikrokontrolery ARM cz8Mikrokontrolery ARM cz12Mikrokontrolery ARM cz15Mikrokontrolery ARM cz21Mikrokontrolery ARM cz19Mikrokontrolery ARM cz3Mikrokontrolery ARM cz6Mikrokontrolery ARM cz22Mikrokontrolery ARM cz11Mikrokontrolery ARM cz13Mikrokontrolery ARM cz17Mikrokontrolery ARM cz5Mikrokontrolery ARM cz20Mikrokontrolery ARM cz7Mikrokontrolery ARM cz9więcej podobnych podstron