Pagina 1 di 1

SPI tra micro con diverse tensioni

MessaggioInviato: 28 giu 2015, 23:27
da scipiusbarbatus
Saluti a tutti,
da pochissimo sto tentando di capire come svilupare alcune semplici funzioni con dei microcontrollori.
In particolare, quello che vorrei fare ora è tentare di interfacciare due micro controllori tramite SPI.
Vorrei usare come master un raspberry PI 2(CPU BCM2836 900 MHz ARM ) e come slave un ATmega328p (il micro di arduino, per intendersi).
Mentre il raspberry ha sui pin una tensione di 3v3, l'ATMEGA328p ha 5V.
Posso connettere i vari MISO e MOSI con tensioni diverse, oppure rischio di danneggiare il raspberry? Dovrei inserire un partitore di tensione tra i due?
Vi ringrazio in anticipo,
saluti

Re: SPI tra micro con diverse tensioni

MessaggioInviato: 29 giu 2015, 0:09
da TardoFreak
Si.
Si

Re: SPI tra micro con diverse tensioni

MessaggioInviato: 29 giu 2015, 0:10
da Arrow
Che io sappiasecondo me la soluzione più elegante è quella di usare degli appositi level shifter bidirezionali tipo questo:
https://www.adafruit.com/products/757
disegnato per lavorare con l'i2c ma funzionante anche con spi, uart....

oppure puoi farlo con l'integrato 74lvc245 di cui ti linko il datasheet:
http://www.adafruit.com/datasheets/sn74lvc245a.pdf
e di cui va fatta la scheda d'interfaccia (o comprata)

Col partitore che hai suggerito avresti il problema che il MOSI (Master output Slave Input) essendo a 3.3V non riuscirebbe a controllare l'in dell'atmega, potresti facilmente finire nella cosiddetta zona di indeterminazione (o almeno così credo)...

Re: SPI tra micro con diverse tensioni

MessaggioInviato: 29 giu 2015, 0:13
da TardoFreak
Il valore minimo di tensione di ingresso alto per un ATmega è di 0,7Vcc.
Quindi sarebbe di 3.5V
Si può provare, al limite non funzionerà. ;-)

Re: SPI tra micro con diverse tensioni

MessaggioInviato: 29 giu 2015, 19:02
da bobina
Proprio qualche giorno fa mi è capito di leggere un articolo su dangerous prototypes che riportava un AN della Silicon Labs su come implementare un low cost level shifter per I2C lo trovi qui. Secondo me è interessante, certo è l'ennesima versione su come implementare un level shifter, sul web c'è ne sono in tutte le salse. Poi a te servirebbe solo nella direzione atmega328 -> raspeberry magari ti è utile per prendere una decisione su come implementare il tuo circuito.
Poi mi rendo conto che potrebbe non andar bene se vuoi raggiungere delle velocità di trasferimento elevate.

Re: SPI tra micro con diverse tensioni

MessaggioInviato: 29 giu 2015, 22:15
da scipiusbarbatus
Saluti a tutti,
vi ringrazio per i vostri consigli!
Sto provando con il partitore. Per ora l'ho messo sul pin 18 dell'atmega328p. Ho inizializzato SPI, e vedo che sul pin 18 (MISO) la tensione è 0V, mentre sul pin 17 (MOSI) la tensione è 5V.
Quindi dovrei mettere il partitore su entrambi i pin? Solo sul pin17?
Grazie ancora!

Re: SPI tra micro con diverse tensioni

MessaggioInviato: 29 giu 2015, 22:26
da edgar
Se potessi alimentare l'ATmega a 3.3 V (ci arriva senza problemi) ti risparmieresti i vari level shifter. Dalle informazioni di partenza non si capisce se l'ATmega sia a se stante (e allora potresti alimentarlo a 3.3 V) o faccia parte di un modulo con altri componenti che deve funzionare a 5 V

Re: SPI tra micro con diverse tensioni

MessaggioInviato: 29 giu 2015, 22:33
da scipiusbarbatus
L'atmega è alimentato dal programmatore USB a 5V. Potrei alimentarlo a 3v3, ma ogni volta che lo programmo dovrei scollegarlo dal raspberry.
Dato che dovrò fare molte prove potrebbe essere più comodo fare due partitori.
Comunque per iniziare provo con l'alimentazione 3v3.
Grazie mille!

Re: SPI tra micro con diverse tensioni

MessaggioInviato: 29 giu 2015, 23:23
da edgar
scipiusbarbatus ha scritto:L'atmega è alimentato dal programmatore USB a 5 V

Alcuni programmatori (l'USBasp per esempio) hanno un jumper per impostare 5 V / 3.3 V

Re: SPI tra micro con diverse tensioni

MessaggioInviato: 29 giu 2015, 23:54
da scipiusbarbatus
Ok, spostato il jumper su 3v3.

Purtroppo non riesco ad ottenere la comunicazione tra i due dispositivi... e non capisco perché!
Ho collegato i seguenti pin:
ATmega------->Raspberry PI
17------------->19
18------------->21
19------------->23
22------------->20

Vi posto il codice

ATmega328p slave:
Codice: Seleziona tutto

#define F_CPU 20000000UL
#include <avr/io.h>
#include <util/delay.h>

void spi_init_slave (void)
{
   DDRB=(1<<6);                                  //MISO as OUTPUT
   SPCR=(1<<SPE);                                //Enable SPI
}

unsigned char spi_tranceiver (unsigned char data)
{
   SPDR = data;                                  //Load data into buffer
   while(!(SPSR & (1<<SPIF) ));                  //Wait until transmission complete
   return(SPDR);                                 //Return received data
}

int main(void)
{
   spi_init_slave();
   unsigned char data, buffer[10];
   uint8_t x = 0;
   
   while(1)
   {
      data = spi_tranceiver(++x);
       _delay_ms(1000);   
   }      
}



Raspberry PI 2, come master:

Codice: Seleziona tutto
import spidev
import time

spi=spidev.SpiDev()

spi.open(0,0)
try:
    while True:
        resp = spi.xfer2([0xAA])
        print "receiving:", resp[0]
        time.sleep(1.0)
except KeyboardInterrupt:
    spi.close()



Sul lato raspberry ottengo solo: "receiving 0".
Su raspberry ho provato il classico spidev_test.c e funziona.
(ottengo la sequenza di bit coretta:
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x40, 0x00, 0x00, 0x00, 0x00, 0x95,
etc.)

Riuscite a capire cosa c'è che non va? Mi potete aiutare?
Grazie ancora!