Чтение уровня выходного контакта на SAMDG55
Собираю прошивку для устройства на базе Atmel/Microchip AT SAMG55.
В простой функции активируйте несколько реле, подключенных к контактам GPIO. Поскольку я хочу блокировать разные входы / выходы, избегая одновременного высокого уровня двух конкретных выходов, мне нужно знать уровень вывода, который я установил ранее.
В другом проекте, основанном на SAMD21, была функция, которая считывает состояние выходного контакта.
static inline bool port_pin_get_output_level(const uint8_t gpio_pin)
Библиотека портов SAMG55 в ASF совсем другая, поэтому я попробовал ioport_get_pin_level(pin)
, но я не получаю ожидаемого результата. Я думаю, что это работает только с выводами, настроенными как входы.
Есть ли рекомендуемые решения?
3 ответа
Ссылаясь на Рисунок 16-2 в листе данных SAMG55 и на разделы 16.5.4 и 16.5.8:
16.5.4 Управление выходом
... Уровень, управляемый на линии ввода / вывода, может быть определен путем записи в регистр установки выходных данных (PIO_SODR) и регистр очистки выходных данных (PIO_CODR). Эти операции записи, соответственно, устанавливают и очищают регистр состояния выходных данных (PIO_ODSR), который представляет данные, передаваемые по линиям ввода-вывода....
16.5.8 Входы
Уровень на каждой линии ввода / вывода можно прочитать через PIO_PDSR. Этот регистр указывает уровень линий ввода / вывода независимо от их конфигурации, будь то однозначно входящие, или управляемые контроллером PIO, или управляемые периферийным устройством. Для чтения уровней линии ввода-вывода требуется, чтобы часы контроллера PIO были включены, в противном случае PIO_PDSR считывает уровни, присутствующие на линии ввода-вывода в то время, когда часы были отключены.
Итак, до тех пор, пока вывод настроен так, что фактический уровень на выводе всегда соответствует уровню, который мы пытаемся установить - что, например, не относится к конфигурации с открытым коллектором - тогда ответ Тарика Веллинга правильный: вы можете прочитать состояние вывода из регистра состояния выходных данных (PIO_ODSR).
Однако истинное состояние вывода, независимо от конфигурации драйвера, может быть считано (с учетом задержки повторной синхронизации, которая может быть или не иметь отношения к любому конкретному приложению) из регистра состояния данных вывода (PIO_PDSR).
Вы можете программировать на низком уровне. Вы используете высокоуровневые функции HAL для настройки, установки и сброса контактов, но перед этим вы это сделаете. Считайте значение вывода, обратившись к значению данных регистра. В AVR это можно сделать, прочитавPORTx
. В STM32 это можно сделать, прочитав значениеGPIOx->ODR
. Конечно, тогда вам нужно будет извлечь правильный штифт, но это можно сделать.
Вы также можете заглянуть внутрь определения port_pin_get_output_level
и проверьте, как они это сделали, и преобразуйте это в способ, которым эта плата / поставщик /HAL выполняет свою адресацию.
Обновить:
При поиске в техническом описании для СЭМ G55G / J. Страница 340 дает нам нужный ответ.
Уровень, управляемый на линии ввода / вывода, может быть определен путем записи в регистр установки выходных данных (PIO_SODR) и регистр очистки выходных данных (PIO_CODR). Эти операции записи, соответственно, устанавливают и очищают регистр состояния выходных данных (PIO_ODSR), который представляет данные, передаваемые по линиям ввода-вывода.
Таким образом, мы можем управлять выводом, записав в PIO_SODR
а также PIO_CODR
для установки и сброса контактов соответственно. Но также читайте изPIO_ODSR
это регистр, который содержит состояние вывода.
Быстрый поиск в Google показывает два варианта контроллеров Atmel/AVR:
считывать обратно из того же места, которое вы использовали для установки выходного значения (регистр PORTx). Это даст вам значение, которое вы записали в регистр ранее.
считайте фактическое значение с помощью регистров PINx. Это даст вам значение, которое вы действительно можете измерить на своем устройстве.
Разница между ними может быть важной: если вы установите GPIO, который опускается ниже порога логического напряжения (то есть, если он подключен к GND), на HIGH, PORTx будет читать HIGH (значение, которое вы установили), а PINx будет читать LOW (реальная стоимость).