uint32_t作为控制输出(继电器)的位值

时间:2016-01-12 08:33:05

标签: c++ arduino

我有25个继电器,它们有15种不同的配置,必须存储在“阵列”或简单的东西......我必须打开/关闭这些继电器(HiGH / LOW)。

使用尽可能少的内存我想用一个“技巧”使用bit来做:

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;
}

但char只有8位,我需要最少25位...... 所以现在问题NR.1,我可以使用uint32_t,就像使用32位的char一样吗?或其他什么?

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;
};

那么面具会是什么? 或者是否有更好/更简单/更快的方法将OUTPUTS设置为所需的值?

谢谢你!

1 个答案:

答案 0 :(得分:2)

正如我已经在另一个帖子中告诉过你的那样,最简单快捷的方法是处理PORTS而不是单个引脚。

例如,在arduino UNO引脚0..7映射到端口D引脚0..7,所以当你做类似的事情时

uint8_t the_value_i_want = 0b01001000;
PORTD = the_value_i_want;

在一条指令中写入引脚0..7。现在,再次使用uno,完整的映射是

  • PORTD映射到Arduino数字引脚0到7
  • PORTB映射到Arduino数字引脚8到13.两个高位(6和7)映射到晶体引脚并且不可用
  • PORTC映射到Arduino模拟引脚0到5.第6位是复位引脚,因此它不可用,而第7位不存在。

因此其他端口的事情要复杂一些。好吧,处理这个的最简单方法是创建一个掩盖相关位的函数。请注意,端口B和C的屏蔽是相同的,但这只是巧合。

#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);
}

现在您可以轻松编写指令以在端口上写入所需的值。例如,如果要打开引脚3,6,8和10,则只需提供两个值(一个用于端口D,即引脚0..7,一个用于端口B,引脚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;

现在,如果你想制作一个包含所有可能值的const矩阵(同样,这仅适用于UNO),你可以制作一个三列的uint8_t矩阵。像

这样的东西
int allvalues[][3] = { {0b001000, 0b001010, 0b00000001},
                    ...};

在这种情况下,使用第一个配置(报告的一个)引脚A3,0,9,11将打开,其他引脚将关闭。

应用此功能的可能功能是

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];
}

这样您就必须为要应用的配置(行)提供索引。

如果由于某些原因,您想要排除某些引脚(例如引脚0和1,因为它们是串行接口),您只需将其包含在掩码中即可。例如:

#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]);
}

这样我就排除了引脚0和1(串行接口)以及引脚A4和A5(I2C接口)。

只有一句话:我以UNO为例,但你可以使用任何一块板。只需查看引脚映射,即可了解端口和arduino引脚之间的关联。