This is an old revision of the document!
Viikude teek on ette nähtud AVR digitaalsete sisend- ja väljundviikudega opereerimiseks. Teegi eesmärk on lihtsustada AVR viikude kasutamist. Kasutaja saab programmis luua soovitud viigu kohta käiva muutuja, millele ta omistab spetsiaalse makro-funktsiooniga füüsilise viigu aadressi. Seejärel saab muutuja abil välja kutsuda erinevaid funktsioone viigu suuna ja olekute muutmiseks ning nende lugemiseks.
Määrates viigu füüsilise siini (pordi) ja indeksi ära ainult ühe korra ja ühes kohas, on füüsiliste muudatuste korral lihtne programmi muuta. Näiteks, kui algul kasutatakse indikaatorina ühte LED-i, võib lihtsa tarkvara muudatusega teist LED kasutama hakata. Viigu muutujatest võib luua ka massiive, näiteks siinide koostamiseks.
Näide sellest, kuidas ühe viigu väärtus teha sõltuvaks teisest. Programmis omandab viik PC3 viigule PC0 vastupidise väärtuse:
#include <homelab/pin.h> pin output_pin = PIN(C, 3); pin input_pin = PIN(C, 0); int main(void) { bool value; // Viigu väljundiks seadistamine pin_setup_output(output_pin); // Viigu pull-up takistiga sisendiks seadistamine pin_setup_input_with_pullup(input_pin); // Lõputu tsükkel while (true) { // Sisendviigu väärtuse lugemine value = pin_get_value(input_pin); // Väljundviigule vastupidise väärtuse omistamine pin_set_to(output_pin, !value); } }
Järgnevalt on lühendatud kujul toodud teegi lähtekood mille eesmärk on kogenunematele programeerijatele selgitada teegis toimuvat. Kasutusel on C-keele viidad (inglise keeles pointer), millest selle raamatu C-keele õpetuses kirjutatud pole, kuid mille kohta leiab palju infomaterjali internetist ja programeerimise õpikutest.
#include <avr/io.h> #include "bit.h" typedef struct pin { _REG_PTR_ ddr; _REG_PTR_ port; _REG_PTR_ pin; uint8_t mask; } pin; #define PIN(port_char, bit_index) \ { \ (_REG_PTR_)&DDR ## port_char, \ (_REG_PTR_)&PORT ## port_char, \ (_REG_PTR_)&PIN ## port_char, \ bit_mask(bit_index) \ } inline void pin_setup_output(pin pin) { bitmask_set(*pin.ddr, pin.mask); } inline void pin_setup_input(pin pin) { bitmask_clear(*pin.ddr, pin.mask); } inline void pin_setup_input_with_pullup(pin pin) { bitmask_clear(*pin.ddr, pin.mask); bitmask_set(*pin.port, pin.mask); } inline void pin_set(pin pin) { bitmask_set(*pin.port, pin.mask); } inline void pin_clear(pin pin) { bitmask_clear(*pin.port, pin.mask); } inline void pin_toggle(pin pin) { bitmask_invert(*pin.port, pin.mask); } inline void pin_set_to(pin pin, bool value) { bitmask_set_to(*pin.port, pin.mask, value); } inline bool pin_get_value(pin pin) { return (bitmask_is_set(*pin.pin, pin.mask) ? 1 : 0); }