Могу ли я добавить биты двух портов для создания новой битовой последовательности? - PullRequest
0 голосов
/ 11 апреля 2019

В моей лаборатории я должен протестировать 9-битное значение, но каждый порт содержит только 8 бит. Согласно инструкциям, я использую все биты в PORTD, включая PB0, чтобы получить это 9-битное значение, но у меня нет плана, как я могу это сделать, и это, по сути, вся проблема этой проблемы. В остальном все должно быть просто, мне нужно только хранить 9-битное значение, «немного заимствуя» у другого порта.

Микроконтроллер: ATmega1284

Проблема: (Задача): Датчик веса сиденья пассажира автомобиля выдает 9-битное значение (в диапазоне от 0 до 511) и подключается к входу PD7..PD0PB0 на микроконтроллере. Если вес равен или превышает 70 фунтов, подушку безопасности следует активировать, установив PB1 в 1. Если вес больше 5, но ниже 70, подушку безопасности следует отключить, а значок «Подушка безопасности отключена» должна загореться, установив PB2 в 1. (Ни B1, ни B2 не должны быть установлены, если вес 5 или меньше, так как нет пассажира).

Ответы [ 2 ]

1 голос
/ 12 апреля 2019

Биты из отдельных регистров могут быть объединены любым необходимым способом с использованием побитовых операторов:

&  – 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

Обратите внимание, что можно (с точки зрения безопасности) упростить задачу, используя только 8-битное значение в PORTD и уменьшая вдвое предельные значения. В настоящее время у вас есть: "выше 5, но ниже 70" , если вы просто прочитаете PORTD, пределы будут 3> = PORTD <35 </em>. На самом деле это может быть безопаснее - при чтении одного значения из двух отдельных регистров необходимо быть уверенным, что у вас есть значения для одного и того же образца, и что значение в первом считанном регистре не изменилось до того, как вы прочитали второй. Если в регистре PORTB будет только один младший бит, это окажет незначительное влияние, но также сделает его ограниченным по значению, если только данные не зафиксированы во время чтения.

0 голосов
/ 11 апреля 2019

Это зависит от того, является ли PB0 MSB или LSB регистра B. Но вы можете использовать переменную uint16_t и некоторые маски для получения нужного значения. Например, вы можете сделать одну из следующих вещей.

PB0 - MSB

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

PB0 - LSB

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

Это можно сделать разными способами, и это только один из них. В обоих решениях все биты регистра D являются наиболее значимыми битами, и младший бит в первом из них будет старшим битом регистра B, а во втором младшим битом будет регистр B.

Если вы хотите, чтобы ваш код соответствовал MISRA-C, вам следует инициализировать переменную датчика.

...