2016-03-20
2016-03-21 - Kiegészítve az inline deklarációval.
Mostanában mindig csak kódokat írtam, ez a kép talán egy kicsit feldobja a lapot.
Előző lapokon szó volt a C++ programozásról, meg a "tkiraaly_kpin.c"-ben lévő port/pin kezelő függvényekről. Most szeretném bemutatni, hogy a nagyobb, lassabb kód ellenére mi a módszer előnye, mennyivel egyszerűbb így a programozás. Fenntartva, hogy ez egy lehetőség, lehet C-ben, vagy méginkább Assembly-ben kisebb, gyorsabb programot írni, ahol arra szükség van. Én most úgy látom mindegy, hogy a uC 2 vagy 8% memóriáját foglalja le a program. A pogram a standard piros/sárga/zöld jelzőlámpa működését modellezi. Vegyük észre, hogy csak minimális változó deklarálásra volt szükség, a kiválasztott port lábak könnyen megváltoztathatók. A program elég áttekinthető, csak a működési logikát tartalmazza. Ha csak magamnak írtam volna, azt hiszem nem is tettem volna bele megjegyzéseket.
/*******************************************************************************
* Author - Kiraly Tibor
* www.tkiraaly.hu
* Date - 2016.03.20.
* Chip - ATmega8
* Compiler - avr-gcc (WinAVR)
*
* Jelzo lampa - cpp demo
*
*******************************************************************************/
#define F_CPU 4 MHZ
#include "tkiraaly_atmega8.h"
#include "tkiraaly_kbutton.cpp"
#include "tkiraaly_kled.cpp"
int main( void)
{
U8 phase= 0; // jelzolampa fazis
kled lamp_red( D_PORT_5); // piros lampa
kled lamp_yellow( D_PORT_6); // sarga lampa
kled lamp_green( D_PORT_7); // zold lampa
lamp_red.on();
kbutton button_step( D_PORT_2); // lepteto gomb
for(;;)
{
if( button_step.check())
{
phase++;
if( phase > 3) phase= 0;
switch( phase)
{
case 0: // piros
lamp_red.on();
lamp_yellow.off();
break;
case 1: // piros + sarga
lamp_yellow.on();
break;
case 2: // zold
lamp_red.off();
lamp_yellow.off();
lamp_green.on();
break;
case 3: // sarga
lamp_yellow.on();
lamp_green.off();
break;
}
}
}
}
A programban látható, hogy a C++-ban lehetőség van az objektum létrehozásakor (valójában a változók létrehozásakor) zárójelek között megadni a kezdő értéke(ke)t, amit a constructor kap meg. Ha a constructor olyan, aminek nem kell kezdő érték, akkor hagyományosan ki kell írni az obektum létrehozásakor a construktor-t. Nézzük például egy led nevű objektum esetén:
led green= led();
A "kbutton" objektummal szeretném demonstrálni a C++-t, meg a "kpin"-t . Úgy tűnik, nem kell külön ".h"-ba tenni a class deklarációt, egy ".cpp"-be bele lehet írni az egészet. Ezen meglátás alapján vontam össze a "tkiraaly_kpin.c"-t és a "tkiraaly_kpin.h"-t is. Láthattuk, hogy a programban az objektum könnyen felhasználható, az objektumok, a ".cpp" file-k megírása igénylik a nagyobb körültekintést. Ezért nem a fő programba, hanem a ".cpp"-be írjuk bele az összes hivatkozást. Lehet több olyan ".cpp" file-unk, amelyikben "#include"-dal hivatkozunk ugyanarra a kódra (pl. "tkiraaly_kpin.c"), és ilyenkor a fordító ellenkezésére számíthatnánk, ha nem használnánk az "#ifndef-#endif" deklarációt.
/*******************************************************************************
* Author - Kiraly Tibor
* www.tkiraaly.hu
* Date - 2016.03.20.
* Chip - AVR
*
* kbutton - nyomogomb kezelo objektum
*
* Az objektum a nyomogombok kezelesere szolgal.
* A gombot a fold es a kivalasztott lab koze kell kotni.
* A construktor-nak meg kell adni a labat, lasd "tkiraaly_kpin.h".
* A lab fel lesz huzva a belso ellenallassal.
* Az objektum pergesmentesen kezeli a gombot.
* Az objektum a gomb lenyomaskor csak egyszer ad ki 1-et.
*
*******************************************************************************/
#ifndef tkiraaly_kbutton
#define tkiraaly_kbutton
#include <util/delay.h>
#include "tkiraaly_kpin.c"
class kbutton
{
public:
kbutton( U8); // constructor
U8 check(); // lekerdezes
private:
U8 _pin; // melyik lab
U8 _state; // gomb allapota
};
kbutton::kbutton( U8 pin) // constructor
{
_pin= pin;
kpin_pullup( pin); // bemenet/felhuzas
_state= 1; // gomb alapallapota
}
U8 kbutton::check( void) // lekerdezes
{
U8 a= 0;
if ( kpin_rd( _pin) != _state )
{
_delay_ms( 30); // esetleges perges miatt varakozas
if ( kpin_rd( _pin) != _state )
{
if ( _state) // allapot valtas
{
_state= 0;
a= 1; // 1-0 valtas eseten
}
else _state= 1;
}
}
return a;
}
#endif
Mikor megírtam a "kbutton"-t, és elkezdtem faragni a mintaprogramot, és láttam, hogy az jó, gyorsan összekalapáltam az alábbi "kled"-t is, mert ezzel egyszerűbb, áttekinthetőbb és kényelmesebb lett a kód. Ez a mintapéldája, hogy a fejlődés mozgatórugója a lustaság :). Csak, hogy néhány sorral rövidebb és egyszerűbb legyen a főprogram, képes voltam egy külön objektumot készíteni.
/*******************************************************************************
* Author - Kiraly Tibor
* www.tkiraaly.hu
* Date - 2016.03.20.
* Chip - AVR
*
* kled - LED kezelo objektum
*
* Az objektum LED-ek kezelesere szolgal.
* A LED katodjat egy ellenallason keresztüla a labra kell kotni, az anodjat a tapra.
* A construktor-nak meg kell adni a labat, lasd "tkiraaly_kpin.h".
* Alaphelyzetben a LED ki lesz kapcsolva.
*
*******************************************************************************/
#ifndef tkiraaly_kled
#define tkiraaly_kled
#include "tkiraaly_kpin.c"
class kled
{
public:
kled( U8); // constructor
void on(); // bekapcsolas
void off(); // kikapcsolas
private:
U8 _pin; // melyik lab
};
kled::kled( U8 pin) // constructor
{
_pin= pin;
kpin_1( pin);
kpin_output( pin);
}
void kled::on() // bekapcsolas
{
kpin_0( _pin);
}
void kled::off() // kikapcsolas
{
kpin_1( _pin);
}
#endif
A C++-ban lehet inline függvényeket is használni, vagyis ha jól értem egy függvényen belül is lehet függvényt deklarálni. Ez biztos mindenfélére jó, én csak egy értelmét látom, mint itt, hogy a kevéssé terjedelmes függvényeket közvetlenül bele lehet írni a class-ba. Hivatalosan ez az implicit inline deklaráció, mivel nem kell kiírni az "inline" kulcsszót. Kevesebbet kell írni, talán az összetatozó részek is egymáshoz közel lesznek, de szerintem a kód kevésbé lesz olvasható. Nekem annyira zavarta a szemem, hogy egy-egy üres sorral választottam el a tagfüggvényeket. Mindkét alak egyező méretűre fordul le.
/*******************************************************************************
* Author - Kiraly Tibor
* www.tkiraaly.hu
* Date - 2016.03.21.
* Chip - AVR
*
* kled2 - LED kezelo objektum inline fuggvenyekkel
*
* Az objektum LED-ek kezelesere szolgal.
* A LED katodjat egy ellenallason keresztüla a labra kell kotni, az anodjat a tapra.
* A construktor-nak meg kell adni a labat, lasd "tkiraaly_kpin.h".
* Alaphelyzetben a LED ki lesz kapcsolva.
*
*******************************************************************************/
#ifndef tkiraaly_kled
#define tkiraaly_kled
#include "tkiraaly_kpin.c"
class kled
{
public:
kled( U8) { _pin= pin;
kpin_1( pin);
kpin_output( pin);}
void on() { kpin_0( _pin);} // bekapcsolas
void off() { kpin_1( _pin);} // kikapcsolas
private:
U8 _pin; // melyik lab
};
#endif
Itt a vége, fuss el véle, legyetek az én vendégeim, innen letölthetitek a programokat, miegymást összecsomagolva.