PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Kommunikation zweier ICs über SPI



.patrick
02.08.2014, 15:26
Hallo!

Ich möchte einen ATmega48 und den IC ADRF6620 per SPI-Schnittstelle verbinden, damit der ATmega den zweiten IC steuern/ programmieren kann.
Die SPI-Schnittstelle des ATmega besitzt bekanntlich folgende Anschlüsse: SS SCK MISO MOSI.
Die Schnittstelle des zweiten IC besitzt aber nur drei Anschlüsse: CSn, SCLK, SDIO(serial data input/output).

Können die beiden trotzdem über SPI kommunizieren und wenn ja wie verbinde ich?
SS <->CSn
SCK <->SCLK
MISO/MOSI ??? SDIO ?

Des weiteren habe ich im Datenblatt des ATmega keine Angabe gefunden welche Spannung auf den SPI-Leitungen liegt (5V?). Der ADRF6620 verträgt nur 3.3V. Muss ich da noch was beachten?

Vielen Dank!

Gruß
.patrick

Bumbum
02.08.2014, 18:42
Hallo,

das was du vorhast wird vom AVR glaube ich nicht in Hardware unterstützt. Du musst die Kommunikation in Software nachbauen. Dazu setzt du die CS Leitung und "wackelst" selbst an der Clock-Leitung. Die Datenleitung musst du entsprechend des Datenblatts deines IC entweder als Ausgang oder als Eingang beschalten. Ich habe mir das Datenblatt zu deinem IC nicht angesehen, aber normalerweise ist die Datenleitung immer erst Ausgang, um eine Art Befehlscode zu übertragen. Dann wird je nach Befehl der Status als Ausgang beibehalten und weitere Parameter gesendet, oder auf Eingang umgeschaltet und der IC überträgt die Antwort.

Für dieses Vorhaben musst du nicht unbedingt die SS SCK MISO und MOSI Leitungen deines AVR verwenden. Ich würde dir sogar ausdrücklich raten andere zu verwenden. So vermeidest du Probleme und Wechselwirkungen während des ISP-flashen deines AVR.

Ich habe so eine Kommunikation mal für einen BMA020 von ELV umgesetzt. Aber der Code ist speziell auf diesen Sensor angepasst und kann deshalb bei dir vermutlich nicht verwendet werden. Trotzdem hier ein paar Auszüge als Denkanstoss für dich:



volatile U8 *BMAportOut;
volatile U8 *BMAportIn;
volatile U8 *BMADDR;
volatile U8 Pin_CSB;
volatile U8 Pin_SCK;
volatile U8 Pin_SDA;

#define BMA020_CSB0 *BMAportOut = ~(~*BMAportOut | 1<<Pin_CSB)
#define BMA020_CSB1 *BMAportOut = (*BMAportOut | 1<<Pin_CSB)
#define BMA020_SCK0 *BMAportOut = ~(~*BMAportOut | 1<<Pin_SCK)
#define BMA020_SCK1 *BMAportOut = (*BMAportOut | 1<<Pin_SCK)
#define BMA020_SDA0 *BMAportOut = ~(~*BMAportOut | 1<<Pin_SDA)
#define BMA020_SDA1 *BMAportOut = (*BMAportOut | 1<<Pin_SDA)
#define BMA020_SDA_output *BMADDR = (*BMADDR | 1<<Pin_SDA)
#define BMA020_SDA_input *BMADDR = ~(~*BMADDR | 1<<Pin_SDA)
#define BMA020_SDAin ((*BMAportIn & 1<<Pin_SDA) != 0)

bool BMA020_Init (volatile U8 *IOportOut, volatile U8 *IOportIn, volatile U8 *DDRport, U8 CSB, U8 SCK, U8 SDA)
{
BMAportOut = IOportOut;
BMAportIn = IOportIn;
BMADDR = DDRport;
Pin_CSB = CSB;
Pin_SCK = SCK;
Pin_SDA = SDA;

*DDRport = (*DDRport | 1<<CSB);
*DDRport = (*DDRport | 1<<SCK);
BMA020_SDA_output;

BMA020_CSB1;
BMA020_SCK1;
BMA020_SDA0;
}

void BMA020_WriteRegister (U8 Register, U8 Data)
{
BMA020_SDA_output;
BMA020_SCK1;
BMA020_CSB0;

BMA020_ByteOut (Register);
BMA020_ByteOut (Data);

BMA020_SCK1;
_delay_us (Clock_time);
BMA020_CSB1;
}

