coolestDisplayName
coolestDisplayName

Reputation: 171

Using an array to store pin bits

Just trying to make sure I'm on the correct track here. I'm trying to store lots of 6-bit bytes into an array to control a parallel device with my PIC18F2550.

My array:

char pins[4] = {
        000000, //0
        000001, //1
        000010, //2
        000011, //3
        000100 //4
}

Later in my code, I want to be able to enter a command such as "Set 3" which will set pins RB0-RB5 to 000011 respectively.

PSEUDO CODE:

if command="Set 3" then find pins[3]{
LATBbits.LATB0 = pins[3][0];
LATBbits.LATB1 = pins[3][1];
LATBbits.LATB2 = pins[3][2];
LATBbits.LATB3 = pins[3][3];
LATBbits.LATB4 = pins[3][4];
LATBbits.LATB5 = pins[3][5];
}

which will give:

{
 LATBbits.LATB0 = 0;
 LATBbits.LATB1 = 0;
 LATBbits.LATB2 = 0;
 LATBbits.LATB3 = 0;
 LATBbits.LATB4 = 1;
 LATBbits.LATB5 = 1;
}

Is this an appropriate way to create this? Am I on the right track? Do you have suggestions on a better way to create an efficient array to control a 6bit parallel device with many settings?

Thanks everyone!

Upvotes: 3

Views: 1774

Answers (1)

kkrambo
kkrambo

Reputation: 7057

You are on the wrong track for many reasons.

Wrong track #1: In your array definition, the C compiler will not interpret values like 000011 as binary. It will interpret that as octal because of the leading zeroes. So 000011 is octal which is decimal 9. So your array contains the values zero, one, eight, nine, and sixty-four.

You might be able to write the value like 0b000011 to tell the compiler that the value is binary. But that is not standard C and many C compilers do not support that. You'll have to check whether your compiler supports that convention.

Wrong track #2: Your intention was to create an array containing the values 0, 1, 2, 3, 4. Notice that the value of each member of the array is equal to the index of that member. This array is pointless. Just use the index value directly rather than as an index into an array which simply returns the original index value.

Wrong track #3: When you set LATBbits.LATB0 = pins[3][0]; you are trying to reference a one-dimensional array as if it were a two-dimensional array. You can't do that. You cannot use an extra array dimension specifier on a value to pull out a bit from that value. The C language doesn't work that way.

Wrong track #4: Just because LATBbits has bitfields defined, it doesn't mean that you cannot set LATBbits directly. In other words, you don't have to set the bits individually. You can set all the bits at once simply by setting LATBbits directly.

Wrong track #5: You wrote that LATB4 and LATB5 will be set to 1. But those are not the least significant bits of LATBbits. LATB0 and LATB1 are the least significant bits and those are the ones that will be set when you set LATBBits = 0b000011.

The right track: Take a look at the definition of LATBbits. I found this online, make sure it matches the definition in your header file.

//==============================================================================
//        LATB Bits

extern __at(0x0F8A) __sfr LATB;

typedef struct
  {
  unsigned LATB0                : 1;
  unsigned LATB1                : 1;
  unsigned LATB2                : 1;
  unsigned LATB3                : 1;
  unsigned LATB4                : 1;
  unsigned LATB5                : 1;
  unsigned LATB6                : 1;
  unsigned LATB7                : 1;
  } __LATBbits_t;

extern __at(0x0F8A) volatile __LATBbits_t LATBbits;

#define _LATB0                  0x01
#define _LATB1                  0x02
#define _LATB2                  0x04
#define _LATB3                  0x08
#define _LATB4                  0x10
#define _LATB5                  0x20
#define _LATB6                  0x40
#define _LATB7                  0x80

I'm pretty sure that your entire example pseudo code can be reduced to this.

if command="Set 3" then {
    LATB = 3;
}

There is no need for the array and there is no need to set the bits individually. You could set either LATB or LATBbits (They're two different names for the same memory mapped register). Setting LATB (or LATBbits) = 3 will result in LATB0 and LATB1 being set and the other bits being cleared.

If the LATB value did not match the command value then it might be useful to use an array to lookup the LATB value. For example, suppose you really do want LATB4 and LATB5 set when command is 3. In that case, you should use the _LATBx definitions to define the array like this:

char pins[] = {
    0,                  // All bits clear
    (_LATB0),           // Bit 0 set
    (_LATB1),           // Bit 1 set
    (_LATB4 | _LATB5),  // Bit 4 and Bit 5 set
    (_LATB2)            // Bit 2 set
}

Then you could set LATB from the array like this.

LATB = pins[3];

Upvotes: 3

Related Questions