2008-02-09
Olvasgattam a neten különböző AVR-rel kapcsolatos magyar lapokat. Megértettem miről van szó, de csak úgy, hogy értettem a szerző miről akart írni. Megrémültem, hogy esetleg én is ugyanolyan érthetetlen vagyok mások számára. Persze nekem világos miről írok, szóval nagyon nehéz az embernek átlépni a saját árnyékát. Na ennek örömére, meg hogy valami vizuális is legyen, meg reklámozzam megint az OOO-t, meg hogy milyen jópofa folyamatábra készletet lehet tőlem hozzá letölteni... szóval összeütöttem néhány magyarázó ábrát. Az ábrák OOO-ban készültek, .png-be exportáltam őket, majd FastStone Image Viewer -ben körülvágtam.
Így működik a program, gyakorlatilag ez található a main()-ben. Lehet, hogy így egyszerűbb, és nem is kell hosszas magyarázgatásokba bonyolódnom. Igaz, azért ezt a folyamat ábrát is össze kellett csapni.
Ez a parancs sor feldolgozónak a működése. Igazából az alábbi két ábrára bontottam, lehet, hogy a progamban is két függvényre kellett volna. A lényege, hogy addig csak gyűjti a soros vonalról bejövő karaktereket, ameddig egy CR-t (Enter) nem kap. Na ekkor feldolgozza, mi jött be a buffer-be, ez található a második ábrán.
Vírus írók figyelem! Hatalmas réseket hagytam a parancs sor feldolgozóba, ki lehet használni! Példáúl ha az ember azt írja .L4B [CR], akkor is működik, pedig nincs is L4! Igazából nem találtam annyira fontosnak, hogy mindent ellenőrizzen a program, de sebaj, öntevékenyen javítsa ki magának mindenki! Talán érdekes, hogy szinte rövidebb a program, mit a folyamatábrája.
Újdonság, hogy több definíciómat is átettem a header file-ba. Gondolkoztam rajta, hogy egy külön saját file-t csináljak, de az az igazság, hogy az eredeti attiny2303.h-t is már jelentősen átírta, úgyhogy belevartam, és új nevet kapott attiny2313_3bmi.h. A másik dolog, hogyha konstans (nem változó) string-eket akarunk használni, azt célszerű a program (flash) memóriában tárolni. Ezért lett a pgmspace.h is befűzve. Ennek egy makróját és egy függvényét használjuk. A PSTR( "szoveg"), a string-t a program memóriába helyezi, és egy mutatót ad vissza. A másik a pgm_read_byte(), amely függvény a program memóriából olvas. Ezzel a függvénnyel usart_puts() függvényben találkozunk, éppen a kiirandó string-t olvastatjuk be vele. É:rdekes lehet még a nagybetüre konvertáló sor. Azért nem tettem külön függvénybe, mert csak azon az egy helyen kerül felhasználásra. Esetleg érdekes lehet kezdőknek a C string kezelése. C-ben a string-t (karakter láncot) mindig '\0' (nem "0", hanem 0 értékű) karakter zár. A string-eket betünként dolgozzuk fel, egészen addig, amíg egy 0-hoz nem érünk, ott a vége. Apropó, ha még valaki nem hallott a mutatókról, akkor tessék fellapozni egy C könyvet és utánaolvasni! String-ek végén többször is alkalmazok '\r' karaktert, ez a [CR], kocsi vissza karakter, aminek hatására a terminál programunk sort emel.
/*******************************************************************************
* 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 *
* *
* USART kezelesehez IT-t hasznalja. *
* 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. *
* USART-on keresztul az alabbi parancsokat fogadja: *
* *
* A parancsok '.'-tal kezdodnek, es ENTER-re zarodnak. *
* .I - Infó kérés *
* .L1B - LED 1 bekapcsolasa *
* .L1K - LED 2 kikapcsolasa *
* .L2B - LED 2 bekapcsolasa *
* .L2K - LED 2 kikapcsolasa *
* .KL - Szia Levi! uzenet kiirasa *
* *
********************************************************************************
* PonyProg Configuration and Security Bits - bepipalva: *
* Belso 4MHz-es osszc.: SUT0, CKSEL3, CKSEL2, CKSEL0 *
* Kulso keramia rezonator: SUT0 *
* *
*******************************************************************************/
#include "attiny2313_3bmi.h"
#include
#include
#include
#ifndef F_CPU
#define F_CPU 4MHz
#endif
#define BAUDRATE 9600
#define CMD_LINE_LENGHT 12 // input buffer hossza
// 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?
UC usart_input; // ide kerul a kapott karakter, 0 ha nem érkezett semmi
void cmd_line( void); // parancssor feldolgozo
void usart_putc( UC); // egy karakter kirasa soros portra
void usart_puts( const char *); // egy string kiirasa soros portra
ISR( USART_RX_vect) // USART olvasa megszakitas kezelese
{
usart_input= UDR;
}
int main( void)
{
UC p= 0; // pergesmentesiteshez, egyenlore
DDRD BS( LED1); // szukseges labak kimenetre allitasa
DDRD BS( LED2);
LED1_OFF;
LED2_ON;
UBRRL= ( F_CPU/( BAUDRATE* 16UL))- 1; // USART init
UBRRH= (( F_CPU/( BAUDRATE* 16UL))- 1)>> 8;
UCSRC= ASYNCRON+ BIT_8+ PARITY_NO+ STOPBIT_1;
UCSRB= RX_ENABLE+ TX_ENABLE+ IT_RX_ENABLE;
IT_ENABLE;
while( 1) // maga a program hurok
{
if ( usart_input) cmd_line(); // ha erkezett valami az USART-ra
if( SW1_ON)
{
if( !p)
{
LED1_ON;
p= 1;
usart_putc( '1');
}
}
if( SW2_ON)
{
if( p)
{
LED1_OFF;
p= 0;
usart_putc( '2');
}
}
}
return 0;
}
void usart_putc( UC c) // egy karakter kirasa soros portra
{
while( UDR_NOT_EMPTY);
UDR= c;
}
void usart_puts( const char *s) // egy string kiirasa soros portra
{
register char c;
while ( ( c= pgm_read_byte( s++))) usart_putc( c);
}
void cmd_line( void) // parancssor feldolgozo
{
static UC buff[ CMD_LINE_LENGHT]; // parancs sor buffer
static UC cbuff= 1; // szamlalo buffer-hez
static UC * pbuff= buff; // mutato buffer-hez, elejere allitas
UC c; // bejott karakter tarolasa
c= usart_input;
usart_input= 0; // globalis valtozo torlese, elengedese
switch( c) // parancs lezaras jott be?
{
case 10: break; // LF - kihagy, eldob
case 13: // CR - parancs lezaras -> feldolgozas
{
*pbuff= '\0'; // sorveg, string lezarasa
pbuff= buff; // mutato allitasa a buffer elejere
usart_putc( '\r');
if ( *pbuff == '.') // megvan a parancs eleje, teljes a parancs
{
switch( *++pbuff)
{
case 'I': // info lekeres
usart_puts( PSTR( "3BMI 2008 - AVR4\r"));
break;
case 'L': // LED-ek be/kikapcsolasa
if ( *++pbuff == '1')
{
if ( *++pbuff == 'B') LED1_ON;
else LED1_OFF;
}
else
{
if ( *++pbuff == 'B') LED2_ON;
else LED2_OFF;
}
break;
case 'K': // csemetemnek
if ( *++pbuff == 'L')
{
usart_puts( PSTR( "Szia Levi!\r"));
}
else
{
usart_putc( '?');
usart_putc( '\r');
}
break;
default: // imeretlen parancs eseten hibajelzes
usart_putc( '?');
usart_putc( '\r');
}
}
cbuff= 1; // parancs feldolgozasa utan buffer torlese
pbuff= buff;
*pbuff= '\0';
break;
}
default: // nem parancs vege, bejott karakter letarolasa buffer-be
{
usart_putc( c);
if( ( c > 96) && ( c < 123)) c-= 32; // ascii upper - a..z -> A..Z
*pbuff= c;
if( cbuff != CMD_LINE_LENGHT) // limit
{
cbuff++;
pbuff++;
}
}
}
}
Itt a vége, fuss el véle, legytek az én vendégeim, innen letölthetitek a hozzávalókat összecsomagolva.