Varikkokello on Attiny2313 mikrokontrollerilla toteutettu kello, jolla voidaan näyttää jäljellä olevaa huoltoaikaa alueella 0-99 min. Tässä projektin kolmannessa vaiheessa tutustutaan ohjelmistonkehitykseen.
Ohjelmistonkehityksessä ensimmäinen tavoite oli saada numerot näkymään näytölle ja niin, että arvoa voisi muuttaa painikkeita painamalla.
Näytön datalehdessä on esitelty yksinkertainen malli, jolla näyttö saadaan toimimaan mikrokontrollerin avulla. Näytön yksi numero koostuu seitsemästä bitistä ja kahdeksas on varattu pisteelle. Näytön siirtorekisterit on ketjutettu, joten molempien lukujen ja pisteiden tilat siirretään muistiin peräkkäin ja annetaan tämän jälkeen lähdönsallinnan signaali.
Jatkokehitetyn ohjelman perusrakenne siis yksinkertaistettuna:
- Haetaan tämänhetkinen luku (8-bit + 8-bit) eli minuutit ja kymmenet minuutit.
- Haetaan pisteiden tilat (8-bit + 8-bit)
- Muunnetaan luvut taulukon avulla siirtorekisteriin sopiviksi arvoiksi ja maskataan pisteen tila LSB-bittiin mukaan
- Estetään siirtorekistereiden lähdöt (ledit sammuvat)
- Siirretään luvut siirtorekisteriin (Maskataan ensimmäinen bitti portin lähtöön, CLK-signaali, bittien shiftaus oikealle, maskaus, CLK-signaali, bittien shiftaus, maskaus, CLK…) jne. Näytölle siirretään ensin minuutit ja tämän jälkeen kymmenet minuutit. Siirto näytölle tapahtuu järjestyksessä oikea näyttö LSB->MSB ja tämän jälkeen vasen näyttö LSB->MSB.
- Sallitaan siirtorekistereiden lähdöt, jolloin ledit syttyvät siirtorekisterin arvojen mukaan
- Viive (esim. 5 ms, kuten datalehden mallissa)
- Siirrytään alkuun eli kohtaan 1.
Kohdan 3 muunto tehdään datalehden taulukon mukaisesti:
Muunnostaulukon käyttö on helppoa esimerkiksi c-kielen taulukon avulla, jolloin oikeaan muunnettuun arvoon voidaan viitata suoraan luvulla.
Esim.
// Alustetaan taulukko muunnoksia varten const uint8_t merkki[] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6}; // 0 - 9 // "DataOikeaNaytto" on näytön oikeanpuolisen luvun data-arvo muunnettuna ja min on tämänhetkisen minuutin arvo DataOikeaNaytto = merkki[min];
// Desimaalipiste saadaan maskauksella mukaan, eli "oikpiste" on joko 0 tai 1. DataOikeaNaytto |= oikpiste;
Vastaavasti datan siirto siirtorekisteriin onnistuu maskauksen avulla
for (i=0;i<8;i++) { //Siirretään minuutit siirtorekisteriin
// Maskataan ensimmäinen bitti ja shiftataan sitä kerran vasemmalle, jolloin pinni PD1 muuttuu datan mukaan. Huomioi, että tämä muuttaa koko PORTD lähdön arvon, eli jos sinulla on muita lähtöjä samasta portista, käytä maskausta säilyttääksesi muiden pinnien tilat. PORTD = (DataOikeaNaytto & 1)<<1)); PORTB &= ~(1<<PB0); // Kellosignaali -> 0 PORTB |= (1<<PB0); // Kellosignaali -> 1
// Haetaan seuraava bitti siirrettäväksi
DataOikeaNaytto = DataOikeaNaytto>>1;
}
Kun numerot saatiin onnistuneesti siirtymään näytölle ja näkymään oikein, oli aika siirtyä kehittämään itse kellon toimintaa. Seuraavaksi tulikin saada ajastin (T0) ja sen esijakaja käyttöön, jotta saataisiin sopivat viiveet sekuntien ja minuuttien toteuttamiseksi.
Kellokeskeytyksen saa loihdittua toimintaan esimerkiksi tällaisella alustuksella.
TIMSK |= (1 << TOIE0); // Sallitaan Timer0 keskeytys TCCR0B = 6; // Käytetään ulkoista kelloa T0 pinnille, laskeva reuna sei(); // Sallitaan keskeytykset
Timer0 overflow keskeytys ohjaa ohjelman keskeytysfunktioon:
ISR(TIMER0_OVF_vect) { // Täällä lasketaan keskeytykset esim. Jakaja++; if (Jakaja == 128) { // Tänne tullaan sekunnin välein, jos esijakaja on 256 // (1/32.768kHz) x 256(overflow) x 128) = 1 sek Jakaja = 0; } }
Näiden perustoimintojen avulla toteutettiin kellon muutkin ominaisuudet, kuten virransäästötila ja vilkutus. Valmis ohjainkortti ja kello on esitelty tarkemmin videolla.
[…] kytkennän löydyttyä siirryin tutkimaan ohjelmistonkehitystä, mutta siitä onkin lisää sitten seuraavassa osassa! Mikrokontrollerit, Rakentelu Mikrokontrollerit, Näyttö, Rakentelu « […]