SPI Arduino Через конфлікт із pinMode (), помилка?


9

Розглянемо наступний мінімальний приклад, де я встановлював pinModeперед викликом функції SPI:

#include <SPI.h>

void setup() {
  pinMode(10, OUTPUT);
  SPI.begin(10);
  SPI.setDataMode(10,SPI_MODE1);
}

void loop() {
  delay(1000);
  SPI.transfer(10,1);
}

Тепер, коли мені SPI.transfer(10,1)зателефонують loop(), я завжди бачу, що вибраний контактний підключений знижується до 1,65 В, але не до 0, як слід! (див. зображення нижче)

встановлений контактний режим перед викликом функцій SPI

Якщо ми не дзвонимо pinMode()так:

#include <SPI.h>

void setup() {
  SPI.begin(10);
  SPI.setDataMode(10,SPI_MODE1);
}

void loop() {
  delay(1000);
  SPI.transfer(10,1);
}

Ми отримуємо те, чого ми очікували при дзвінку SPI.transfer:

Режим штифтів не встановлений

Це помилка чи у вас є пояснення такої поведінки?

Заздалегідь дякую за ваш час та інтерес!


Чи не повинно бути SPI.setDataMode(10, SPI_MODE1);? Також корисний лише другий, як begin()називає setDataMode. Дивлячись на вихідний код, схоже, бібліотека SPI не змінює вказаний вами контакт (хоча я не знаю ARM).
Гербен

Ja ви праві, випадково я дзвоню setDataMode () двічі. Завтра я перевірю ефект SPI.setDataMode (10, SPI_MODE1); Але чому виклик pinMode () має такий ефект, все ще не зрозуміло або? @Gerben
newandlost

@Gerben Я змінив свій пост
newandlost

Відповіді:


1

Це може мати щось спільне з внутрішнім підтягуючим резистором. Відповідно до таблиці даних SAM3X / A,

Управління підтягуючим резистором можливе незалежно від конфігурації лінії вводу / виводу.

Після скидання всі підключення активовано.

Якщо ви перекопаєте всі знайдені файли:

../Arduino/hardware/arduino/samd/cores/arduino/wiring_digtal.c

Рядок 124 визначає pinMode(uint32_t ulPin, uint32_t ulMode)функцію. Розглядаючи оператор перемикача / випадку для INPUT проти INPUT_PULLUP проти OUTPUT, ви бачите наступне:

  1. INPUT встановлює регістр на reg = PORT_PINCFG_INEN.
  2. INPUT_PULLUP встановлює реєстр reg = (PORT_PINCFG_INEN | PORT_PINCFG_PULLEN)
  3. OUTPUT встановлює регістр на reg &= ~PORT_PINCFG_INEN.

'Реєстр' у кожному випадку однаковий. Я не можу за все життя знайти, яке значення PORT_PINCFG_INEN або PORT_PINCFG_PULLEN визначено як, але вони, без сумніву, лише 8-бітні маски (вони передаються uint8_t, коли їх призначають до "регістру"). Таким чином, ми можемо припустити, що незалежно від того, який біт керує входом / виходом, активований при затвердженні, як і біт підключення. Наприклад:

 PORT_PINCFG_INEN   = b'00000001';
 PORT_PINCFG_PULLEN = b'00000010';
~PORT_PINCFG_INEN   = b'11111110';

Якщо підключення підключено після скидання, ми можемо сказати, що під час скидання:

 reg = b'xxxxxx1x';

З пункту 3 вище випливає, що інструкція:

 reg = b'xxxxxx1x' & 'b11111110';
   so
 reg = b'xxxxxx10'; // pull-up is enabled!

Тому, якщо ви зателефонуєте pinMode (X, OUTPUT) раніше всього іншого, у вас виявиться включений підтягуючий резистор. Встановлення штифта на вхід очистить біт включення підключення, після чого ви можете встановити штифт на вихід, і біт залишиться чітким.

Тим НЕ менше, вся arguement падає з простим фактом , що , якщо ви не викликаєте pinMode () взагалі , проблема не виникає ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.