By Starlino
[VDD 5V] | [RESISTOR 10K] | P1 â-[SWITCH] â [GND] P2 â-[RESISTOR ~ 200Ohm] â[LED]â[GND]
pinSwitch PIN 1 pinLed PIN 2 INPUT pinSwitch OUTPUT pinLed main: IF pinSwitch = 0 THEN HIGH pinLed ELSE LOW pinLed ENDIF GOTO main
pinSwitch PIN 2 pinLed PIN 1
All the remaining PBASIC code remains the same.
RA2â-[SWITCH] â [GND] RB5 â-[RESISTOR ~ 200Ohm] â[LED]â[GND]
To accomplish same thing we'd have to write something like this in C:
TRISAbits.TRISA2 = 1; //make switch pin an input
WPUAbits.WPUA2 = 1; //turn on the pull-up
TRISBbits.TRISB5 = 0; //make led pin an output
while(1){
PORTBbits.RB5 = ! PORTAbits.RA2;
}
//âââââââââââââââââââââââ
// MACROS FOR EASY PIN HANDLING IN PIC C18/C30
//âââââââââââââââââââââââ
#define _TRIS(pin) pin(_TRIS_F)
#define _TRIS_F(alpha,bit) (TRIS ## alpha ## bits.TRIS ## alpha ## bit)
#define _PORT(pin) pin(_PORT_F)
#define _PORT_F(alpha,bit) (PORT ## alpha ## bits.R ## alpha ## bit)
#define _LAT(pin) pin(_LAT_F)
#define _LAT_F(alpha,bit) (LAT ## alpha ## bits.LAT ## alpha ## bit)
#define _WPU(pin) pin(_WPU_F)
#define _WPU_F(alpha,bit) (WPU ## alpha ## bits.WPU ## alpha ## bit)
//âââââââââââââââââââââââ
// USAGE
//âââââââââââââââââââââââ
#define pinSwitch(f) f(A,2) //Switch, INPUT , pin RA2
#define pinLed(f) f(B,5) //Led, OUTPUT , pin RB5
_TRIS(pinSwitch) = 1; //make pin an input
_WPU(pinSwitch) = 1; // turn on internal pull-up
_TRIS(pinLed) = 0; // make pin an output
while(1){
_PORT(pinLed) = ! _PORT(pinSwitch)
}
#define pinSwitch(f) f(B,5) //Switch, INPUT, pin RB5 #define pinLed(f) f(A,2) //Led, OUTPUT, pin RA2
Here is an example how compiler interprets these statements:
_PORT(pinLed) => pinLed (PORT_F) => PORT_F( B, 5) => PORTBbits.RB5
{Ed; Here is a version adapted for use with HiTech C:
#define _TRIS(pin) pin(_TRIS_F)
#define _TRIS_F(alpha,bit) (TRIS ## alpha ## bit)
#define _PORT(pin) pin(_PORT_F)
#define _PORT_F(alpha,bit) (R ## alpha ## bit)
#define _LAT(pin) pin(_LAT_F)
#define _LAT_F(alpha,bit) (LAT ## alpha ## bit)
#define _WPU(pin) pin(_WPU_F)
#define _WPU_F(alpha,bit) (WPU ## alpha ## bit)
}
/*
BASIC STAMPS STYLE COMMANDS FOR ATMEL GCC-AVR
Usage Example:
ââââââââââââââââ
#define pinLed B,5 //define pins like this
OUTPUT(pinLED); //compiles as DDRB |= (1<<5);
HIGH(pinLed); //compiles as PORTB |= (1<<5);
ââââââââââââââââ
*/
//these macros are used indirectly by other macros , mainly for string concatination
#define _SET(type,name,bit) type ## name |= _BV(bit)
#define _CLEAR(type,name,bit) type ## name &= ~ _BV(bit)
#define _TOGGLE(type,name,bit) type ## name ^= _BV(bit)
#define _GET(type,name,bit) ((type ## name >> bit) & 1)
#define _PUT(type,name,bit,value) type ## name = ( type ## name & ( ~ _BV(bit)) ) | ( ( 1 & (unsigned char)value ) << bit )
//these macros are used by end user
#define OUTPUT(pin) _SET(DDR,pin)
#define INPUT(pin) _CLEAR(DDR,pin)
#define HIGH(pin) _SET(PORT,pin)
#define LOW(pin) _CLEAR(PORT,pin)
#define TOGGLE(pin) _TOGGLE(PORT,pin)
#define READ(pin) _GET(PIN,pin)
#define MIN(A,B) (((A)<(B)) ? (A) : (B) ) #define MAX(A,B) (((A)>(B)) ? (A) : (B) ) #define PUT_IN_RANGE(V,VMIN,VMAX) MAX(VMIN,MIN(VMAX,V)) #define MAP_TO_RANGE(V,VMIN0,VMAX0,VMIN1,VMAX1) ( (VMIN1) + ( (V) â (VMIN0) ) * ( (VMAX1) â (VMIN1) ) / ( (VMAX0) â (VMIN0) ) )
volatile unsigned int * tris_ptr[4];
unsigned char* pin_bit[4];
//define our pins as RA2 , RA3 , RB5 , RB7 at run time
tris_ptr[0] = &TRISA; pin_bit[0] = 2; //RA2
tris_ptr[1] = &TRISA; pin_bit[1] = 3; //RA3
tris_ptr[3] = &TRISB; pin_bit[2] = 5; //RB5
tris_ptr[4] = &TRISB; pin_bit[3] = 7; //RB7
int i;
//perform bulk operations on pins
for(i=0;i<4;i++)
if(i % 2){
(*tris_ptr[i]) |= 1<<tris_bit[i]; //set bit, make odd pins INPUT
else
(*tris_ptr[i]) ^= !(1U<<tris_bit[i]); //clear bit, make even pins OUTPUT
In the same way you could define port_ptr[] , lat_ptr[] , wpu_ptr[] arrays and perform operations on those ports. Even more smarter would be to group all these in a structure, and then create a single array of these structures. Using macros you could simplify assignment to these arrays in one simple statement. (I leave this as a homework for you) !
I hope you'll find this article useful. If you have any comments or suggestions do not hesitate to leave a comment below ! Happy coding !
This code copyright Starlino Electronics 2011. Used by permission with link to original content here: http://www.starlino.com/port_macro.html