Как получить значение из 15-го вывода 32-битного порта в ARM?

StackOverflow https://stackoverflow.com/questions/1810308

Вопрос

Я использую микросхему DS1620 для считывания 1-битных последовательных данных, поступающих в одной строке.Мне нужно прочитать эти данные, используя один из портов микроконтроллера ARM (LPC2378).Порты ARM являются 32-разрядными.Как мне преобразовать это значение в 1-битную переменную?

Редактировать:Другими словами, мне нужна прямая ссылка на pin-код порта.

Это было полезно?

Решение

нет 1-битных переменных, но вы можете выделить конкретный бит, например:

uint32_t original_value = whatever();
uint32_t bit15 = (original_value >> 15) & 1; /*bit15 now contains either a 1 or a 0 representing the 15th bit */

Примечание. Я не знаю, считали ли вы битовые числа, начиная с 0 или 1, поэтому > > 15 может быть выключен один, но вы поняли.

Другой вариант - использовать битовые поля, но это становится беспорядочным, и IMO не стоит того, чтобы каждый бит в значении был каким-то образом полезен. Если вам нужен только один или два бита, лучше всего использовать сдвиг и маскировку.

В целом эта статья может быть вам полезна.

Другие советы

Для вашего процессора следует использовать ответ от Evan Teran. Я просто хотел упомянуть о битовой полосе некоторых других процессоров ARM, таких как Cortex-M3. Для некоторого региона ОЗУ / Периферийные устройства все биты отображаются на отдельный адрес для легкого доступа.

См. http: / /infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/Behcjiic.html для получения дополнительной информации.

Это просто, если вы можете получить доступ к регистру порта напрямую (у меня нет никакого опыта работы с ARM), просто поразрядно И это с двоичной маской, которая соответствует требуемому разряду:

var = (PORT_REGISTER & 0x00008000);

Теперь var содержит 0, если 15-й бит равен 0, или 0x00008000, если 15-й бит равен 1.

Кроме того, вы можете сдвинуть его, если хотите, чтобы у вас было «0» или «1»:

var = ((PORT_REGISTER & 0x00008000) >> 15);

Заголовочные файлы, которые поставляются с вашим компилятором, будут содержать объявления для всех регистров микроконтроллера и биты в этих регистрах.

В этой конкретной статье давайте представим, что регистр ввода порта называется PORTA , а для нужного бита для него определена маска с именем PORTA15 .

Затем, чтобы прочитать состояние этого вывода:

PinIsSet = (PORTA & PORTA15) == PORTA15;

Или аналогичным образом, используя троичный оператор :

PinIsSet = (PORTA & PORTA15) ? 1 : 0;

В общем, обратитесь к справочному руководству, чтобы узнать, что делают все регистры и биты. Также посмотрите на некоторые примеры. ( Эта страница на веб-сайте Keil содержит и то, и другое. примеры в Интернете.)

В LPC2378 (как и в другом семействе микроконтроллеров LPC2xxxx ) порты ввода-вывода находятся в системной памяти, поэтому вам нужно объявить некоторые переменные следующим образом:

#define  DALLAS_PIN (*(volatile unsigned long int *)(0xE0028000)) /* Port 0 data register */
#define  DALLAS_DDR (*(volatile unsigned long int *)(0xE0028008)) /* Port 0 data direction reg */
#define  DALLAS_PIN (1<<15)

Пожалуйста, обратите внимание, что 0xE0028000 - это адрес регистра данных порта 0, а 0xE0028008 - адрес регистра направления данных для порта 0.Вам нужно изменить это в соответствии с портом и битом, используемыми в вашем приложении.После этого в вашей функции code код или макросы для write 1, write 0 и read должны быть примерно такими:

#define  set_dqout()    (DALLAS_DDR&=~DALLAS_PIN)   /* Let the pull-up force one, putting I/O pin in input mode */
#define  reset_dqout()  (DALLAS_DDR|=DALLAS_PIN,DALLAS_PORT&=~DALLAS_PIN) /* force zero putting the I/O in output mode and writing zero on it */
#define  read_dqin()    (DALLAS_DDR&=~DALLAS_PIN,((DALLAS_PORT & DALLAS_PIN)!= 0)) /* put i/o in input mode and test the state of the i/o pin */

Я надеюсь, что это может помочь.

С уважением!

Если вы проверяете биты, хорошо иметь в виду порядок оценки оператора C, например,

if( port & 0x80 && whatever() )

может привести к неожиданному поведению, как вы только что написали

if( port & (0x80 && whatever()) )

но, вероятно, мент

if( (port & 0x80) && whatever() )
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top