AVR - Portok/lábak kezelése 2. - "tkiraaly_kpin.c"

2016-03-16

 

Azt gondolhatnánk, a port lábak kezelését már teljesen megoldottam. Viszont, ha az Arduino-hoz hasonlóan paraméterként szeretnénk átadni a port lábakat az objektumoknak/függvényeknek, akkor sajnos nem használhatjuk a szép és gyors makróimat. Ehhez készítettem a mellékelt föggvény csomagot. Rögtön az elején, nézzük egy LED villogtató minta programot, miről is beszélek:


/*******************************************************************************
*   Author       -  Kiraly Tibor
*                   http://www.tkiraaly.hu
*   Date         -  2016.01.03.
*   Chip         -  Atmel AMega8
*   Compiler     -  avr-gcc ( WinAVR)
*
*   kpin bemutatasa, egy LED villogtatasa
*   
*******************************************************************************/
#define F_CPU                4 MHZ


#include "tkiraaly_atmega8.h"
#include "tkiraaly_kpin.c"
#include <util/delay.h>


int main( void)
{
   U8 led= B_PORT_0;
   kpin_output( led);
   for(;;)
   {
      kpin_0( led);
      _delay_ms( 300);
      kpin_1( led);
      _delay_ms( 300);
   }
}

Láthatjuk, hogy programba be kell fűzni a "tkiraaly_kpin.c"-t. Az meg úgy kezdődik, hogy beszúrjuk a "tkiraaly_kpin.h"-t. Ebben találhatók a függvények definíciói, majd a port lábaké.


#ifndef tkiraaly_kpin
#define tkiraaly_kpin
#include "tkiraaly_avr_macros.h"


U8   kpin_bit( U8);                              // bit minta meghatarozasa
void kpin_output( U8);                           // port lab(ak) kimenetre allitas
void kpin_input( U8);                            // port lab(ak) bemenetre allitas
void kpin_pullup( U8);                           // port lab(ak) bemenetre allitas es felhuzo ellenallas bekapcsolasa
void kpin_1( U8);                                // port lab(ak) 1-be allitas
void kpin_0( U8);                                // port lab(ak) 0-be allitas
U8   kpin_rd( U8);                               // port lab(ak) olvasasa
void kpin_wr( U8, U8);                           // port lab(ak) irasa


                                                 // byte felso fele mutatja melyik port
                                                 // byte also fele mutatja melyik bit
// Port A

#define A_PORT_0             0x00                // A port, 0. bit
#define A_PORT_1             0x01                // A port, 1. bit ...
#define A_PORT_2             0x02
#define A_PORT_3             0x03
#define A_PORT_4             0x04
#define A_PORT_5             0x15
#define A_PORT_6             0x06
#define A_PORT_7             0x07
#define A_PORT_UPPER_NIBBLE  0x08                // A port, felso 4 bit
#define A_PORT_LOWER_NIBBLE  0x09                // A port, also 4 bit
#define A_PORT               0x0A                // A port osszes bit

Az ARDUINO-val szemben előnye, hogy a teljes AVR családot lefedi, az Atmel port/láb azonosítókat használja, megoldja a bit/nibble/port szintű műveleteket. Hátránya, hogy lassab, és több helyet igényel mint a direkt makrók.

Egy érdekes megoldást találtam ki, hogy kód uC független legyen, csak azok a portok kezelése lesz a függvényekbe befordítva, amelyekkel az adott uC rendelkezik. Mintának lássuk a "kpin_1( p)" függvényt. A többi függvény hasonló felépítésű.


void kpin_1( U8 p)                               // port lab(ak) 1-be allitas
{
   U8 _bit;
   _bit= kpin_bit( p);
   switch( p & 0xF0)
   {
   #ifdef PORTA                                  // csak letezo portokhoz
      case 0x00: PORTA|= _bit; break;  
   #endif         
   #ifdef PORTB
      case 0x10: PORTB|= _bit; break;  
   #endif         
   #ifdef PORTC
      case 0x20: PORTC|= _bit; break;  
   #endif         
   #ifdef PORTD
      case 0x30: PORTD|= _bit; break;  
   #endif         
   #ifdef PORTE
      case 0x40: PORTE|= _bit; break;  
   #endif         
   #ifdef PORTF
      case 0x50: PORTF|= _bit; break;  
   #endif         
   #ifdef PORTG
      case 0x60: PORTG|= _bit; break;  
   #endif         
   #ifdef PORTH
      case 0x70: PORTH|= _bit; break;  
   #endif         
   #ifdef PORTI
      case 0x80: PORTI|= _bit; break;  
   #endif         
   #ifdef PORTJ
      case 0x90: PORTJ|= _bit; break;  
   #endif         
   #ifdef PORTK
      case 0xA0: PORTK|= _bit; break;  
   #endif         
   }
}

Egyedül a "kpin_bit( p)" eltérő, amit a függvényeknek a bit mintáit generálja. A bit minták egy "static" tömbbe kerültek, így csak egyszer, a program elején kapnak értéket.


U8 kpin_bit( U8 p)                               // bit minta meghatarozasa
{
   static U8 b[]=
   {
      0B00000001,
      0B00000010,
      0B00000100,
      0B00001000,
      0B00010000,
      0B00100001,
      0B01000000,
      0B10000000,
      0B11110000,
      0B00001111,
      0B11111111
   };
   return b[ p & 0x0F];
}


Itt a vége, fuss el véle, legytek az én vendégeim, innen letölthetitek a teljes programokat, miegymást, összecsomagolva.