Programiranje AT89C2051 sa SDCC-om na Linuxu
Sadržaj
AT89C2051 je mali Atmelov mikrokontroler iz porodice 8051 u kućištu s 20 nožica: 2 KB flash memorije, 128 bajtova RAM-a, 15 ulazno-izlaznih linija, dva timera i UART. Za njega se na Linuxu može pisati u C-u s besplatnim prevoditeljem SDCC, a programirati s programatorom TL866 i alatom minipro.

Osvježena verzija
Ovo je ažurirana verzija tutorijala iz rujna 2021. Postupak je provjeren sa SDCC-om 4.5 na Debianu 13, a trajanje treptanja izmjereno je u simulatoru ucsim. Pritom se pokazalo da je kašnjenje u izvornom primjeru bilo oko 3,6 puta prekratko, pa je primjer ispravljen.
Potrebno
- AT89C2051 na pločici s kvarcom od 12 MHz i LED-icom s otpornikom između +5 V i nožice P1.0,
- univerzalni programator TL866A/CS ili TL866II+,
- Debian ili distribucija izvedena iz njega.
Instalacija SDCC-a
SDCC je u Debianovu repozitoriju:
sudo apt install sdcc sdcc-ucsim
Paket sdcc-ucsim donosi simulator, koji nije obavezan, ali je koristan za provjeru programa bez hardvera. Provjera instalacije:
sdcc --version
Instalacija programatora
Za upis programa u čip treba minipro. Postupak je opisan u tutorijalu MiniPRO TL866 programator na Debian Linuxu.
Program: treptanje LED-ice
Program pali i gasi LED-icu na nožici P1.0 svake sekunde. Kašnjenje od 1 ms napravljeno je hardverskim timerom 0, pa ne ovisi o verziji prevoditelja ni o optimizacijama.
Spremi ga kao main.c:
// ********************************************************
// Program: Blink LED example
// Author: Elvis Baketa
// Processor: AT89C2051
// Oscillator: 12 MHz
// Compiler: SDCC (Linux)
// ********************************************************
#include <at89x051.h>
// delay one millisecond using timer 0 (12 MHz crystal, 1 us per machine cycle)
void delayms(void)
{
// 65536 - 966 = 0xFC3A (1000 cycles minus 34 cycles of call and loop overhead)
TH0 = 0xFC;
TL0 = 0x3A;
// start timer and wait for overflow
TR0 = 1;
while (!TF0);
// stop timer and clear overflow flag
TR0 = 0;
TF0 = 0;
}
// amount of milliseconds to delay
void delay(unsigned int ms)
{
while (ms--)
{
delayms();
}
}
void main(void)
{
// timer 0 in mode 1 (16-bit timer)
TMOD = 0x01;
while (1)
{
// turn LED on
P1_0 = 0;
delay(1000);
// turn LED off
P1_0 = 1;
delay(1000);
}
}
LED-ica svijetli kad je izlaz u logičkoj nuli (P1_0 = 0), jer je spojena prema +5 V, a mikrokontroler struju povlači prema masi.
Zašto timer, a ne petlja?
Izvorni primjer čekao je 1 ms praznom petljom for (i = 0; i < 34; i++);. U simulatoru takva petlja traje samo oko 275 µs, pa delay(1000) traje 0,275 s umjesto jedne sekunde. Trajanje programske petlje ovisi o tome kakav kod prevoditelj generira. Ako baš želiš petlju, sa SDCC-om 4.5 potrebno je oko 137 ponavljanja. Timer broji strojne cikluse neovisno o kodu, pa je točan i nakon nadogradnje prevoditelja.
Prevođenje
sdcc -mmcs51 --code-size 2048 main.c
packihx main.ihx > main.hex
-mmcs51 odabire porodicu 8051, a --code-size 2048 javlja grešku ako program ne stane u 2 KB flasha AT89C2051. SDCC stvara više datoteka, a za programator je važna main.ihx. Alat packihx pretvara je u uobičajenu Intel HEX datoteku main.hex. Ovaj program zauzima 240 bajtova.
Provjera u simulatoru (po želji)
Simulator ucsim_51 izvršava program kao pravi 8051 na zadanoj frekvenciji:
ucsim_51 -X 12M main.ihx
U simulatoru naredba run pokreće program, break postavlja prekidnu točku na adresu, a state ispisuje proteklo vrijeme. Adrese naredbi za paljenje i gašenje LED-ice nalaze se u datoteci main.rst. S prekidnim točkama na njima izmjereno je da jedna faza treptanja traje 1,000026 s.
Upis u mikrokontroler
Umetni AT89C2051 u ZIF podnožje programatora i upiši program:
minipro -p AT89C2051 -w main.hex
Za TL866II+ naziv čipa je AT89C2051@DIP20. Minipro sam prepoznaje format datoteke i prije upisa briše čip.
Nakon upisa vrati čip na pločicu i uključi napajanje. LED-ica bi trebala treptati sekundu upaljena, sekundu ugašena.
Napomena
Nožice P1.0 i P1.1 AT89C2051 nemaju unutarnje pull-up otpornike, jer služe i kao ulazi analognog komparatora. Za LED-icu spojenu prema +5 V to nije problem. Za ulaze, npr. tipkala, na tim nožicama treba dodati vanjski pull-up otpornik.
Izvorni kod
Kod iz ovog tutorijala nalazi se i na GitHubu: ebaketa/blink_at89c2051.