SAM3X8E (Arduino Due) Регистры ввода-вывода IO

Как регистрируются записи IO в Arduino Due? На Arduino Uno просто установите DDRx, затем PINx для чтения, PORTx для записи, я хотел бы сделать то же самое с Arduino Due , но он имеет гораздо больше регистров, таких как PIO_OWER, PIO_OSER, PIO_CODR, PIO_SODR и т. д.). нет соответствия между регистрами Arduino Uno и Arduino Due.

Существуют также некоторые полезные функции, такие как pio_clear, pio_set, pio_get и другие, все объясненные здесь:

http://asf.atmel.com/docs /3.19.0/sam3x/html/group__sam__drivers__pio__group.html

Теперь, я думаю, я понял, что делают три упомянутые функции, но не другие, например:

 pio_configure (Pio *p_pio, const pio_type_t ul_type, const uint32_t ul_mask, const uint32_t ul_attribute)

Я не могу понять, что такое ul_attribute и ul_type.

9 голосов | спросил Alex 8 MarpmSun, 08 Mar 2015 20:45:10 +03002015-03-08T20:45:10+03:0008 2015, 20:45:10

3 ответа


7

Если вы прочитали раздел 31 Технического описания, доступный из здесь , вам может показаться немного понятнее.

Вот краткое изложение того, что я знаю:

PIO означает параллельный ввод /вывод и предлагает функциональность для чтения и записи нескольких портов регистра за раз. Где в таблице данных упоминается регистр, например PIO_OWER, библиотека Arduino имеет макросы для доступа к ним в этом формате REG_PIO? _OWER где? либо A, B, C или D для различных доступных портов.

Я, как правило, все еще использую медленную функцию pinMode () Arduino для установки ввода /вывода на контакты, поскольку он делает код более читаемым, чем такие регистровые вызовы, такие как REG_PIOC_OWER = 0xdeadbeef, но затем используйте прямые регистры для установки штырьки для выполнения /синхронизации. Пока что я ничего не сделал с помощью ввода, поэтому мои примеры основаны на результатах.

Для базового использования вы должны использовать REG_PIO? _SODR, чтобы установить выходные строки высоко, и REG_PIO? _CODR, чтобы установить их на низком уровне. Например, REG_PIOC_SODR = 0x00000002 будет устанавливать бит 1 (нумерованный с нуля) на PORTC (это цифровой цифровой контакт 33). Все остальные контакты на PORTC остаются неизменными. REG_POIC_CODR = 0x00000002 установит бит 1 на низком уровне PORTC. Опять же все остальные контакты не изменились.

Поскольку это еще не оптимально или синхронизировано, если вы работаете с параллельными данными, есть регистр, который позволяет вам записывать все 32 бита порта с помощью одного вызова. Это REG_PIO? _ODSR, поэтому REG_PIOC_ODSR = 0x00000002 теперь установит бит 1 на PORTC, а все остальные биты на PORTC будут установлены мгновенно в одной команде CPU.

Поскольку маловероятно, что вы когда-нибудь окажетесь в ситуации, когда вам нужно одновременно установить все 32 бита порта, вам нужно будет сохранить текущее значение контактов, выполнить операцию И для маскировки те, которые вы хотите изменить, выполните операцию ИЛИ, чтобы установить те, которые вы хотите установить, а затем выполните запись и снова, и это не оптимально. Чтобы преодолеть это, сам процессор выполнит маскировку для вас. Существует регистр под названием OWSR (регистр состояния записи записи), который будет маскировать любые биты, которые вы пишете в ODSR, которые не соответствуют битам, установленным в OWSR.

Итак, теперь, если мы будем называть REG_PIOC_OWER = 0x00000002 (это устанавливает бит 1 высокого уровня OWSR) и REG_PIOC_OWDR = 0xfffffffd (это очищает все биты, кроме бит 1 OWSR), а затем снова вызывает REG_PIOC_ODSR = 0x00000002, на этот раз это будет только бит 1 изменения PORTC и все остальные биты остаются неизменными. Обратите внимание на то, что OWER включает любые биты , которые установлены в 1 в значении, которое вы пишете, и что OWDR отключает любые бит , которые установлены в 1 в значении, которое вы пишете. Несмотря на то, что я это понимал, когда читал, мне все же удавалось сделать ошибку кода при написании моего первого тестового кода, думая, что OWDR отключил биты, которые не были установлены на 1 в значении, которое я написал.

Я надеюсь, что это, по крайней мере, дало вам немного понять понимание PIO должного процессора. Прочитайте и сыграйте, и если у вас появятся какие-то дополнительные вопросы, я постараюсь ответить на них.

Изменить: Еще одна вещь ...

Откуда вы знаете, какие биты PORT соответствуют цифровым линиям Due? Проверьте это: Отслеживание выводов

ответил Mick Waites 12 J0000006Europe/Moscow 2015, 11:04:41
3

Существует довольно простая эквивалентность для базового прямого доступа к выводам. Ниже приведен пример кода, который показывает, как установить цифровой контакт с высоким, а затем низким. Первый - для Arduino Due, второй - для Arduino Uno /Mega /etc.

const unsigned int imThePin = 10; //e.g. digital Pin 10

#ifdef _LIB_SAM_

    //First lets get the pin and bit mask - this can be done once at the start and then used later in the code (as long as the variables are in scope
    Pio* imThePort = g_APinDescription[imThePin].pPort; 
    unsigned int imTheMask = g_APinDescription[imThePin].ulPin; 

    //Lets set the pin high
    imThePort->PIO_SODR = imTheMask;
    //And then low
    imThePort->PIO_CODR = imTheMask;

#else

    //First lets get the pin and bit mask - this can be done once at the start and then used later in the code (as long as the variables are in scope
    volatile unsigned char* imThePort = portOutputRegister(digitalPinToPort(imThePin)); 
    unsigned char imTheMask = digitalPinToBitMask(imThePin);

    //Lets set the pin high
    *imThePort |= imTheMask;
    //Now low
    *imThePort &= ~imTheMask;

#endif

Все, что необходимо для этого, должно быть включено по умолчанию - и если не #include <Arduino.h> должно быть достаточно, чтобы получить его там.

Существуют фактически доступные функции, которые можно вызвать, если у вас есть указатель Pio, чтобы выполнить настройки /сброс /подтягивающие резисторы /и т. д. используя несколько более чистые функции вызова функций. Полный список можно найти в заголовочный файл.

ответил Tom Carpenter 12 J000000Sunday15 2015, 17:59:52
0

Это пример кода, который мигает светодиодом на выводе 33. Код, заимствованный сверху - большое спасибо за очень полезные объяснения :) Это начало проекта, чтобы поговорить с TFT-сенсорным дисплеем с сбросом 16-битного цветного пикселя данные, требующие быстрого доступа к портам. Я думаю, что у меня есть код справа - особенно строка, которая устанавливает низкий уровень вывода. Светодиод счастливо мигает.

void setup() 
{
  pinMode(33, OUTPUT); 
  REG_PIOC_OWER = 0x00000002; 
  REG_PIOC_OWDR = 0xfffffffd; 
}

void loop() 
{
  REG_PIOC_ODSR = 0x00000002; 
  delay(1000);             
  REG_PIOC_ODSR = 0x00000000;    
  delay(1000);   
}
ответил James Moxham 13 +03002017-10-13T15:45:47+03:00312017bEurope/MoscowFri, 13 Oct 2017 15:45:47 +0300 2017, 15:45:47

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132