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

uint32_t as Bit value to control outputs (relays)

本文关键字:继电器 输出 控制 uint32      更新时间:2023-10-16

我有25个继电器,它们至少有15种不同的配置,必须存储在"阵列"或其他简单的。。。我必须打开/关闭那些继电器(高/低)。

为了使用尽可能少的内存,我想用一个"技巧"来做到这一点,比如:

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,我能像使用32位的char一样使用uint32_t吗?还是别的什么?

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设置为所需的值吗?

谢谢你!

正如我在另一个线程中已经告诉过的那样,最简单、最快的方法是处理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引脚之间的关联。