Ich hab Probleme mit dem SPI Transfer:
Ich habe einen AD7714 mit SPI an einen AtMega2560 angeschlossen.
Mit zu Fuß programmierter SPI Übetragung, also ohne dem CPU Support,
funktioniert die Kommunikation. Sobald ich meinen Treiber auf den CPU
Support umstelle bekomme ich Zufallszahlen. Die Geschwindigkeit kann
m.e. nicht das Problem sein, da ich zu Fuß schneller bin (Clock Puls
Dauer etwa 15yS) als mit dem CPU Support im langsamsten Modus (Clock
Puls etwa 32 yS bei 4 MHz).
Weiß jemand, welchen SPI Mode ich einstellen muß und wie der POL Pin des
AD7714 zu beschalten ist. Hab jetzt fast alles probiert.
Ich hab auch eine Treiber für einen AD7793, der funktioniert problemlos
mit dem CPU - SPI Interface.
Es muß scheinbar zwischen dem AD7793 und dem AD7714 Unterschiede geben.
Welche ?
Es gab hier ja Dikussionen mit einem AtMega 32 und 8, hab da aber keine
Initialisierung gefunden.
Hat wir eine Idee ?
Danke, Mario
1. y für Mikro gibt Augenkrebs :-)
2. POL = 1
3. "warum" interessiert Dich wohl nicht, sonst hättest
gegooglet/gedatenblättert und's selbst rausgefunden... ;-)
4. Datenblätter weiter studieren, Schema und Code veröffentlichen hilft
machmal auch
mit POL = 1 mein ich natürlich logisch '1' - also HIGH. Dann hast Du das
gleich wie beim 7793.
Mit "CPU Support" meinst Du wohl einen hardwaremässigen SPI Controller.
Die haben manchmal die dumme Angewohnheit Byteweise zu arbeiten obwohl
Du lieber z.B. genau 28 Bits pro Befehl übertragen möchtest. Dann hast
Du evtl. Probleme mit der Zeit, die dazwischen vertstreicht oder damit,
dass vielfache von 8 Bits übertragen werden müssen und du nicht weisst
ob die höchst- oder niederwertigsten Bits abgeschnitten (bzw. ignoriert)
warden. Bei beiden Problemen hilft ein KO und oder Datenblatt-Studium.
Viel Erfolg!
Hi,
Ich google jetzt und lese seit 1 Woche.
Meine derzeitige Konfig ist:
POL=High,
SPCR = 0x5F
SPSR = 0
die Leseroutine:
/*
empfängt ein Byte vom AD7714
Select gibt an, wie das CS Signal aussehen soll
SelectAtBegin == 0 -> CS = Low~aktiviert, ansonst unverändert
SelectAtEnd != 0 -> CS = High~deaktiviert, ansonst unverändert
*/
unsigned char AD7714_GetByte ( unsigned char SelectAtBegin, unsigned
char SelectAtEnd )
{
unsigned char x,y ;
if (SelectAtBegin == 0)
{
ADI_PART_CS_LOW ;
}
SPDR = 0 ;
while (!(SPSR & 0x80)) ;
x = SPDR ;
if (SelectAtEnd != 0)
{
ADI_PART_CS_HIGH ;
}
return (x) ;
}
die Schreibroutine:
/*
sendet ein Byte an den AD7714
Select gibt an, wie das CS Signal aussehen soll
SelectAtBegin == 0 -> CS = Low~aktiviert, ansonst unverändert
SelectAtEnd != 0 -> CS = High~deaktiviert, ansonst unverändert
*/
void AD7714_SendByte ( unsigned char data, unsigned char SelectAtBegin,
unsigned char SelectAtEnd )
{
unsigned char x,y ;
if (SelectAtBegin == 0)
{
ADI_PART_CS_LOW ;
}
SPDR = data ;
while (!(SPSR & 0x80)) ;
ADI_PART_MOSI_HIGH ;
if (SelectAtEnd != 0)
{
ADI_PART_CS_HIGH ;
}
}
Der Unterschied zwischen der CPU Version und der Zu-Fuß Version besteht
- abgesehen von der Initialisierung - einzig darin, daß dort wo
SPDR=data usw
steht, ein Call auf die Prozedur erfolgt, die das eben zu Fuß macht.
Das ADI_PART_MOSI_HIGH ;
ist wirkungslos, da es vorher draußen war und auch nicht ging.
lg Mario
Hallo Mario,
MOSI wird durch Aktivierung der SPI-Schnittstelle (mit SPE in SPCR) vom
Atmega auf High getrieben. Das sollte also nicht das Problem sein.
Noch einmal: Wie initialisiert Du DDRB PB0 (SPI SS pin) in der
"CPU-Version"? Die Datenrichtung von genau PB0 hat nämlich in der
"CPU-Version" eine besondere Bewandnis:
"Master Mode
When the SPI is configured as a Master (MSTR in SPCR is set), the user
can determine the direction of the SS pin. If SS is configured as an
output, the pin is a general output pin which does not affect the SPI
system. Typically, the pin will be driving the SS pin of the SPI Slave.
If SS is configured as an input, it must be held high to ensure Master
SPI operation. If the SS pin is driven low by peripheral circuitry when
the SPI is configured as a Master with the SS pin defined as an input,
the SPI system interprets this as another master selecting the SPI as a
slave and starting to send data to it. To avoid bus contention, the SPI
system takes the following actions:
1. The MSTR bit in SPCR is cleared and the SPI system becomes a Slave.
As a result of the SPI becoming a Slave, the MOSI and SCK pins become
inputs.
..."
LG, Sebastian
Servus Sebastian,
Ich hab im Code, in allen Dateien nach PORTB, DDRB gesucht.
Es sollte passen.
Mit Meßgerät den PORTB0 geprüft, sollte ebenfalls passen.
Es gibt die Definitionen:
// SPI Interface Ports
#define configure_pin_ss() DDRB |= 0x01 ; PORTB |= 0x01
#define configure_pin_mosi() DDRB |= 0x04 ; PORTB |= 0x04
#define configure_pin_sck() DDRB |= 0x02 ; PORTB |= 0x02
#define configure_pin_miso() DDRB &= ~0x08 ; PORTB |= 0x08
und dann in der Init-Routine:
/* enable outputs for MOSI, SCK, SS, input for MISO */
configure_pin_mosi();
configure_pin_sck();
configure_pin_miso();
configure_pin_ss() ;
SPCR = 0x5f ;
x = SPSR ;
y = SPDR ;
sollte stimmen ...
Mario
Ja, dann sollte es eigentlich auch gehen.
Jetzt wäre, glaube ich, der Quellcode (reduziert auf die einfachste
nicht funktionierende Version), ein Schaltplan, ein Foto vom Aufbau, und
ein Logikanalyzer-Trace angebracht ...
LG, Sebastian
Nope,
Ist wirklich falsch! Unter "SPI Interface Ports" definierst Du die
Portbits B 0 bis 3. Danach bedudelst Du unverständlicherweise Bits 4 bis
6... Da liegt kein Segen drauf.