ATtiny85 - Blik (76 bajtů)

Zápisník experimentátora

Hierarchy: ATtiny85

Před několika lety jsem napsal článek ATtiny85 - Blik. Tehdy jsem napsal několik příkladů a nejmenší z programů měl po kompilaci délku 468 bajtů. Nyní si ukážeme program, který se chová stejně a má jen 76 bajtů. Pojďme si tento blik vyrobit pomocí mikrokontroléru ATtiny85.

Program Blik je nejzákladnějším programem pro Arduino, na kterém se naučíte základy ovládání výstupních pinů mikrokontroléru. Na pin je připojena LED s rezistorem a tato LED v pravidelných intervalech bliká.

Typický blik

Pro Arduino (a všechny různé klony) se tento program objevuje na tisících stránek v prakticky nezměněném tvaru, který je uveden v následujícím příkladu. Pro ATtiny85 je třeba udělat pouze změnu ve zdrojovém kódu a nastavit výstupní pin z čísla 13 na některý pin, který tento miniaturní mikrokontrolér obsahuje. Obvykle je to pin 0. V programu se používá typický kód pro ovládání výstupního pinu. Vybraný pin se nastavit jako výstup a potom se stále dokola pin přepne na hodnotu HIGH nebo LOW a pomocí funkce delay se počká několik milisekund, aby bylo blikání viditelné. Zdrojový kód má po kompilaci s IDE 1.8.12 a jádru ATTinyCore 1.1.5 velikost 880 bajtů.

const int led = 0;
const int sleep = 1000;

// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
}

// the loop routine runs over and over again forever
void loop() {
  digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
  delay(sleep);            // wait for a second
  digitalWrite(led, LOW);  // turn the LED off by making the voltage LOW
  delay(sleep);            // wait for a second
}

Optimalizovaný program blik

Pokud přepíšeme tento kód podle následujícího příkladu, po kompilaci bude velikost programu 76 bajtů. Jak jsem to dosáhl? Pokud si prostudujete zdrojový kód, vidíte, že se skoro vůbec nepodobá původní zdrojový kód. Zcela zmizely funkce setup a loop a nahradila je jediná funkce main. Tato zdánlivě malá změna má ale velké důsledky. Tím, že jsme odstranili ze zdrojového kódu všechny funkce jádra ATTinyCore, kompilátor automaticky zredukoval velikost výsledného kódu. Používá se funkce _delay_ms, která je naprogramována jako několik instrukcí v assembleru. Je úspornější než obvykle používaná funkce delay. Přesná je jen do 262 ms, pak se automaticky přepne na méně přesný variant. Pro účely našeho programu je to dostatečné.

Poslední důležitá změna je v použití funkce main. Naše funkce nahradí jinou funkci a zcela vypne úvodní inicializace systémových registrů, které se obvykle při startu Arduina provedou. Výsledkem je úspora kódu, ale žádný registr není nastaven, takže si na to třeba dát pozor, pokud byste chtěli používat některé další funkce, které jsou na nastavení registrů závislé. Příklad originální funkce main naleznete v následující kapitole.

#include <util/delay.h>

const int led = 0;
const int sleep = 1000;

int main() {
  // initialize the digital pin as an output.
  bitSet(DDRB, led);
  for (;;) {
    bitSet(PINB, led);
    _delay_ms(sleep);
  }
}

ATTinyCore funkce main

Takto vypadá originální funkce main v jádru ATTinyCore. Volá funkci init, která provede mnoho různých nastavení registrů. Daní za to je ale zvětšení velikosti výsledného programu po kompilaci.

#include <WProgram.h>

int main(void)
{
    init();

    setup();
    
    for (;;)
        loop();
        
    return 0;
}

Zdrojový kód

Zdrojový kód se nachází na serveru GitHub.



Video



10.02.2021


Menu