AVR1 - 01 program - kapcsolók és LED-ek kezelése

2008-02-02

 

Itt van az első fecske, pontosbban az első program, amit betölthetünk az AVR1 panelünkbe. Eltartott egy kis ideig, amíg a programból elkészült ez a web lap, de előbb azokat a lapokat akartam elkészíteni, amelyek egy kicsit megalapozzák a programokat. Ne töltsék le copy/paste-tel a programokat, mert össze vissza kellett szerkesztgetni, hogy a weblapon is legyen valamilyen formája a forráskódnak. Mint korábban is említettem, C-ben lehet követheetlenűl és rondán programozni, és lehet áttekinthetően és szépen is. Az én elképzeléseim szerint valahogy így kellene kinéznie az áttekinthető programnak. Nehéz jól dokumentált kódot írni. Ha sokat kommentezünk az is baj, mert a sok szöveg között elvész a lényeg. Az is baj, ha egy fél év múlva már azt sem tudjuk mi is volt ez, mire írtuk, stb.? Aztán jó lenne, ha más is eligazodna rajta. Tapasztalataim szerint, a legmegdöbbentőbb, hogy a program megírásakor a leg-maguktól-értetődőbb dolgokat kell ledokumentálni. Két hónap múlva pontosan ezekre nem fogunk emlékezni. Nagyon jó módszer az úgynevezett magyar jelölés (by Charles Simonyi), csak én lusta vagyok hosszú változó neveket írni. Inkább egyenként szeretem a változókat deklarálni, és mindegyik mellé feljegyezni mire való. Másik módszerem a struktúrált programozás, ami azt jelenti, hogy a programot jól meghatározott modulokra bontja az ember. Ezeket modulokat egyenként le lehet tesztelni. Én nem használok debuggert, szimulátort. Inkább a programba iktatok be olyanokat, hogy kapcsoljon be egy LED-et, vagy küldjön egy betüt a soros portra.

A chip-ünk jól el van láttva perifériákkal is. Ha jobban utánanézünk, sokkal több ki/bementről szól a dokumentáció, mint ami elférne a chip 20 lábán. Az a dolog magyarázata, hogy ezek tényleg bele vannak építve a chip-be, de mi választhatjuk ki, hogy melyik perifériára van szükségünk, és azt konfiguráljuk az adott lábhoz. Az alább látható a Neumann architektúra:

Az AVR-ek architektúrája ennél bonyolultabb (lásd dokumentáció), úgynevezett Howard architektúra, ami alapvetően abban különbözik a Najman architektúrától, hogy külön memóriában tárolja az adatokat és a programot. A mikroprocesszorok a központi egységet tartalmazzák. Mellé kell pakolnunk memóriát. Azután mellé kell tennünk a periféria illesztő (interface) áramköröket, amikhez csatlakoztathatjuk a perifériákat. Az AVR chip-eket azért nevezzük mikro kontrollereknek, mert ezeket az egységeket mind magukban tartalmazzák.

Egy port olyan periféria, amely 8 vezetéket kezelését teszi lehetővé. Azért fogalmazok ilyen körmönfontan, mert ezek a vezetékek lehetnek kimenetek és bemenetek is. A D port azért D, mert az AVR családban egységesen lettek kiosztva a port kezelő regiszterek, A, B, C, D, stb. A regiszter (SFR) olyan adattár, amely 1 byte, azaz 8 bit adat tárolására alkalmas. A perifériákat ilyen regisztereken keresztűl érhetjük el. Van olyan amelyik csak írható, van olyan amelyik csak olvasható, és van irható/olvasható is. A D port kezeléséhez 3 regiszter szolgál. A DDRD regiszter határozza meg, hogy egy port lábat kimenetként, vagy bemenetként akrunk használni. Amelyik lábat kimenetként akarunk használni, azt a bitet 1-be kell állítani. A PIND regisztert olvasva nézhetjük meg, milyen állapotúak a bejövő vezetékeink. Persze csak a bemenetnek konfigurált bitek értékesek a byte-ból. A PORTD regiszterbe írt bitek jelennek meg a kimeneteken. Ha az adott láb bemenetnek van definiálva, a PORTD adott bitjének 1-be állításával bekapcsolhatunk egy felhúzó ellenállást az adott lábra, feltéve, hogy a MCUCR regiszter PUD bitjét is 1-be tettük. És mindezt megkapjuk 300HUF-ért!

Az első program nagyon egyszerű, SW1 lenyomására bekapcsolja LED1-et, SW2 lenyomására pedig kikapcsolja. Azért választottam ezt a feladatot, mer a kapcsolók prellegésével majd később akarok foglakozni.

