AVR1 - 04 program - parancs sor feldolgozás

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.