Forum: Mikrocontroller und Digitale Elektronik ADS8344 und AT90CAN128


von Owen S. (senmeis)


Lesenswert?

Hallo,

ich habe versucht, einen ADS8344 ADC von TI mit dem AT90CAN128 von Atmel 
über SPI komminizieren zu lassen. Irgendwie klappt das nicht. 
Anscheinend ist das Timing nicht korrekt. Ich lasse meinen Code unten 
stehen. Ist das wahr, SPI-Daten des Slave werden automatisch vorkommen 
während der Master über SPI schreibt?
1
... 
2
SPI_MasterInit(); 
3
4
/* one ADC measurement */    
5
PORTB &= 0xFE;   // set SS to low 
6
7
// set command to ADS8344: start bit, channel 0, single ended and no power down 
8
SPI_Master_Transmit_Receive(0x87);    
9
adc_data[2] = SPI_Master_Transmit_Receive(0x00);   // highst 7 bits 
10
adc_data[1] = SPI_Master_Transmit_Receive(0x00);   // middle 8 bits 
11
adc_data[0] = SPI_Master_Transmit_Receive(0x00);   // lowest 1 bit 
12
PORTB |= 0x01;   // set SS to high 
13
... 
14
15
/*   SPI initialization */ 
16
void SPI_MasterInit(void) 
17
{ 
18
   // set MOSI, SCK and SS as output 
19
   DDRB = (1 << DDB2) | (1 << DDB1) | (1 << DDB0); 
20
   //   Enable SPI, Master, set clock rate fck/16 
21
   SPCR =(1<<SPE)|(1<<MSTR)|(1<<SPR1); 
22
} 
23
24
/*   SPI transmit and receive */ 
25
UINT8 SPI_Master_Transmit_Receive(UINT8 spi_data) 
26
{ 
27
   SPDR = spi_data; 
28
   while (!(SPSR & (1 << SPIF))); 
29
   return SPDR; 
30
}

MfG
Senmeis

von Marco (Gast)


Lesenswert?

Hallo Senmeis,

hast du den Chip richtig angeschlossen? Ich kann mich erinnern, dass der 
einen SHDN Eingang hat. Der sollte auf high liegen! Ansonsten macht der 
ADC nämlich nix ;)

Hast du ein Digitaloszi? Besser noch ein Logic Analyzer :D
Dann könntest du dir mal die Signale anschauen.

Ich wünsche dir viel erfolg

von Bensch (Gast)


Lesenswert?

> Ist das wahr, SPI-Daten des Slave werden automatisch vorkommen
während der Master über SPI schreibt?

vorkommen --> eingelesen ?

Im Datenblatt sieht's anders aus (Fig. 5 und 6).

von Kobaltchlorid (Gast)


Lesenswert?

Hast du dir das Datenblatt bezüglich der SPI-Kommunikation auch genau 
angesehen? Der ADS8344 ist etwas eigenwillig in seiner Ansteuerung. Du 
musst nämlich nach dem ersten Steuerbyte eine einzelnes (!) neuntes Bit 
senden.

Bei deinem Code werden drei normale Steuerbytes gesendet, das geht so 
nicht.

Nachfolgend meine (funktionierende) Funktion, mit der ich den ADS8344 
auslese. Ist zwar für CodevisionAVR, das Setzen des Portpins PORTB.5 
(SCK) und die SPI-Funktion muss man für WinAVR umändern, aber das 
Prinzip sollte klar sein. Die einzelnen Bytes der Messwerte muss man 
dann natürlich noch zu einem 16bit-Integer zusammensetzen.

Codeschnipsel:
1
unsigned char Messwerte[16]; //Zwischenspeicher für Messwerte 
2
//Steuerbytes für AD-Wandler:
3
const char Channel[8] =
4
{0b10001111,0b11001111,0b10011111,0b11011111,
5
0b10101111,0b11101111,0b10111111,0b11111111};
6
7
//Funktion zum Auslesen der ADC-Messwerte:
8
void read_AD(void)
9
{
10
unsigned char i;
11
for (i=0;i<8;i++)
12
  { 
13
  spi(Channel[i]); //Controlbyte senden
14
  SPCR=0x00; //SPI ausschalten
15
  //Einen einzelnen Taktimpuls senden:
16
  //**********************************
17
  delay_us(10);
18
  PORTB.5=1; //SCK auf High 
19
  delay_us(10);
20
  PORTB.5=0; //SCK wieder auf LOW
21
  delay_us(10);
22
  SPCR=0x53; //SPI wieder einschalten 
23
//*************************************  
24
  Messwerte[(i*2)+1]=spi(0); //Highbyte einlesen
25
  Messwerte[i*2]=spi(0); //Lowbyte einlesen
26
  spi(0);
27
  };
28
}
29
30
// SPI initialization
31
// SPI Type: Master
32
// SPI Clock Rate: 115,195 kHz
33
// SPI Clock Phase: Cycle Half
34
// SPI Clock Polarity: Low
35
// SPI Data Order: MSB First
36
SPCR=0x53;
37
SPSR=0x00;

von Bensch (Gast)


Lesenswert?

> Du musst nämlich nach dem ersten Steuerbyte eine einzelnes (!) neuntes Bit
senden.

Das seh ich aber in Fig. 3,5 und 6 nicht.

Lediglich das Ergebnis ist um 1 Bit verschoben, sodass man für volle 16 
Bit Auflösung 3 Byte lesen muss, das allererste ist immer L.

von Kobaltchlorid (Gast)


Lesenswert?

@ Bensch:

Zitat Datenblatt:
"Since one clock cycle of the serial clock is consumed with
BUSY going HIGH (while the MSB decision is being
made), 16 additional clocks must be given to clock out all 16
bits of data; thus, one conversion takes a minimum of 25
clock cycles to fully read the data."

Ich hab's halt mit einem einzelnen eingeschobenen Taktimpuls gemacht. 
Alternativ dazu kann man natürlich drei Bytes auslesen und diese dann 
mit shiften und umkopieren zu einem 16bit-Wert ummodeln. Jeder wie er 
mag.

von Bensch (Gast)


Lesenswert?

> Ich hab's halt mit einem einzelnen eingeschobenen Taktimpuls gemacht.

Bei ner Hardware-SPI? Viel Spass....

von Kobaltchlorid (Gast)


Lesenswert?

> Bei ner Hardware-SPI? Viel Spass....

Wie darf ich das verstehen? Wie ich den eingeschobenen einzelnen 
Taktpuls erzeuge, steht doch da. Mein Codeschnipsel läuft einwandfrei 
auf einem ATMega8.

Ich empfinde halt diese Lösung als effizienter, als drei Bytes mit 
Herumshifterei und Herumkopiererei zu einem 16bit-Wert zu verwursten.

Aber, wie gesagt, jeder wie er mag. Viele Wege führen nach Rom.

Ach ja, das Auslesen der Messwerte in ein char-Array erfolgt deshalb, 
weil der AD-Wandler als Modul für Mess- und Regelaufgaben auf einem 
RS485-Bus hängt, da muss ich die Messwerte sowieso byteweise absenden. 
Den ADS8344 habe ich damals sehr billig als Restposten bekommen, der war 
eigentlich nicht meine erste Wahl, speziell wegen des winzigen Gehäuses.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.