A fejrészben megtalálható nemcsak a fordítással kapcsolatos infók, hanem a programletöltő beállításai is.

A #include utasítással más .c, vagy .h (header) file-kat füzhetünk bele a forrás kódunkba. Header file-okban tároljuk általában szükséges definíciókat, jelen esetben a chip regisztereinek definícióit, stb. Nagyobb C programokban, de itt is lehetséges, hogy előre megírt és lefordított program modulokat fordítunk be library-kből. Ezeknek a modulok használatához szükséges definíciokat is header file-k segítségével adjuk meg a fordító programnak, igaz erre egyenlőre nem lesz szükségünk. Fontos, ha azt irom, hogy #include , akkor a fordítóprogram az adott file-t a kijelölt helyről veszi (WinAVR mappáján belül kell keresgélni), míg #include "attiny2313.h" esetén ugyanabban a mappában keresi, ahonnan a .c file származott. Talán mondanom sem kell, a rendszerhez adott header file-t nem bírtam ki, hogy egy kicsit át ne faragjam. A későbbiekben ezt tovább faragom, szóval minden project-be beteszem az éppen aktuális verziót.

A #define-t is szeretem. Példáúl a #define MHz 000000 -val azt modjuk a fordító programnak, ha valhol a programunkban azzal a string-gel találkozik, hogy MHz, azt cserélje le a 000000 string-re (boccs string = karakter lánc). Aztán vannak őrültebb csere lehetőségek is, kéretik valami C könyvben utána nézni.

A bitek kezelésére kimazsoláztam néhány makrót, mert az agyam ledobta az ékszíjat, amikor a C program egy bit leérdezést alig 3 assmbly utasításra fordított le, míg ezt egyetlen assembly utasítással lekezelhető. Érdemes néha belekukkantanunk a .lss file-ba, ez tartalmazza a közbülső assemly kódot.

Talán a többi már magáért beszél.



/*******************************************************************************
*   Author       -  3 BYTE MI                                                  *
*                   http://haromb.freeweb.hu                                   *
*   Date         -  2008.11.08.                                                *
*   Chip         -  Atmel ATtiny2313                                           *
*   Hardware     -  AVR1 tesztpanel                                            *
*   Compiler     -  avr-gcc (WinAVR 20080610) 4.3.0                            *
*                                                                              *
*   SW1 lenyomasara LED1-et bekapcsolja, SW2 lenyomasara LED1-et kikapcsolja   *
*                                                                              *
********************************************************************************
*   PonyProg Configuration and Security Bits - bepipalva:                      *
*   Belso 4MHz-es osszc.:     SUT0, CKSEL3, CKSEL2, CKSEL0                     *
*   Kulso keramia rezonator:  SUT0                                             *
*                                                                              *
*******************************************************************************/
#include "attiny2313.h"




#define MHz           000000
#define kHz           000
#define F_CPU         4MHz


// PORTD bitjei
#define SW1           5
#define SW2           6
#define LED1          3
#define LED2          4


#define BS(bit)       |= ( 1 << ( bit))          // egy byte adott bitjenek 1-re allitas
#define BC(bit)       &= ~( 1 << ( bit))         // egy byte adott bitjenek 0-ra allitas
#define BTS(sfr,bit)  bit_is_set( sfr, bit)      // egy regiszter egy bitjenek vizsgalata 1-re
#define BTC(sfr,bit)  bit_is_clear( sfr, bit)    // egy regiszter egy bitjenek vizsgalata 0-ra


#define LED1_ON       PORTD BC( LED1)
#define LED1_OFF      PORTD BS( LED1)
#define LED2_ON       PORTD BC( LED2)
#define LED2_OFF      PORTD BS( LED2)


#define SW1_ON        BTC( PIND, SW1)           // SW1 lenyomva?
#define SW2_ON        BTC( PIND, SW2)           // SW2 lenyomva?




int main( void)
{
   DDRD BS( LED1);                               // szukseges labak kimenetre allitasa
   DDRD BS( LED2);
   LED1_OFF;
   LED2_ON;
   for(;;)                                       // vegtelen ciklus
   {
      if( SW1_ON) LED1_ON;                       // 1. gombra bekapcsolja a LED1-et
      if( SW2_ON) LED1_OFF;                      // 2. gombra kikapcsolja a LED1-et
   }
}

Itt a vége, fuss el véle, legytek az én vendégeim, innen letölthetitek a hozzávalókat összecsomagolva.