PIC C, Simple IO


Two routines are presented to implement an ascending or descending pattern on eight LEDs.

BAR_1.C implements this by using a constant array.

BAR_2.C uses two constant arrays, one for the up and the other for the down sequence. Note, however, that pointers to constant arrays are not implemented. Thus, the constant array is first copied to a RAM array which is passed by reference. (Note that this is a very foolish routine, intended only to illustrate this point).

Another alternative which is illustrated in 5832.C which uses a 32-bit shift register to interface with four 7-segment LEDs is to decalre the constant array globally.


// Program BAR_1.C (CCS PCW - PIC16F84)
//
// Eight LEDs on PORTB, Switch on RA.2.
//
// Bar climbs if switch is at one, declines if switch is at zero
//
// Illustrates ROM arrays.
//
// copyright, Peter H. Anderson, Mecklenburg Co, VA, Mar, '99

#case

#include <16F84.h>
#include <defs_f84.h>	// definitions of TRISA, TRISB, PORTA, PORTB, etc

// timing routines
void delay_10us(int t);
void delay_ms(long t);

main()
{
   int const patts[8]={0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
   signed int n;

   TRISA = 0x1f;	// all are inputs
   TRISB = 0x00;

   while(TRUE)
   {
      if (!ra2)		// if switch at ground, bar goes up
      {
         for(n=0; n<8; n++)
         {
            PORTB=patts[n];
            delay_ms(500);
         }
      }
      else		// otherwise, down
      {
	for(n=7; n>=0; n--)          
          {
             PORTB=patts[n];
             delay_ms(100);
          }
      }
   }
}

void delay_10us(int t)	// provides t * 10 usecs
			// max is 255 or 2550 usecs
{
#asm
      BCF STATUS, RP0
DELAY_10US_1:
      CLRWDT
      NOP
      NOP
      NOP
      NOP
      NOP
      NOP
      DECFSZ t, F
      GOTO DELAY_10US_1
#endasm
}

void delay_ms(long t)	// delays t millisecs
{
   do
   {
     delay_10us(100);
   } while(--t);
}


// Program BAR_2.C (CCS PCW - PIC16F84)
//
// Eight LEDs on PORTB.  Switch on RA.3.
//
// Bar climbs if switch is at one, declines if switch is at zero.
//
// Illustrates RAM and ROM arrays and passing by reference.
//
// Note that pointers to CONST are not permitted.  Thus the array of
// "const" is first copied to an array of RAM and then the pointer is
// passed to the function.
//
// copyright, Peter H. Anderson, Mecklenburg Co, VA, Mar, '99

#case
#include <16F84.h>
#include <defs_f84.h>

void led_out(byte *patt, long delay_time);

// timing routines
void delay_10us(int t);
void delay_ms(long t);

main()
{
   int const up[8]={0x01, 0x03, 0x07, 0x0f,
                     0x1f, 0x3f, 0x7f, 0xff};
   int const down[8]={0xff, 0x7f, 0x3f, 0x1f,
                       0x0f, 0x07, 0x03, 0x01};
   int patts[8], n;
   
   TRISA = 0x1f;	// all are inputs
   TRISB = 0x00;

   while(TRUE)
   {
      if (!ra2)
      {
         for(n=0; n<8; n++)
         {
            patts[n]=up[n]; // copy from CONST to RAM
         }
      }
      else
      {
         for (n=0; n<8; n++)
         {
            patts[n]=down[n];
         }
      }

      led_out(patts, 500);
   }
}

void led_out(byte *patt, long delay_time)
{
   int n;
   for(n=0; n<8; n++)
   {
      PORTB=patt[n];
      delay_ms(delay_time);
   }
}


// delay routines
void delay_10us(int t)	// provides t * 10 usecs
			// max is 255 or 2550 usecs
{
#asm
      BCF STATUS, RP0
DELAY_10US_1:
      CLRWDT
      NOP
      NOP
      NOP
      NOP
      NOP
      NOP
      DECFSZ t, F
      GOTO DELAY_10US_1
#endasm
}

void delay_ms(long t)	// delays t millisecs
{
   do
   {
     delay_10us(100);
   } while(--t);
}