我可以将两个端口的位相加以形成新的位序列吗?

时间:2019-04-11 01:07:21

标签: c embedded

在我的实验室中,我应该测试9位值,但是每个端口仅包含8位。根据说明,我使用PORTD上的所有位(包括PB0)来设置这9位值,但是我没有计划如何做到这一点,这实质上就是此问题的全部挑战。其余的应该很容易,我只需要存储一个9位值即可从另一个端口“借用”。

微控制器:ATmega1284

问题: (挑战):汽车的乘客座位重量传感器输出9位值(范围从0到511),并连接到微控制器上的输入PD7..PD0PB0。如果重量等于或大于70磅,则应通过将PB1设置为1来启用安全气囊。如果重量大于5但低于70磅,则应禁用安全气囊,并且将PB2设置为可以点亮“安全气囊禁用”图标。 1.(如果重量不超过5,则B1和B2都不应设置,因为没有乘客。)

2 个答案:

答案 0 :(得分:1)

可以使用按位运算符以任何必要的方式组合来自单独寄存器的位:

&  – Bitwise AND
|  – Bitwise OR
~  – Bitwise NOT
^  – Bitwise XOR
<< – Left Shift
>> – Right Shift  

有点模糊的符号“ PD7..PD0PB0 ”表明PB0是LSB或重量值。在这种情况下,给出:

PORTD DDDDDDDD
PORTB xxxxxxxB

然后:

uint16_t weight = ((uint16_t)PORTD << 1u) | (PORTB & 0x01) ;

将产生由位组成的weight的值:

0000000DDDDDDDDB

子表达式((uint16_t)PORTD << 1u)将PORTD的值左移1位:

0000000DDDDDDDD0

(PORTB & 0x01)将位0以外的所有位清零,而位0保持不变:

        0000000B

然后将这两个子表达式按位进行“或”运算:

   0000000DDDDDDDD0
OR         0000000B
   ----------------
 = 0000000DDDDDDDDB

请注意,通过仅使用PORTD中的8位值并将限制值减半,可以简化任务(出于安全考虑)。当前,您有:“高于5但低于70” ,如果您刚刚阅读PORTD,则限制为 3> = PORTD <35 。实际上,这可能更安全-从两个单独的寄存器读取单个值时,您需要确定您拥有的值与同一样本相同,并且在读取第二个寄存器之前读取的第一个寄存器中的值没有改变。在PORTB寄存器中只有一个LSB​​时,这几乎没有影响,但也使其具有有限的值,除非在读取数据时以某种方式锁存了数据。

答案 1 :(得分:0)

这取决于PB0是寄存器B的MSB还是LSB。但是您可以使用uint16_t变量和一些掩码来获取所需的值。例如,您可以执行以下操作之一。

PB0是MSB

uint16_t sensor;
sensor = (PORTD << 1) | (PORTB >> 7);

PB0为LSB

uint16_t sensor;
sensor = (PORTD << 1 ) | (PORTB & 0x01);

可以通过多种方式完成,这只是其中之一。在这两种解决方案中,寄存器D的所有位都是最高有效位,第一个是LSB,是寄存器B的MSB;第二个是LSB。

如果您希望代码兼容MISRA-C,则应初始化传感器变量。