Mikrokontrolery_ARM_cz19(1).pdf
(
350 KB
)
Pobierz
109-110_arm_cz19.indd
KURS
Mikrokontrolery z rdzeniem ARM,
część 19
Interfejsy szeregowe: I
2
C – przykład
Niestety w zestawie ZL6ARM,
który jest naszą platformą sprzę-
tową, nie ma żadnego urządzenia
podłączonego do magistrali I
2
C, dla-
tego przed uruchomieniem przykła-
du będziemy musieli przeprosić się
z lutownicą i zmontować na „pa-
jąku” układ z pamięcią AT24C128
przedstawiony na
rys. 54
. Linie
SDA i SCL zgodnie ze specyfikacją
I
2
C są „podciągnięte” za pomocą re-
zystorów 10 kV do plusa napięcia
zasilającego. Tak podłączona pamięć
będzie widoczna na magistrali pod
adresem 0xA0. Na
list.
10
poka-
zano fragment programu (
ep8c.zip
,
dostępny na CD–EP6/2007B) reali-
zujący procedury zapisu i odczytu
pamięci AT24C128.
Funkcja
EepromInit()
dokonuje
inicjalizacji kontrolera I
2
C. Najpierw
ustawiane są funkcje alternatywne
portu, tak aby pełniły one rolę li-
nii SDA oraz SCL, ustawiana jest
prędkość transmisji magistrali I
2
C,
a na koniec włączany jest kontroler
magistrali. Funkcja
EepromWrite()
za-
pisuje pod adresem
addr
w pamię-
ci AT24C128 liczbę
val
. Operacja
ta rozpoczyna się od nadania bitu
startu poprzez ustawienie bitu STA
w rejestrze I2C0CONSET, następnie
program wchodzi do pętli, w któ-
rej w zależności od odpowiedniego
stanu rejestru I2C0STAT podejmu-
je określone czynności. Po nada-
niu bitu startu, rejestr I2C0STAT
przyjmuje wartość 0x08, w wyniku
czego do rejestru I2C0DAT wpisy-
wany jest sprzętowy adres pamięci
EEPROM, ustawiany jest bit po-
twierdzenia i kasowany bit startu.
Następnie kasowany jest bit SI, co
powoduje wykonanie następnego
Omówiliśmy rejestry niezbędne do posługiwania
się sprzętowym interfejsem I
2
C, zatem możemy
przystąpić do części praktycznej. W artykule
przedstawiamy przykład obsługi pamięci EEPROM
dołączanej do mikrokontrolera LPC za pomocą
magistrali I
2
C.
List. 10.
/Ustawienia kontrolera VIC
#define
SCL0_P02_SEL (1<<4)
#define
SDA0_P03_SEL (1<<6)
//Adres urzadzenia na magistrali I2C
#define
I2C_MEMADDR 0xA0
/* Inicjalizuje interfejs I2C pamiec AT24C128*/
void
EepromInit(
void
)
{
PINSEL0 |= SCL0_P02_SEL | SDA0_P03_SEL;
//FI2C = PCLK/(SCLL+SCLH) – 100KHz
I2C0SCLL = 300;
I2C0SCLH = 300;
//Wyzeruj wszystkie flagi
I2C0CONCLR = 0x6C;
//Wlacz interfejs I2C – MASTER
I2C0CONSET = I2C0CONSET_I2EN;
}
/* Zapisuje komorke pamieci AT24C128
* addr – adres komorki pamieci do zapisania
* val – vartosc liczbowa do zapisania
* Zwraca 0 dla sukces lub wartosc ujemna dla bledu
*/
int
EepromWrite(
unsigned
short
addr,
unsigned
char
val)
{
int
tmp;
//Licznik nadanych bajtow
int
cnt = 0;
//Rozpocznij nadawanie bitu start
I2C0CONSET = I2C0CONSET_STA;
//Petla oczekiwania
while
(1)
{
//Czekaj na zdarzenia
while
(I2C0STAT==0xF8);
//Status magistrali
switch
(I2C0STAT)
{
//Bit start zostal nadany
case
0x08:
//Wyslij adres pamieci I2C
I2C0DAT = I2C_MEMADDR;
I2C0CONSET = I2C0CONSET_AA;
I2C0CONCLR = I2C0CONCLR_SIC|I2C0CONCLR_STAC;
break
;
//Adres I2C zostal nadany
case
0x18:
//Wyslij starszy bajt adresu
I2C0DAT = addr>>8;
I2C0CONSET = I2C0CONSET_AA;
I2C0CONCLR = I2C0CONCLR_SIC;
cnt=0;
break
;
//Dane zostaly nadane
case
0x28:
//Pierwszy raz
if
(cnt==0)
{
//Mlodsza czesc adresu
I2C0DAT = addr;
I2C0CONSET = I2C0CONSET_AA;
I2C0CONCLR = I2C0CONCLR_SIC;
}
//Drugi raz
else
if
(cnt==1)
{
//Dana do umiesczenia w komorce pamieci
I2C0DAT = val;
I2C0CONSET = I2C0CONSET_AA;
I2C0CONCLR = I2C0CONCLR_SIC;
}
Rys. 54.
Elektronika Praktyczna 6/2007
109
KURS
polecenia przez kontroler I
2
C. Po
nadaniu adresu sprzętowego w ten
sam sposób jest nadawana starsza
część adresu pamięci, następnie
młodsza część adresu pamięci oraz
dane do zapisania. Na zakończe-
nie nadawany jest bit stopu. Jeśli
rejestr I2C0STAT przyjmie wartość
inną od wyszczególnionych w sek-
cjach
case
, oznacza to wystąpienie
błędu. Funkcja wychodzi wówczas
z pętli głównej i zwraca wartość
mniejszą od zera. Funkcja
ReadE-
eprom()
odczytuje bajt spod adresu
pamięci EEPROM wskazanego jako
argument. Jest ona nieco bardziej
skomplikowana od poprzedniej
z uwagi na to, że najpierw musi-
my zapisać do pamięci adres, spod
którego chcemy odczytać dane. Na-
stępnie musimy wysłać ponownie
bit startu, przesłać adres sprzętowy
tym razem z najmłodszym bitem
ustawionym do odczytu i dopiero
po tej czynności dane mogą być
odczytane z pamięci. Ponieważ od-
czytujemy tylko jeden bajt danych,
w stanie po wysłaniu adresu w try-
bie do odczytu (0x58) zerujemy
bit AA w rejestrze I2C0CONCLR,
w wyniku czego nie zostanie wy-
słane potwierdzenie. Będzie to sy-
gnałem dla układu podrzędnego, że
jest to ostatnia dana. W przypadku,
gdy chcielibyśmy przesłać większą
ilość danych, należy bit AA usta-
wić, a wyzerować tuż przed od-
bieraniem ostatniego bajtu danych.
Funkcje te zostały napisane bez
użycia systemu przerwań, tak aby
pokazać samą ideę użycia kontrole-
ra I
2
C. Bez wykorzystania systemu
przerwań pożytek ze sprzętowego
interfejsu I
2
C w trybie nadrzędnym
i tak jest niewielki, ponieważ mi-
krokontroler w aktywnej pętli cały
czas zajmuje się badaniem rejestru
statusu. Dopiero wykorzystanie sys-
temu przerwań pozwoli wykorzy-
stać procesor do realizacji innych
zadań.
Program
Ep8c.zip
wykorzystu-
jąc poprzednio omówione proce-
dury interfejsu UART, wysyła na-
pis powitalny, a następnie oczekuje
od użytkownika wpisania komendy
write=tekst
Wydanie tej komendy
powoduje zapisanie w zewnętrznej
pamięci EEPROM łańcucha teksto-
wego, którego odczyt jest możliwy
za pomocą komendy
read
.
Lucjan Bryndza, EP
lucjan.bryndza@ep.com.pl
List. 10. c.d.
//Trzeci raz
else
if
(cnt==2)
{
//Wyslij STOP
I2C0CONSET = I2C0CONSET_AA|I2C0CONSET_STO;
I2C0CONCLR = I2C0CONCLR_SIC;
return
0;
}
cnt++;
break
;
//Jezeli blad zatrzymaj i wyjdz
default
:
tmp = I2C0STAT;
I2C0CONSET = I2C0CONSET_AA|I2C0CONSET_STO;
I2C0CONCLR = I2C0CONCLR_SIC;
return
–tmp;
}
}
}
/* Odczytuje komorke pamieci AT24C128
* addr – adres komorki pamieci
* Zwraca zawartosc komorki gdy OK w przypadku bledu
* zwraca wartosc mniejsza od zera
*/
int
EepromRead(
unsigned
short
addr)
{
int
tmp;
int
cnt = 0;
//Transmit Start BIT
I2C0CONSET = I2C0CONSET_STA;
//Petla oczekiwania
while
(1)
{
//Czekaj na zdarzenie
while
(I2C0STAT==0xF8);
//Okresl rodzaj
switch
(I2C0STAT)
{
//Bit startu nadany
case
0x08:
//Wyslij Adres pamieci I2C
I2C0DAT = I2C_MEMADDR;
I2C0CONSET = I2C0CONSET_AA;
I2C0CONCLR = I2C0CONCLR_SIC|I2C0CONCLR_STAC;
break
;
//Adres zostal nadany
case
0x18:
//Wyslij starsza czesc adresu
I2C0DAT = addr>>8;
I2C0CONSET = I2C0CONSET_AA;
I2C0CONCLR = I2C0CONCLR_SIC;
cnt=0;
break
;
//Dane zostaly nadane
case
0x28:
//Pierwszy raz
if
(cnt==0)
{
//Wyslij mlodsza czesc adresu
I2C0DAT = addr;
I2C0CONSET = I2C0CONSET_AA;
I2C0CONCLR = I2C0CONCLR_SIC;
}
else
{
//Wyslij ponowny bit startu
I2C0CONSET = I2C0CONSET_STA;
I2C0CONCLR = I2C0CONCLR_SIC;
}
cnt++;
break
;
//Kolejny bit startu zostal nadany
case
0x10:
//Nadaj adres I2C w trybie read
I2C0DAT = I2C_MEMADDR|1;
I2C0CONSET = I2C0CONSET_AA;
I2C0CONCLR = I2C0CONCLR_SIC|I2C0CONCLR_STAC;
break
;
//Wyslano adres pomyslnie
case
0x40:
//Rozpocznik odbieranie danej
I2C0CONCLR = I2C0CONCLR_SIC|I2C0CONCLR_AAC;
break
;
//Odebrano dana – pierwsza i ostatnia
case
0x58:
//Wyslij stop
tmp = I2C0DAT;
I2C0CONSET = I2C0CONSET_AA|I2C0CONSET_STO;
I2C0CONCLR = I2C0CONCLR_SIC;
return
tmp;
//Jezeli blad
default
:
//Zatrzymaj i wyjdz
tmp = I2C0STAT;
I2C0CONSET = I2C0CONSET_AA|I2C0CONSET_STO;
I2C0CONCLR = I2C0CONCLR_SIC;
return
–tmp;
}
}
}
110
Elektronika Praktyczna 6/2007
Plik z chomika:
mga0
Inne pliki z tego folderu:
Mikrokontrolery_ARM_cz22.pdf
(397 KB)
Mikrokontrolery_ARM_cz21.pdf
(747 KB)
Mikrokontrolery_ARM_cz20.pdf
(364 KB)
Mikrokontrolery_ARM_cz19(1).pdf
(350 KB)
Mikrokontrolery_ARM_cz19.pdf
(350 KB)
Inne foldery tego chomika:
• Mikrokontrolery
• Mikrokontrolery i układy cyfrowe
0001-0999
1000-1999
2000-2999
Zgłoś jeśli
naruszono regulamin