Acessing port bits dynamically

Status
Not open for further replies.

Varunme

Member
can we access pic 16F877a port bits dynamically like

Code:
#define _TOTAL_LIGHTS 5

for(i=0; i<_TOTAL_LIGHTS; i++)
             { 
                     if (PORTD.[i] == 1)
                        {
                                 PORTC.[i] = 1;
                        }
                     else
                       {
                                 PORTC.[i] = 0;
                       }
            }
 
You can do,
Code:
    if(PORTD&(1<<i)){
        PORTC|=(1<<i)
    }else{
        PORTC&=(255-(1<<i))
    }

Edit, A good compiler should use the bit instructions to do this.

Mike.
 
Last edited:
or maybe this
Code:
PORTC = (PORTC & 0xE0) | (PORTD & 0x1F);  // (part to keep) | (part to change)
 
Any good PIC compiler will let you test or set register bits directly.

In MikroC you can use
if(PORTB.F1)
and
PORTA.F3 = 0
to access bits.
 
Any good PIC compiler will let you test or set register bits directly.

In MikroC you can use
if(PORTB.F1)
and
PORTA.F3 = 0
to access bits.

With a bit of preprocessor magic this can be made compiler independent but for the actual defines. It makes the code easier to port and arguably more readable.

Code:
#ifdef __C18  // these are not the actual compiler ID's
#define STATUS_LED PORTBbits.RB0 
#endif

#ifdef __MIKROC
#define STATUS_LED PORTBbits.RB0 
#endif

...
STATUS_LED = 1;

The masking solution I proposed has the advantage that you can use it with most/all data types and it can operate on several bits at once.


To use the compiler specific bit setting and testing with defines in a loop we could try.

Code:
// compiler specific defines/macros
#define  PORTD_BIT(x)  PORTDbits.PORTDx    
#define  PORTC_BIT(x)  PORTCbits.PORTCx

for(i=0; i<_TOTAL_LIGHTS; i++)
             { 
                     if (PORTD_BIT(i) == 1)  // when i is 3 this expands to  "if (PORTDbits.PORTD3 == 1) "
                        {
                                 PORTC_BIT(i) = 1;
                        }
                     else
                       {
                                PORTC_BIT(i) = 0;
                       }
            }  

or

for(i=0; i<_TOTAL_LIGHTS; i++)
{ 
       PORTC_BIT(i)  = PORTD_BIT(i);                   
}
 
Last edited:
Whoops! You are right of course Pommie.

I missed that he wanted to use the variable i to access a bit. I just can't remember ever needing to do that? It's definitely not a standard C type of thing to do.

Maybe if it must be done using bit tests he could do something like this (which would compile to very fast executing code);

Code:
#define _TOTAL_LIGHTS 5
 
while(1)
{ 
  i = TOTAL_LIGHTS;
  PORTC.F0 = PORTD.F0;                 
  i--;
  if(!i) break;

  PORTC.F1 = PORTD.F1;                 
  i--;
  if(!i) break;

  PORTC.F2 = PORTD.F2;                 
  i--;
  if(!i) break;

  PORTC.F3 = PORTD.F3;                 
  i--;
  if(!i) break;

  PORTC.F4 = PORTD.F4;                 
  i--;
  if(!i) break;

  PORTC.F5 = PORTD.F5;                 
  i--;
  if(!i) break;

  PORTC.F6 = PORTD.F6;                 
  i--;
  if(!i) break;

  PORTC.F7 = PORTD.F7;                 
  break;
}

That has all the speed of an assembler function and should compile to BTF BSF DECFSZ etc.

But really it looks like a job for a parallel process, which would be a good way to redesign it?
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…