2008-02-03
A második programban felélesztjük a kommunikációt a PC és AVR1 tesztpanelünk között. Igaz még csak egy irányba, a paneltől a PC felé. Ehez szükségünk lesz a soros kábelre és egy terminál programra. Számomra legcélszerűbb eszköz a már korábban is említett Bray's Terminal. Elég egyszerű a használata. Előszőr állítsuk be ugyanazokat a paramétereket, amelyeket a panelunkba is beállítunk (9800 bit, no parity, 1 stop bit). Majd kattintsunk a CONNECT gombra. Ha minden ok, a két gomb nyomogatására 1-eseket és 2-eseket kell megjelenni a képernyőnkön. Hiba esetén most jó segítség lehet a panelra helyezet két LED, amelyek mutatják a kimenő illetve a bemenő vezetékek állapotát. Ha a mikrovezérlőnk ad, akkor L4 felvillan. Ha bejövő jel van, akkor L3 villog. Most talán feleslegesnek tűnik ez a két plusz LED, de majd akkor fogjuk igazán megbecsülni, ha egy műhely koszos, hozzáférhetetlen sarkában kell életet lehelnünk a berendezésünkbe (többi lehetetlen helyszin felsorolása fakultatív feladat :).
Néhány definícióval bővült a programunk, amelyeket a későbbiekben átrakok a header file-ba. A feladat egyszerű, előszőr inicializálni (kezdő beállítás) kell a mikrovezérlőnkben található UART egységet, ami azután hardware-ből megcsinálja nekünk a kommunikációt. Anélkül, hogy fényezni akarnám magamat, szerintem egy egészen áttekinthető beállítási módot sikerült készítenem. A baudrate (átviteli sebesség, bit/sec) beállító macro-t azt ollóztam, de egy kicsit azt is pofozgattam. Érdemes a doksiban megnézegetni, hogy milyen órajel mellett (F_CPU), milyen baudrate értékek, milyen pontosan állíthatók be. 1%-nál pontosabb értékpárok esetén jó eséjünk van, hogy nem fog hibázni az összeköttetés. Alapesetben nagyon könnyű az UART-on egy karaktert elküldeni, meg kell vizsgálni, hogy az UDR regiszter üres-e? Ha az előző karakter már kiment, akkor üres, és betölthető a következő. A main()-ban egyszerűen a c-ben követjük, hogy melyik gomb volt utoljára lenyomva. Ez azért kell, hogy egy gomb nyomásra csak egy üzenetet küldjön a program. Ezután eltároljuk c-be a lenyomott gombot, módosítjuk LED1 állapotát, addig várunk amíg UDR üres nem lesz, majd elküldjük a jelző karaktert. Ez ciklikusan ismétlődik a végtelenséig. Ez egy abszolút favágó módszer, hogy nem csináltam külön egy függvényt a karakter elküldéséhez, hanem mindent kétszer leprogramoztam. Későbbiek során majd visszatérünk erre, megvizsgáljuk, hogy lehet-e olyan eset, amikor ez a megoldás célszerű? Érdekes, hogy a main()-t nem sikerült void main( void);-formában deklarálni, ragaszkodik a fordító a default int main(); -hoz, azért kellet egy return 0;-t írni a végére, hogy ne panaszkodjon.
/*******************************************************************************
* Author - 3 BYTE MI *
* http://haromb.freeweb.hu *
* Date - 2008.12.30. *
* Chip - Atmel ATtiny2313 *
* Hardware - AVR1 tesztpanel *
* Compiler - avr-gcc (WinAVR 20080610) 4.3.0 *
* *
* IT-t nem hasznal. *
* LED1 es LED2 labakat kimenetre allitja. *
* LED1-t kikapcsolja, LED2-t bekapcsolja alaphelyzetben. *
* USART-ot (soros port) 9600 baud 8 bit no parity 1 stop bit-re allitja. *
* SW1 lenyomasara LED1-et bekapcsolja, es a soros porton elkuld egy '1'-t. *
* SW2 lenyomasara LED1-et kikapcsolja, es a soros porton elkuld egy '2'-t. *
* *
********************************************************************************
* PonyProg Configuration and Security Bits - bepipalva: *
* Belso 4MHz-es osszc.: SUT0, CKSEL3, CKSEL2, CKSEL0 *
* Kulso keramia rezonator: SUT0 *
* *
*******************************************************************************/
#include "attiny2313.h"
#include
#define UC unsigned char
// lasd sfr_defs.h
#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 MHz 000000
#define kHz 000
#define IT_ENABLE __asm__ __volatile__ ("sei" ::)
#define IT_DISABLE __asm__ __volatile__ ("cli" ::)
#define NOP __asm__ __volatile__ ("nop" ::)
// USART inicializalasahoz, kezelesehez
// UCSRA beallitasai
#define DOUBLE_SPEED 0B00000010
#define MULTIPROC 0B00000001
// UCSRA lekerdezese
#define RX_ERROR UCSRA & 0B00011100 // hiba lekerdezese, 0 - nincs hiba
#define RX_COMPLETE BTS( UCSRA, 7)
#define TX_COMPLETE BTS( UCSRA, 6)
#define UDR_EMPTY BTS( UCSRA, 5)
// UCSRB beallitasai
#define IT_RX_DISABLE 0
#define IT_RX_ENABLE 0B10000000
#define IT_TX_DISABLE 0
#define IT_TX_ENABLE 0B01000000
#define IT_UDR_EMPTY_DISABLE 0
#define IT_UDR_EMPTY_ENABLE 0B00100000
#define RX_DISABLE 0
#define RX_ENABLE 0B00010000
#define TX_DISABLE 0
#define TX_ENABLE 0B00001000
// UCSRC beallitasai
#define ASYNCRON 0
#define SYNCRON 0B01000000
#define PARITY_NO 0
#define PARITY_EVEN 0B00100000
#define PARITY_ODD 0B00110000
#define STOPBIT_1 0
#define STOPBIT_2 0B00001000
#define BIT_5 0
#define BIT_6 0B00000010
#define BIT_7 0B00000100
#define BIT_8 0B00000110
// PORTD bitjei
#define SW1 5
#define SW2 6
#define LED1 3
#define LED2 4
// LED-ek vezerlese
#define LED1_ON PORTD BC( LED1)
#define LED1_OFF PORTD BS( LED1)
#define LED2_ON PORTD BC( LED2)
#define LED2_OFF PORTD BS( LED2)
// kapcsolok lekerdezese
#define SW1_ON BTC( PIND, SW1) // SW1 lenyomva?
#define SW2_ON BTC( PIND, SW2) // SW2 lenyomva?
#ifndef F_CPU
#define F_CPU 4MHz
#endif
#define BAUDRATE 9600
int main( void)
{
UC c= 0; // pergesmentesites helyett
UBRRL= ( F_CPU/( BAUDRATE* 16UL))- 1; // USART inicializalasa
UBRRH= (( F_CPU/( BAUDRATE* 16UL))- 1)>> 8;
UCSRC= ASYNCRON+ BIT_8+ PARITY_NO+ STOPBIT_1;
UCSRB= RX_ENABLE+ TX_ENABLE;
DDRD BS( LED1); // szukseges labak kimenetre allitasa
DDRD BS( LED2);
LED1_OFF;
LED2_ON;
for( ;;)
{
if( SW1_ON)
{
if( !c)
{
c= 1;
LED1_ON;
if( UDR_EMPTY) UDR= '1';
}
}
if( SW2_ON)
{
if( c)
{
c= 0;
LED1_OFF;
if( UDR_EMPTY) UDR= '2';
}
}
}
return 0;
}
Itt a vége, fuss el véle, legytek az én vendégeim, innen letölthetitek a hozzávalókat összecsomagolva.