U8 BMA020_ReadRegister (U8 Register, bool ReadFinished)
{
BMA020_SDA_output;
BMA020_SCK1;
BMA020_CSB0;

BMA020_ByteOut (Register | 0b10000000);

BMA020_SDA_input;
_delay_us (Clock_time);
BMA020_SCK0;
_delay_us (Clock_time);
BMA020_SCK1;

U8 Data = BMA020_ByteIn ();

if (ReadFinished)
BMA020_CSB1;

return (Data);
}

void BMA020_ByteOut (U8 Data)
{
U8 i1;

for (i1 = 8; i1 > 0; i1--)
{
_delay_us (Clock_time);
BMA020_SCK0;

if ((Data & 0b10000000) == 0)
{
BMA020_SDA0;
Data = ((Data<<1) & 0b11111110);
}
else
{
BMA020_SDA1;
Data = ((Data<<1) | 1);
}

_delay_us (Clock_time);
BMA020_SCK1;
}
}

U8 BMA020_ByteIn (void)
{
U8 i1;
U8 Data = 0;

for (i1 = 8; i1 > 0; i1--)
{
_delay_us (Clock_time);
BMA020_SCK0;

if (BMA020_SDAin)
Data = (Data<<1) | 1;
else
Data = (Data<<1) & 0b11111110;

_delay_us (Clock_time);
BMA020_SCK1;
}

return (Data);
}


Viele Grüße
Andreas

schorsch_76
25.08.2014, 18:42
Nur zur Info, Atmel sagt in der Appnote dass es geht.
http://www.atmel.com/images/doc2585.pdf



1. Introduction
This application note describes how to setup and use the on-chip Serial Peripheral
Interface (SPI) of the AVR micro-controller. Most AVR devices come with an on board
SPI and can be configured according to this document. After a theoretical background
it will be shown how to configure the SPI
to run in both mast
er mode and slave mode

Bumbum
26.08.2014, 16:30
Hallo Schorsch,

ich müsste jetzt das Datenblatt noch mal rauskramen, aber ich bin mir ziemlich sicher, dass der Tiny48 KEINEN SPI-Master-Betrieb kann (nur Slave). Deine Application Note scheint sich allgemein auf das Thema zu beziehen und nicht speziell auf den Tiny48.

Viele Grüße
Andreas

schorsch_76
26.08.2014, 18:00
Hallo Schorsch,

ich müsste jetzt das Datenblatt noch mal rauskramen, aber ich bin mir ziemlich sicher, dass der Tiny48 KEINEN SPI-Master-Betrieb kann (nur Slave). Deine Application Note scheint sich allgemein auf das Thema zu beziehen und nicht speziell auf den Tiny48.

Viele Grüße
Andreas

Es geht ja nicht um den Tiny48 (gibts den?) sondern den Atmega48. Und da heist es im Datasheet:
28968

Bumbum
26.08.2014, 18:11
Hallo Schorsch,

da hast du recht, das mit den Controllern war eine Verwechslung von mir. Das Thema ist schon ein paar Tage her. Nach kurzem Überlegen weiß ich nun, warum es nicht geht: Der BMA verwendet kein 3-Pin SPI-Protokoll, sondern ein 2-Pin bei dem MOSI und MISO während der Kommunikation ständig wechseln. Dies ist so im Atmel mit den Standard SPI-Funktionen nicht möglich. Darum muss man das SPI-Protkoll per Software nachbilden und den MOSI/MISO Pin an entsprechender Stelle manuell entweder auf Output oder Input konfigurieren.

Viele Grüße
Andreas

RoboHolIC
26.08.2014, 22:15
Der BMA verwendet kein 3-Pin SPI-Protokoll, sondern ein 2-Pin bei dem MOSI und MISO während der Kommunikation ständig wechseln.

Der BMA020 kann SPI wahlweise mit drei und mit vier Drähten. Dabei muss man aber die erforderliche Verdrahtung genau beachten. Die Verbindungsschemata finden sich bei ELV.de im Datenblatt zum BMA020-Modul, Papier-Seite 41.

Edit:
Ups, das steht da zwar so im Datenblatt, hilft dem TO aber nicht weiter. Bitte entschuldigt die Störung.