Programiranje AT89C2051 sa SDCC-om na Linuxu

· #at89c2051 #8051 #sdcc #minipro #c #linux

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.

Domaća razvojna pločica s AT89C2051, tipkalima i nizom LED-ica

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.