 
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
}