SPI Arduino Due conflitto con pinMode (), bug?


9

Considera il seguente esempio minimo, dove ho impostato pinModeprima di chiamare le funzioni 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);
}

Ora quando SPI.transfer(10,1)viene chiamato loop(), vedo sempre che il pin selezionato dallo slave scende a 1,65 V, ma non a 0 come dovrebbe! (vedi immagine sotto)

modalità pin impostata prima di chiamare le funzioni SPI

Se non chiamiamo pinMode(), in questo modo:

#include <SPI.h>

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

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

Otteniamo ciò che ci aspetteremmo quando chiamiamo SPI.transfer:

Modalità pin non impostata

È un bug o hai una spiegazione per quel comportamento?

Grazie mille in anticipo per il tuo tempo e interesse!


Non dovrebbe essere SPI.setDataMode(10, SPI_MODE1);? Anche solo il secondo è utile, come begin()chiama setDataMode. Guardando il codice sorgente sembra che la libreria SPI non modifichi il pin specificato (anche se non conosco ARM).
Gerben,

Sì hai ragione, per caso chiamo due volte setDataMode (). Domani testerò l'effetto di SPI.setDataMode (10, SPI_MODE1); Ma perché chiamare pinMode () ha questo effetto non è ancora chiaro o? @Gerben
newandlost,

@Gerben Ho modificato il mio post
newandlost

Risposte:


1

Potrebbe avere qualcosa a che fare con il resistore pull up interno. Secondo la scheda tecnica SAM3X / A,

Il controllo della resistenza di pull-up è possibile indipendentemente dalla configurazione della linea I / O.

Dopo il ripristino, tutti i pull-up sono abilitati.

Se cerchi tutti i file inclusi che trovi:

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

La riga 124 definisce la pinMode(uint32_t ulPin, uint32_t ulMode)funzione. Esaminando l'istruzione switch / case per INPUT vs INPUT_PULLUP vs OUTPUT viene visualizzato quanto segue:

  1. INPUT imposta un registro su reg = PORT_PINCFG_INEN.
  2. INPUT_PULLUP imposta un registro su reg = (PORT_PINCFG_INEN | PORT_PINCFG_PULLEN)
  3. OUTPUT imposta un registro su reg &= ~PORT_PINCFG_INEN.

Il 'registro' in ogni caso è lo stesso. Per la vita non riesco a trovare quale valore PORT_PINCFG_INEN o PORT_PINCFG_PULLEN sono definiti come, ma sono senza dubbio solo maschere a 8 bit (vengono lanciate su uint8_t quando sono assegnate al 'registro'). Quindi, possiamo supporre che qualunque bit controlli input / output sia attivo quando asserito, così come il bit di pullup. Per esempio:

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

Se i pull-up sono abilitati dopo il reset, possiamo dire che al reset:

 reg = b'xxxxxx1x';

Il punto (3) sopra implica fortemente che l'istruzione è:

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

Pertanto, se si chiama pinMode (X, OUTPUT) prima di ogni altra cosa, si otterrà la resistenza pullup abilitata. L'impostazione del pin su un ingresso cancella il bit di abilitazione pullup, dopodiché è possibile impostare il pin su un'uscita e il bit rimarrà chiaro.

Tuttavia, l'intero arguement cade verso il basso con il semplice fatto che se non si chiama pinMode () a tutti , il problema non si verifica ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.