PROCESORY SYGNAŁOWE I
MIKROKONTROLERY
Mariusz Pauluk
Wykład IV Mikrokontrolery
Kierunek: Automatyka i Robotyka
AGH, Katedra Automatyki
Architektura Von Neumanna
Rozwinął ją węgierski matematyk: John von Neumann.
Koncepcja ta została po raz pierwszy opublikowana w 1946 roku
wspólnie przez: Burk’a, Goldstine’a i Von Neumanna. Zdominowała
budowę komputerów na następne dziesięciolecia. J. von Neumann
był jednym z konsultantów przy budowie komputera ENIAC.
Podstawowym układem jest ALU (ang. Arithemtic Logic Unit),
wykonuje w kilku cyklach podstawowe operacje, takie jak:
dodawanie, odejmowanie, przesuwanie, zapisywanie do rejestrów.
Bardziej skomplikowane operacje, takie jak: mnożenie i dodawanie
realizowane są za pomocą operacji dodawania, odejmowania i
przesunięcia. Sa to tak zwane urządzenia typu CISC (ang. Complex
Instruction Set Computers), gdzie operacja mnożenia polega na
wykonania kilku mikrokodów zapisanych w pamięci ROM. Dlatego
operacje takie trwają nawet kilkanaście cykli procesora
Cechy charakterystyczne
Architektura von Neumanna
program i dane przechowywane są w tej samej pamięci,
dostęp do programu i danych jest sekwencyjny,
jedna magistrala obsługująca pamięć programu i danych
architektura ta jest łatwiejsza do zrealizowania,
ograniczenia wynikające z niej nie stanowiły poważnego problemu,
przedstawicielami tej technologii są produkty np. Motorola serii
68000, Intel seria i86.
ADRES
DANE I ROZKAZY
Komputer IAS
W 1951 roku zbudowano w Institute for Advanced Studies w Prinston
komputer wg koncepcji Johna von Neumanna, w którym nie wyróżnia się
danych, tylko umieszcza się je razem z programem we wspólnej pamięci i
odczytuje sekwencyjnie.
Schemat blokowy komputera IAS
ALU
UKŁAD
ZARZĄDZAJĄCY
PROGRAMEM
URZĄDZENIA
WEJŚCIA WYJŚCIA
WSPÓLNA PAMIĘĆ
DANYCH I PROGRAMU
Mikroprocesor - architektura
Zespół rejestrów:
dedykowane rejestry – szybsze rozwiązanie (np. Z80)
rejestry stanowią część pamięci RAM – wolniejsze
rozwiązanie (np. ST52x420G2)
Jednostka arytmetyczno - logiczna:
dodawanie, odejmowanie, porównanie dwóch liczb
operacje logiczne AND, OR, EXOR, przesuwanie o n bitów
w lewo lub prawo
operacje na bitach: ustawianie, zerowanie i negowanie bitu
operace wykonywane na liczbach typu : NKB, BCD i U2
Mikroprocesor - architektura
Układ sterowania z dekoderem rozkazów:
faza pobrania kodu operacji,
faza wykonania operacji.
Magistrala adresowa
Magistrala danych
Magistrala sterująca
Mikroprocesor - schemat blokowy
REJESTRY
ALU
UKŁAD
STERUJĄCY
SZYNA DANYCH
SZYNA ADRES.
SZYNA STER.
Mikrokontroler
Jest to mikroprocesor ze zintegrowanymi w jednym układzie
scalonym urządzeniami wejścia wyjścia (I/O). Integracja
realizowana
jest zarówno
na poziomie
sprzętowym
(elektrycznym) jak i logicznym (ingerencja w wewnętrzną
strukturę mikroprocesora.)
Najczęściej mikrokontrolery wyposażane są w:
porty równoległe,
porty szeregowe,
pamięć programu i pamięć danych,
przetworniki A/D i D/A,
moduły komunikacji szeregowej: SPI, I
2
C, RS485,
kontrolery chip-kart,
kontrolery wyświetlacza LCD,
Mikrokontroler - schemat blokowy
REJESTRY
ALU
UKŁAD
STERUJĄCY
SZ. ADR.
SZ. DANYCH
RÓWN. PORTY I/O
SZEREGOWE
PORTY I/O
PAMIĘĆ
PROGRAMU
PAMIĘĆ
DANYCH
KONTROLERY
URZĄDZEŃ
ZINTEGROWAN.
A/D PRZ.
D/A PRZ.
M
A
G
ISTR
A
LE
SZER
EG
O
W
E
I/0
SZ. STER.
L
CD
, 7S
E
G
.
W
Y
ŚW
IE
TL
AC
Z
E
Adresowanie
Adresowanie za pomocą wskaźników: MOV A,@R0
R0
uK
PAMIĘĆ
KOD ROZKAZU
PC
KOMÓRKA Z DANĄ
R0 jest wskaźnikiem
Adresowanie natychmiastowe: MOV A,#13h
uK
PAMIĘĆ
KOD ROZKAZU
PC
KOMÓRKA Z DANĄ
...
Adresowanie
Adresowanie bezpośrednie: MOV A,12h
uK
PAMIĘĆ
KOD ROZKAZU
PC
ADRES = 12h
...
12h
DANA
Adresowanie
Adresowanie indeksowe: MOVX A,@(A+DPTR)
uK
PAMIĘĆ
KOD ROZKAZU
PC
ADRES = 12h
...
12h
DANA
Adresowanie
Adresowanie względne: JP 16H
uK
PAMIĘĆ
KOD ROZKAZU
PC
PRZESUNIĘCIE = 16h
...
PC=PC+16h
∑
Device
Vcc (V)
Pins
TWI
SPI
ISP UART
2,7-5.5
60
2
1
Yes
2.7-5.5
12
16, 24
16
2
Yes
2,7-5.5
66
2
Yes
8
1
Yes
2,7-5.5
66
2
Yes
1
Yes
2,7-5.5
16
40, 44
60
3
1
Yes
2,7-5.5
32
40, 44
60
3
1
Yes
2.7-5.5
12
16
2
Yes
2,7-5.5
66
2
Yes
8
1
Yes
2,7-5.5
60
2
Yes
8
1
Yes
5.0
4
40, 44
33
3
1
Yes
5.0
32
40, 44
33
3
1
Yes
5.0
8
40, 44
33
3
1
Yes
Flash
(Kbytes)
EEPROM
(Kbytes)
Mask
ROM
(Kbytes)
OTP
(Kbytes)
F.max
(MHz)
16-bit
Timer
10-bit
A/D
(chann
els)
Watchd
og
AT80C5112
AT83C5103
AT83C5111
AT83C5112
AT83C51RB2
AT83C51RC2
AT87C5103
AT87C5111
AT87C5112
AT87F51
AT87F51RC
AT87F52
DANE ZE STRONY www.atmel.com
Procesory serii AT80, 83, 87
Device
Vcc (V)
Pins
TWI
SPI
ISP
UART
1
2,7-6.0
20
24
2
1
2
2,7-6.0
20
24
2
1
2
2.7-6.0
20
16
2
1
4
2,7-6.0
20
24
2
1
4
4.0-6.0
40, 44
33
2
1
64
2.7-5.5
2
40
3
Yes
Yes
1
Yes
64
2.7-5.5
2
60
Yes
3
Yes
Yes
Yes
Yes
16
2.7-5.5
40
3
Yes
Yes
1
Yes
32
4.0-6.0
40, 44
33
3
1
Yes
32
2.7-5.5
40
3
Yes
Yes
1
Yes
64
2.7-5.5
40
3
Yes
Yes
1
Yes
8
4.0-6.0
40, 44
33
3
1
20
4.0-6.0
40, 44
33
3
1
Yes
4
2,7-6.0
40, 44
16
2
Yes
1
Yes
8
2,7-6.0
40, 44
16
3
Yes
1
Yes
12
2,7-6.0
40, 44
12
3
Yes
Yes
1
Yes
8
2,7-6.0
2
40, 44
12
3
Yes
Yes
1
Yes
4
2,7-6.0
40, 44
16
2
1
8
2,7-6.0
40, 44
16
3
1
20
2,7-6.0
44
12
3
1
4
4,0-6.0
40, 44
33
2
Yes
1
Yes
8
4,0-6.0
40, 44
33
3
Yes
1
Yes
12
4,0-6.0
40, 44
24
3
Yes
Yes
1
Yes
Flash
(Kbytes)
EEPROM
(Kbytes)
Mask
ROM
(Kbytes)
OTP
(Kbytes)
F.max
(MHz)
16-bit
Timer
10-bit
A/D
(chann
els)
Watchd
og
AT89C1051U
AT89C2051
AT89C2051x2
AT89C4051
AT89C51
AT89C51ED2
AT89C51ID2
AT89C51RB2
AT89C51RC
AT89C51RC2
AT89C51RD2
AT89C52
AT89C55WD
AT89LS51
AT89LS52
AT89LS53
AT89LS8252
AT89LV51
AT89LV52
AT89LV55
AT89S51
AT89S52
AT89S53
Procesory serii AT89
DANE ZE STRONY www.atmel.com
Device
Vcc (V)
Pins
TWI
SPI
ISP
UART
2,7-5.5
16
24, 28
60
3
1
2,7-5.5
8
24, 28
66
3
1
2,7-5.5
16
24, 28
60
3
1
16
###
2
24, 28
40
2
8
Yes
1
Yes
32
###
2
44, 64
40
3
8
Yes
1
Yes
32
2,7-5.5
44
40
Yes
3
Yes
Yes
1
Yes
2,7-5.5
40, 44
60
2
1
2,7-5.5
40, 44
60
3
1
2,7-5.5
40, 44
60
3
2
Yes
2,7-5.5
8
40, 44
60
3
1
2,7-5.5
16
40, 44
60
3
1
Yes
2,7-5.5
32
40, 44
60
3
1
Yes
2,7-5.5
16
40, 44
60
3
1
Yes
2,7-5.5
32
40, 44
60
3
1
Yes
2,7-5.5
64
40, 44, 64, 68 60
3
1
Yes
2,7-5.5
16
40, 44
60
3
2
Yes
2,7-5.5
16
40, 44
60
3
1
Yes
2,7-5.5
32
40, 44
60
3
1
Yes
2,7-5.5
64
40, 44, 64, 68 40
3
1
Yes
2,7-5.5
16
60
3
2
Yes
2,7-5.5
8
40, 44
60
3
1
2,7-5.5
16
40, 44
60
3
1
Yes
2,7-5.5
32
40, 44
60
3
1
Yes
2,7-5.5
40, 44
24
Yes
3
Yes
1
Yes
2,7-5.5
32
40, 44
24
Yes
3
Yes
1
Yes
Flash
(Kbytes)
EEPROM
(Kbytes)
Mask
ROM
(Kbytes)
OTP
(Kbytes)
F.max
(MHz)
16-bit
Timer
10-bit
A/D
(chann
els)
Watchd
og
T83C5101
T83C5102
T87C5101
T89C5115
T89C51AC2
T89C51IC2
TS80C31X2
TS80C32X2
TS80C51U2
TS80C52X2
TS80C54X2
TS80C58X2
TS83C51RB2
TS83C51RC2
TS83C51RD2
TS83C51U2
TS87C51RB2
TS87C51RC2
TS87C51RD2
TS87C51U2
TS87C52X2
TS87C54X2
TS87C58X2
TSC80251G2D
TSC83251G2D
Procesory serii T83, 87, 89
DANE ZE STRONY www.atmel.com
Sprzętowa realizacja układu „watchdog”
P3.0
555
RESET
VCC
τ
=kRC
T<
τ
Q
IMP
AT89C51RB2/RC2 - Watchdog
Watchdog - jest to układ mający na celu nadzorowanie poprawności
wykonywanego przez procesor programu. W przypadku „zawieszenia” się
procesora układ watchdoga powinien podać aktywny sygnał RESET.
W procesorze Atmela funkcję WD’a pełni 14 bitowy licznik oraz rejestr
typu SFR - WDTRST (0A6H). Po uruchomieniu procesora WD jest
wyłączony. Uruchamia się go wpisując do rejestru WDTRST kolejno
wartości: 01Eh i 0E1h. Od tej chwili licznik WD’a zlicza cykle maszynowe.
Nie ma możliwości wyłączenia WD’a, za wyjątkiem podania sygnału
RESET.
Gdy licznik się przepełni (po 16383 cyklach) nastąpi podanie sygnału
RESET i procesor wyzeruje się. Jedyną możliwością, aby zapobiec temu, jest
zerowanie licznika zanim się przepełni. Licznik WD’a zeruje się tak samo jak
uruchamia. Ponowne wpisanie do rejestru WDTRST wartości 01Eh i 0E1h,
wyzeruje licznik. Rozakaz zerujący WD należy umieścić w krytycznym
fragmencie programu. Zawieszenie się programu spowoduje najpóźniej po
16,3 ms (XTAL 12MHz) wyzerowanie procesora.
Auto-programowanie
W aplikacjach typu „stand alone”, bardzo praktycznym i przydatnym jest mechanizm
samo-programowania się mikrokontrolera. Jest to funkcja pozwalająca na zdalne wpisanie
do mikrokontrolera nowego programu. Po tej operacji mikrokontroler powinien sam się
wyzerować.
Podstawowe problemy przy projektowaniu układu autoprogramującego:
µ
K
Pamięć programu
Pamięć danych
ROM
EEPROM
RAM
Długi czas zapisu danych do pamięci
ROM powoduje zawieszenie procesora
w takiej konfiguracji
Program do podmiany
Program obsługujący funkcję
autoprogramowania
AT89C51RB2/RC2 - autoprogramowanie
Podstawowe własności Flash EEPROM’a
pamięć programu,
możliwość zdefiniowania adresu „bootloadera”,
domyślny „bootloader”,
programowanie 5V,
programownaie bajtu - 10ms,
programowanie 32kB - ok.. 10s,
10 000 cykli zapisu,
okres podtrzymania danych - 10 lat
programowanie po 1 bajcie lub po stronach 128 bajtowych,
nie jest wymagane wymazanie pamięci przed zaprogramowaniem,
wbudowana biblioteka API do programowania pamięci z poziomu
aplikacji
API - AT89C51RB2/RC2
W procesorze ATMELA dodano drugi rejestr DPTR. Program operuje na rejestrze
DPTR0 lub DPTR1 w zależności od ustawienia bitu DPS.
DPS = AUXR1.0 (adres SFR = 0A2h). DPS = 0 wskazuje na DPTR0 jako aktywny,
DPS = 1 wskazuje na DPTR1.
Funkcje API wywołuje się zawsze poprzez tę samą procedurę PGM_MTP
umieszczoną w pamięci pod adresem FFF0h. Numer wywoływanej funkcji ustawia
się w rejestrze R1.
Wybrane funkcje API:
Komenda
R1
A
DPTR0
DPTR1
Wartość zwrotna
Opis funkcji
WYMAŻ BLOK
01h
xxh
00h
ACC = DPH
ZAPISZ BAJT
02h
Adres bajtu
09h
DPH = 00h, DPH =
20h, DPH = 40h
Wymaż blok 0000h - 1FFFh,
Wymaż blok 2000h - 3FFFh,
Wymaż blok 4000h - 7FFFh
wartość do
zaprogram
owania
ACC = 0 -
arealizowano
Zaprogramowanie jednego
bajtu w pamięci programu
PROGRMAUJ
STRONĘ DANYCH
Liczba
bajtów do
zaprogram
owania
Adres pierwszego
bajtu do
zaprogramowania w
pamięci programu
Adres pierwszego
bajtu do
zaprogramowania
w XRAM
ACC = 0 -
arealizowano
Programowanie do 128 bajtów
w pamięci programu.
Kompilator C – SDCC
SDCC jest to kompilator ANSI C
Produkt dystrybuowany jest w wersji opensource i freeware
Kompilator przenaczony jest m.inn. dla procesorów z rodziny
Intel MCS51 (8031,8032,8051,8052)
Kompilator wykorzystuje assembler i linker dla powy`zszych
procesorów dostęnych także w wersji freeware.
Typy danych:
Char 8 bitów (1 bajt)
Short i Int 16 bitów (2 bajty)
Long 32 bity (4 bajty)
Float 32 bity zgodnie ze standardem IEEE
SDCC - ang. Small Device C Compiler,
przedrostki typów danych
Kompilacje wykonuje się komendą sdcc plik.c
Kompilacja gdy projekt zajmuje kilka plików:
sdcc -c plik1.c plik z funkcjami
sdcc -c plik2.c plik z funkcjami
sdcc -c main.c plik z funkcją main
sdcc main.rel plik1.rel plik2.rel – plik główny powinien być na pierwszym
miejscu
Przedrostki dla typów zmiennych dla procesorów z rodziny MCS51
data – jest to domyślny przeddrotek dla zmiennych, określa miejsce
umieszczenia zmiennej w wewnętrznej pamięci RAM, bezpośrednio adresowanej,
np. data unsigned char x
xdata – przedrostek wskazujący, że dana powinna być przechowywana w
zewnętrznej pamięci RAM, np. xdata int y, po takiej deklaracji dwa bajty zostaną
zarezerwowane w zewnętrznej pamięci RAM
SDCC – przedrostki typów danych
idata – zmienna zadeklarowana z takim przedrostkiem zostanie przechowana w
wewnetrznej pamięci RAM adresowanej pośrednio, np. idata unsigned char ala,
zapis jakiejś wartości do takiej zmiennej zostanie wykonany przez dwie instrukcje
assemblerowe:
Przykład:
mov R0, #_ala
mov @R0,#nowa_wartosc
code – zmienna z takim przedrostkiem zostanie ulokowana w pamięci programu.
Na ogół taką zmienną można wyłącznie odczytywać
pdata – przedrostek definiujący pamięć stronicowaną, dla rodziny MCS51
zawsze jest to kontakt z zewnętrzną pamięcią danych, np. pdata unsigned char
*wskaznik
Przykład:
pdata unsigned char *wskaznik
wskaznik = (pdata *)0x00ff;
*wskaznik = 23;
SDCC – przedrostki typów danych
bit – przdrostek określa, że deklarowana zmienna jest bitem i należy ją
umieścić w wewnętrznym obszarze pamięći RAM procesora adresowanej bitowo,
np. bit zmienna_bitowa
sfr lub sbit – przedrostki określają zarówno typ zmiennej jak również miejsce
ich skjładowania, pierwszy definiuje Special Function Register, a drugi Special
Bit, przedrostki pomocne przy dostosowywaniu kompilatora do procesorów
pochodnych rodziny MCS51, np. ADuC812, ADuC831, AT89C51RC2,
Przykład:
sfr at 0xC8 T2CON;
sbit at 0xCF TF2;
SDCC, wskaźniki
Istnieje kilka sposobów deklaracji wskaźników:
xdata unsigned char * data wskażnik –
wskaźnik do zmiennej w xdata, wskaźnik
przechowywany w pamięci wewnętrznej RAM
data unsigned char * xdata wskażnik –
wskaźnik do zmiennej w wewnętrznej
pamięci danych, wskaźnik przechowywany w zewnętrznej pamięci RAM
data unsigned char * code wskażnik –
wskaźnik do zmiennej w wewnętrznej
pamięci RAM, wskaźnik przechowywany w pamięci programu
code unsigned char * code wskażnik –
wskaźnik do zmiennej w pamięci programu,
wskaźnik przechowywany w pamięci programu
Wskaźniki dla których nie została określona pamięć mają długość
3 bajtową
SDCC, adresowanie bezwzględne
Można narzucić kompilatorowi adres, pod którym zmienna
ma być przechowywana, np.
x
data at 0x01aa int zmienna
Zmienna będzie przechowywana w dwóch bajtach, o adresach
0x01aa i 0x01ab
Kompilator nie rezerwuje tego adresu, tzn. że może wystąpić
konflikt z innymi zmiennymi, programista sam musi to kontrolawać.
Adresy przydzielone poszczególnym zmiennym można sprawdzić
w plikach .rst, .lst i .map
Adresowanie bezwzględne dostęne jest dla każdego typu zm
iennej
i każdej pamięci, także dla zmiennej bitowej
SDCC - Zmienne lokalne i parametry funkcji
Zmienne lokalne i parametry funkcji są przechowywane w pamięci
wewnętrznej lub zewnętrznej w zależności o opcji kompilatora (small
model i large model) – domyślna działalnośc kompilatora, takie
funkcje określane są jako non-reentrant
Powyższe zmienne mogą być także przechowywane na stosie
(funkcje takie określa się jako reentrant), zamiast w pamięci, w tym
celu na końcu nagłówka funkcji należy umieścić słowo kluczowe
reentrant np.
void funkcja_przykladowa (param1 int) reentrant
Jeżel parametry funkcji mają zdefiniowaną pamięć gdzie powinny być
przechowywane, to zostanie to zignorowane, a parametry funkcji zostaną i tak
umieszczone na stosie,
Na stosie zostaną umieszczone tylko te zmienne lokalne, które nie mają
zdefiniowanych jawnie pamięci, w których maja być przechowywane
SDCC - Nakładanie się zmiennych
Kompilator ma wbudowany mechanizm optymalizacji ilości
zużywanej pamięci wewnętrznej, w tym celu wyodrębnia w niej
fragment na zmienne, które mogą zajmować ten sam adres fizyczny,
obszar ten określa się jako overlayable segment
Zmienne i parametry funkcji umieszczane są w overlayable segment
jeżeli:
Funkcja nie ma w sobie wywołań do innych funkcji
Funkcja jest non-reentrant
Model pamięci jest small – domyślny
Jeżeli zmienna lokalna funkcji ma jawnie określoną pamięć, w której
ma być przechowywana, taka zmienna nie zostanie umieszczona w
segmencie overlayable
Mechanizm umieszczania zmiennych w segmencie overlayable jest
domyślny, w kilku przypadkach może spowodować błędy
SDCC - Overlayable segment
Kompilator decyduje o umieszczeniu zmiennych we wspólnym
segmencie pamięci jeżeli wykluczy ich równoczesne wykorzystanie, nie
zawsze jednak potrafi to trafnie ocenić
Kompilator nie analizuje pod tym względem zawartośći programu po
słowie kluczowym inline (czyli nie analizuje assemblera umieszczonego w
ciele funkcji), jeżeli z poziomu assemblera wywołana jest inna funkcja, to
może się okazać, że funkcja wywołująca i wywoływana ma pewne zmienne
przechowywane we wspólnym obszarze pamięci
Aby uniknąć możliwośći wystąpienia takiej kolizji, funkcja wywoływana z
poziomu assemblera powinna być skompilowana jako reentrant, w tym
celu wykorzystuje się komenndę preprocesora #pragma NOOVERLAY,
którą umieszczaja się przed funkcją wywoływaną
Podobna sytuacja zachodzi dla funkcji wywoływanych z poziomu funkcji
obsługujących przerwania
SDCC - Overlayable segment
Przykład:
#pragma SAVE
//zachowanie dotychczasowych ustawień
#pragma NOOVERLAY
// ustawienie opcji, nie umiesczania we wspólnej pamięci
void ustaw_adres(int adres) {
int adres_koncowy;
adres_koncowy = adres*32;
}
#pragma RESTORE
//przywrócenie początkowych ustawień
void obsluga_przerwania() interrupt 2 {
ustaw_adres(16);
}
}
SDCC - Przerwania
Funkcję obsługującą przerwanie defiunuje się następująco:
void funkcja(void) interrupt 1 {...;}
Nie jest zalecane wywoływanie innych funkcji z procedury
obsługi przerwań
Nie należy używać w procedurach obsługi przerwań bilblioteki z
funkcjami mnożenia,dzielenia itp. na liczbach typu int i long.
Chyba, że zostaną przekompilowane z opcją:
--stack-auto, i ponownie z opcją
--int-long-rent
Jeżeli procedura obslugująca przerwania modyfikują zmienną,
która dostępna jest także dla innych procedur, to taką zmienną
należy zadeklarować z przedrostkiem volatile
SDCC - Assembler
Wewnątrz
funkcji
możnba
umieszczać kod napisany w
assemblerze, służą do tego
przedrostki
_asm
i
_end asm
,
pomiędzy którymi należy umieścić
kod (linijka pod linijką) w
assemblerze
Przykład 1:
void przyklad(void)
{
DPTR = 132;
_asm
MOV DPTR,#132
_endasm
}
Pomocną
i
niebezpieczną
dyrektywą do umieszczania kodu w
assemblerze jest:
_naked
,
która
powoduje, że kompilator nie
zabezpiecza
zmiennych
przed
wywołaniem funkcji, nie umieszcza
także na jej końcu instrukcji ret
Przykład 2:
void f_przyklad(void) interrupt 1 _naked
{
_asm
M?OV DPTR,#132
reti
_endasm
}