Какой формат вывода PINxn на atmega328p?
Я написал этот простой код для запуска на своем Arduino:
#ifndef F_CPU
#define F_CPU 16000000UL // тактовая частота 16 МГц
#endif
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
Serial.begin(9600);
DDRD = 0x00;
PORTD = 0x80; //активируем подтягивающий резистор на первом выводе порта D
while (1)
{
Serial.print(PIND);
}
return 0;
}
Я просто устанавливаю порт D в качестве входа и считываю значение в цикле. Результат PIND — 253. Что представляет это число? это в десятичных дробях? где можно посмотреть их список? Как я могу увидеть двоичное подавление вывода PIN-кода (их 8 бит). Я не хочу использовать сдвиг битов.
@Joseph a, 👍1
Обсуждение4 ответа
Serial.print(PIND, BIN);
запишет значение в PIND
в последовательный порт в представлении Base-2.
поэтому 253 - это десятичное число (11111101 в двоичной системе счисления). Разве оно не должно быть 1000 0000
, поскольку только контакт 1 преобразован в вход? Что означает это число?, @Joseph a
Это зависит от того, что вы подключили ко всем контактам PORTD. Если только к контакту 7 что-то подключено, а у остальных подтягивающий резистор не включен, они плавающие и могут иметь любое значение., @jose can u c
Я только что включил подтягивание на всех PORD с помощью PORTD = 0xFF;
, к которым ничего не подключено, и он все еще выводит 11111101
, @Joseph a
Из таблицы данных Atmega 323p: «Запись логической единицы в PINxn переключает значение PORTxn независимо от значения DDRxn», что, вероятно, не то, что вы хотели сделать. Чтобы прочитать текущее состояние регистра D, нужно прочитать PORTD, или
Serial.print(PORTD);
в вашем примере.
Обновление:
... для чего используется PIND...
PINx называется адресом входных контактов порта x, а примечание под ним гласит: «Запись в регистр контактов обеспечивает функцию переключения для ввода-вывода» и отсылает нас к общей схеме драйвера контактов (раздел 41.2 в моей копии таблицы данных). ). В этом разделе говорится, что «Запись логической единицы в PINxn переключает значение PORTxn независимо от значения DDRxn». Это единственная ссылка на этот реестр, которую я смог найти.
Обратите внимание, что регистры PORTx являются двунаправленными; тот же регистр используется для чтения или установки состояний битов порта.
Кроме того, я нигде не пишу логическую единицу для PINxn, я просто читаю это
В таблице данных не упоминается, что считывается из порта, по крайней мере, я нигде не нашел, несмотря на то, что регистр PINx описан как чтение/запись, так что ваше предположение так же верно, как и мое! ¯\_(ツ)_/¯ Но чтобы прочитать данные порта, вам нужно прочитать его регистр PORTx.
Обновление 2:
6 & 7сопоставляются с выводами кристалла и не могут использоваться
Их можно использовать. Вы можете использовать их для ввода-вывода или для внешнего кристалла, но не для того и другого. Вопрос «почему?» Это, по праву, прерогатива инженеров Atmel, но я возьмусь за это и скажу, что на чипе можно разместить гораздо больше функций, чем места для физических контактов на корпусе. Поскольку количество выводов имеет большое значение, функции приходится дублировать на одних и тех же выводах; вы сможете выбрать то, что вам нужно. SPI, PWM или ввод-вывод на DIP B2 и 3; Сброс и ввод-вывод на C6; Таймер-счетчик 1 вход, ввод/вывод, & ШИМ на D5, для нескольких примеров. Почти каждый контакт имеет несколько возможных применений (заметными исключениями являются питание и заземление). В своих целях я выделяю для этих функций контакты Crystal, Reset и UART, но могу представить себе системы, которым может потребоваться переназначить любой из них.
тогда для чего в этом случае используется PIND? что представляет собой 253
, почему использование PINB вместо этого дает мне правильный вывод, где все значения равны 1, а PORTD - нет., @Joseph a
Также я нигде не пишу логику 1 в PINxn, я просто читаю ее., @Joseph a
Быстрый вопрос, почему сопоставление портов Arduino с чипом Atmel не является прямым сопоставлением. Например, на PORTB 6 и 7 сопоставлены с выводами кристалла и не могут быть использованы
, почему так? Что делать, если я хочу их использовать?, @Joseph a
Последовательный порт имеет контакты 0 и 1.
PORTD предназначен для контактов 0,1,2,3,4,5,6,7. В том-то и проблема: вы портите контакты последовательного порта.
Примечание. При использовании кристалла/резонатора/часов эти контакты отключаются от PORTB. Это означает, что вы можете использовать PORTB и читать и записывать в него 8 бит, кристалл будет продолжать работать.
То есть, по сути, мне не следует использовать PORTD для обеспечения безопасности входных данных?, @Joseph a
Быстрый вопрос, почему сопоставление портов Arduino с чипом Atmel не является прямым сопоставлением. Например, на PORTB, 16 и 7 сопоставлены с выводами кристалла и не могут быть использованы, почему так? Что, если я хочу их использовать?, @Joseph a
После вызова Serial.begin
не меняйте ни один из этих двух битов в регистрах. Вы можете использовать остальные шесть бит. Функциональность каждого вывода фиксирована. При использовании кристалла вы больше не можете использовать эти же выводы для чего-то другого, поскольку они подключены к кристаллу. Я не уверен, понял ли я ваш вопрос., @Jot
вопрос в том, что у atmega328p 8 бит в порту B, а у Arduino 6 (2 порта зарезервированы для чего-то другого), почему так?, @Joseph a
Portb.6 и Portb.7 — это контакты для кристалла. Когда кристалл не используется, они могут быть обычными цифровыми контактами. Микросхема atmega не может назначить функцию другому контакту. Последовательный порт, кристалл, шина i2c, аналоговые входы — все это закреплено за определенными контактами. Однако один контакт может выполнять несколько разных функций., @Jot
byte valueB = PINB; // считывает значение порта B, D14-D19, в переменную valueB
Если вы тогда
Serial.print (valueB,BIN);
вы увидите значения от D19 до D14 в двоичном формате или 0 и amp; 1 с. Я не думаю, что ведущие нули отображаются, так что это может немного сбить с толку.
Serial.print (valueB);
отобразит то же значение в десятичном виде. 253 = 0b11111101 0b указывает формат по основанию 2 (двоичный). 0x используется для шестнадцатеричного формата (от 0x00 до 0xFF от 0 до 255).
Если вы используете IDE и не меняли фьюзы с платы типа Uno/Nano, IDE ожидает кристалл или резонатор на PB7 & PB6, поэтому их чтение вернет бессмысленный результат, поэтому их можно замаскировать перед печатью.
valueB = valueB & 0b00111111;
Если на других выводах внутренние подтягивающие резисторы не включены или внешние подтягивающие или понижающие резисторы не используются, выводы являются «плавающими», а их низкий входной ток означает, что любой внешний заряд может легко изменить их показания - поэтому значениеB = PINB; будет иметь ошибочные результаты.
Если порт настроен на выходы, то все контакты могут быть записаны одновременно:
PORTB = 0b0011111111; // например, устанавливаем высокий уровень от D19 до D14
- Как использовать SPI на Arduino?
- Как решить проблему «avrdude: stk500_recv(): programmer is not responding»?
- Как создать несколько запущенных потоков?
- Как подключиться к Arduino с помощью WiFi?
- avrdude ser_open() can't set com-state
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Я закирпичил свой Arduino Uno? Проблемы с загрузкой скетчей на плату
К вашему сведению, я запустил ваш код на своем MEga2560 и постоянно получаю ошибку 11111111. Возможно, вам стоит попробовать другой блок PORT или даже другой Arduino., @Sener
Я только что попробовал PORTB, и там все 1
111111
(побочный вопрос, почему порт B имеет только 6 бит?). Так что же здесь происходит с PORTD, сломанная плата?, @Joseph a