简体   繁体   中英

uint32_t as Bit value to control outputs (relays)

i have 25 relays which has min 15 different configurations, which have to be stored in a "array" or something simple...i have to switch those relays on/off (HiGH/LOW).

to use as less memory as possible i want to do it with a "trick" using bit's like:

char two = B1011011;
int mask = 1;
for(int i=0; i<7; i++){
if((mask & two) == 0) digitalWrite(pins[i], LOW); else  
digitalWrite(pins[i], HIGH);
mask = mask << 1;
}

but char has only 8 bits and I NEED min 25 bits... so now it the question NR.1, can i use uint32_t just in the same way as char just with 32 bits's? or something else?

uint32_t BIG1 = B10110110111011011111101101101
uint32_t BIG2 = B10110110111011011011101101101
uint32_t BIG3 = B10110110111111011011101101101
...
uint32_t BIG = B10110110111011011011101101101;//B... and 31 0s and 1s
uint32_t mask = 1;//????? not right???
for(int i=0; i<31; i++){
  if((mask & two) == 0) digitalWrite(pins[i], LOW); else  
digitalWrite(pins[i], HIGH);
mask = mask << 1;
};

what would be the mask then? or is there a better/easyer/faster way to set OUTPUTS to the needed value?

Thank you in davance!

As I already told you in the other thread, the easiest and fastest way to do this is to deal with PORTS rather than individual pins.

For example, on the arduino UNO pins 0..7 map to port D pins 0..7, so when you do something like

uint8_t the_value_i_want = 0b01001000;
PORTD = the_value_i_want;

you write the pins 0..7 in a single instruction. Now, again with the uno, the complete mapping is

  • PORTD maps to Arduino digital pins 0 to 7
  • PORTB maps to Arduino digital pins 8 to 13. The two high bits (6 & 7) map to the crystal pins and are not usable
  • PORTC maps to Arduino analog pins 0 to 5. Bit 6 is the reset pin, so it's not usable, while bit 7 does not exist.

So things are a bit more complicated for the other ports. Well, the easiest way to handle this is making a function to mask the relevant bits. Just note that the masking is the same for port B and C, but this is just a coincidence.

#define PORT_B_C_MASK = 0x3F;
void write_with_mask(volatile uint8_t *p_register, uint8_t mask, uint8_t value)
{
    *register = (*register | (value & mask)) & (value | ~mask);
}

Now you can write easily the instructions to write the value you want on the port. For instance, if you want to turn on pins 3, 6, 8 and 10, you just have to provide two values (one for port D, ie pins 0..7, and one for port B, pins 8..13):

uint8_t the_value_i_want_8_13 = 0b000101;
uint8_t the_value_i_want_0_7 = 0b01001000;

write_with_mask(&PORTB,PORT_B_C_MASK,the_value_i_want_8_13);
PORTD = the_value_i_want_0_7;

Now, if you want to make a const matrix with all the possible values (again, this applies for the UNO only), you can just make a three-columns uint8_t matrix. Something like

int allvalues[][3] = { {0b001000, 0b001010, 0b00000001},
                    ...};

In this case, with the first configuration (the reported one) pins A3, 0, 9, 11 will be turned on, the others will be off.

A possible function to apply this is

void apply_configuration(uint8_t index)
{
    write_with_mask(&PORTC,PORT_B_C_MASK,allvalues[index][0]);
    write_with_mask(&PORTB,PORT_B_C_MASK,allvalues[index][1]);
    PORTD = allvalues[index][2];
}

This way you just have to provide the index for the configuration (the row) you want to apply.

If, for some reasons, you want to exclude some pins (eg pin 0 and 1, since they are the serial interface) you just have to include it in the mask. For instance:

#define PORT_B_MASK = 0x3F;
#define PORT_C_MASK = 0x0F;
#define PORT_D_MASK = 0xFC;
void apply_configuration(uint8_t index)
{
    write_with_mask(&PORTC,PORT_C_MASK,allvalues[index][0]);
    write_with_mask(&PORTB,PORT_B_MASK,allvalues[index][1]);
    write_with_mask(&PORTD,PORT_D_MASK,allvalues[index][2]);
}

This way I excluded pins 0 and 1 (serial interface) and pins A4 and A5 (I2C interface).

Just one remark: I used the UNO as example, but you can use any board. Just look at the pin mapping to understand what is the association between ports and arduino pins.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM