在我的实验室中,我应该测试9位值,但是每个端口仅包含8位。根据说明,我使用PORTD上的所有位(包括PB0)来设置这9位值,但是我没有计划如何做到这一点,这实质上就是此问题的全部挑战。其余的应该很容易,我只需要存储一个9位值即可从另一个端口“借用”。
微控制器:ATmega1284
问题: (挑战):汽车的乘客座位重量传感器输出9位值(范围从0到511),并连接到微控制器上的输入PD7..PD0PB0。如果重量等于或大于70磅,则应通过将PB1设置为1来启用安全气囊。如果重量大于5但低于70磅,则应禁用安全气囊,并且将PB2设置为可以点亮“安全气囊禁用”图标。 1.(如果重量不超过5,则B1和B2都不应设置,因为没有乘客。)
答案 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,则应初始化传感器变量。