Forum: Mikrocontroller und Digitale Elektronik ADS7816P an ATmega1284


von Tom M. (faceless)


Lesenswert?

Guten Abend,

ich wende mich mit zwei Fragen an euch.

Im Moment experimentiere ich mit dem ATmega1284p herum. Nun möchte ich 
einen ADS7816p via SPI anbinden.

Erste Frage:

Soweit ich SPI verstanden habe, kann man an einen Master-Mikrochip 
mehrere Slave-Mikrochips hängen. Neben dem normalen SS-Pin (bei mir 
PORTB4) brauche dafür doch eigentlich nur weitere Pins dafür 
bereitstellen.

Im Moment hängt eine 7-Segmen-Anzeige (MAX7219) an meinem ATmega. Die 
funktioniert auch über die Standard-SPI-Schnittstelle. Jetzt habe ich 
mal versucht, die Schnittstelle statt mit PORTB4 mit PORTB0 umzusetzen. 
Leider hat es nicht geklappt. Habe ich da zu einfach gedacht?

Zweite Frage:

Da ich mit dem ADS7816p einen zweiten SLAVE hätte, müsste ich die 
SPI-Schnittstelle ja anders intilisiieren. Leider stehe ich, was die 
Kommunikation mit dem ADS7816p angeht gerade wie der Ochse vor dem Berg.

Meine SPI-Initialisierung:
1
//SS  PORTB4
2
//MOSI  PORTB5
3
//SCK  PORTB7
4
5
class SPI
6
{
7
    public: static void Initialize(void)
8
    {
9
      DDRB |= (1 << PORTB7) | (1 << PORTB5) | (1 << PORTB4);
10
      SPCR |= (1 << SPE) | (1 << MSTR) | (1 << SPR1);
11
    }
12
13
    public: static void TransmitByte(char byte)
14
    {
15
      SPDR = byte;
16
      while(!(SPSR & (1 << SPIF)))
17
      {
18
          ;
19
      }
20
    }
21
};
Danke schonmal :)

von Karl M. (Gast)


Lesenswert?

Hallo Tom M.,

für den ADS7816p gibt es doch ein Timing und die Angabe der zu lesenden 
Bits. Alles schön in Bildern gefasst.

Daran musst Du dich halten und nicht nur 8 Bit aus dem Datensalat 
nehmen.

Ok?

von c-hater (Gast)


Lesenswert?

Tom M. schrieb:

> Soweit ich SPI verstanden habe, kann man an einen Master-Mikrochip
> mehrere Slave-Mikrochips hängen. Neben dem normalen SS-Pin (bei mir
> PORTB4) brauche dafür doch eigentlich nur weitere Pins dafür
> bereitstellen.

Nein. Du musst sie natürlich auch entsprechend steuern.

> Im Moment hängt eine 7-Segmen-Anzeige (MAX7219) an meinem ATmega. Die
> funktioniert auch über die Standard-SPI-Schnittstelle. Jetzt habe ich
> mal versucht, die Schnittstelle statt mit PORTB4 mit PORTB0 umzusetzen.
> Leider hat es nicht geklappt. Habe ich da zu einfach gedacht?

Irgendeinen anderen Pin "statt" des designierten SS-Pin zu verwenden, 
geht nur eingeschränkt. Dieser Pin muss trotzdem entweder auf Ausgang 
konfiguriert werden oder, wenn man ihn als Eingang konfiguriert, muss 
zumindest von außen dauerhaft High anliegen.

Und natürlich musst du nun den alternative SS-Pin zusätzlich 
konfigurieren und auch benutzen, um den Slave anzusprechen. Dieser Teil 
kommt in deinem Programm überhaupt nicht vor, was soll der Unsinn, Code 
zu posten, in dem genau der Teil nicht vorkommt, in dem offensichtlich 
das Problem stecken muss?

> Da ich mit dem ADS7816p einen zweiten SLAVE hätte, müsste ich die
> SPI-Schnittstelle ja anders intilisiieren.

Sagt wer? Solange beide Slaves den gleichen SPI-Modus verwenden, 
brauchst du an der SPI-Schnittstelle selber überhaupt nichts anders zu 
initialisieren, sondern immer nur lustig im richtigen Moment mit dem 
richtigen SS-Pin wackeln, nämlich mit dem, an dem der Slave hängt, mit 
dem du gerade reden willst.

Aber ob es eine gute Idee ist, Display und AD-Wandler an den gleichen 
SPI-Bus zu hängen, würde ich nach Lektüre des DB des ADS7816 sowieso mal 
bezweifeln.

von c-hater (Gast)


Lesenswert?

Karl M. schrieb:

> für den ADS7816p gibt es doch ein Timing und die Angabe der zu lesenden
> Bits. Alles schön in Bildern gefasst.

Wo? Jedenfalls nicht im Datenblatt von TI. Das Thema SPI-Timing ist da 
alles andere als erschöpfend behandelt.

von Tom M. (faceless)


Lesenswert?

Das SPI-SS auf einen anderen Pin zu legen habe ich mittlerweile 
hinbekommen.

Wenn ich nun für meinen ADS7816 das Arduino-Beispiel nehme, dann muss 
ich den DOUT-Pin des ADS7816 an den MISO-Pin meines ATmegas hängen und 
das via SPI auslesen oder?

: Bearbeitet durch User
von Karl M. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Tom M. ,

SPI ist nicht geeignet, schau dir bitte das Diagramm der 
Datenübertragung des ADS7816p an.

http://www.ti.com/lit/ds/symlink/ads7816.pdf

/FIGURE 1. ADS7816 Basic Timing Diagrams/
Seite 9

Ich würde mir eine Klasse ADS7816 schreiben und die 3 Pins frei 
definieren.
1
struct bits {
2
  u8 b0:1;
3
  u8 b1:1;
4
  u8 b2:1;
5
  u8 b3:1;
6
  u8 b4:1;
7
  u8 b5:1;
8
  u8 b6:1;
9
  u8 b7:1;
10
} __attribute__((__packed__));
11
12
#define SBIT(port,pin) ((*(volatile struct bits*)&port).b##pin)
1
// Beispiel
2
#define PIN_CS       SBIT( PORTB, 0 )
3
#define PIN_CS_DDR   SBIT( DDRB, 0 )
4
#define PIN_DCLK     SBIT( PORTB, 1 )
5
#define PIN_DCLK_DDR SBIT( DDRB, 1 )
6
#define PIN_DOUT     SBIT( PORTB, 2 )
7
#define PIN_DOUT_DDR SBIT( DDRB, 2 )
8
9
PIN_CS = 1;
10
PIN_CS_DDR = 1; // set to output
11
PIN_DCLK = 1;
12
PIN_DCLK_DDR = 1; // set to output
13
PIN_DOUT = 1; // pullup on
14
PIN_DOUT_DDR = 0; // set to input

Man setzt CS auf 1, taktet DCLK x2, man er liest das Startbit = 0 - 1->0 
Wechesl - und danach taktet man DCLK x12 und liest jeweils MSB-LSB D11 
bis D0 aus. CS geht wieder auf 0.
Das in groben.

von Tom M. (faceless)


Lesenswert?

Jetzt bitte nicht lachen^^

1
{
2
  #define  ON      PORTB &= ~(1 << PORTB1)    //SS1 LOW
3
  #define   OFF    PORTB |= (1 << PORTB1)      //SS1 HIGH
4
5
  public: static void Clock()
6
  {
7
    PORTB |= (1 << PORTB2);                 //CLK HIGH
8
    PORTB &= ~(1 << PORTB2);    //CLK LOW
9
  }
10
11
  public: static char Read()
12
  {
13
    int value = 0;
14
15
    ON;
16
    Clock();
17
     Clock();
18
    
19
     for (int i = 11; i >= 0; i--)
20
     {
21
       Clock();
22
      if(PINB & (1 << PINB3))
23
      {
24
        value += 1 << i;
25
      }
26
      else
27
      {
28
        value += 0 <<i;
29
      }
30
    }
31
     OFF;
32
    return value;
33
  }
34
  
35
};

NACHTRAG: Es läuft, allerdings gerade nur mit 8-Bit Auflösung. Liegt es 
wohlmöglich an der Übergabe mit dem Datentyp int?

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Karl M. schrieb:

> http://www.ti.com/lit/ds/symlink/ads7816.pdf

Aha, cool, es gibt also auch ein vollständiges Datenblatt. Damit kann 
man schon eher was anfangen.

> SPI ist nicht geeignet, schau dir bitte das Diagramm der
> Datenübertragung des ADS7816p an.

Also ich lese da eher heraus, dass das wunderbar gehen müsste. 
Schlimmstenfalls müßte das gelesene Ergebnis um ein Bit nach rechts 
geschoben werden (wenn man SPI-Mode0 verwendet). Das sind zwei Takte 
Rechenaufwand für einen AVR, fällt also überhaupt nicht in's Gewicht.

Und vermutlich liesse sich auch das noch einsparen, indem man SPI-Mode3 
verwendet, dann müssten die Bits eigentlich sogar passend aligned im 
Schieberegister landen. Wäre auszuprobieren, ob das tatsächlich geht.

von Tom M. (faceless)


Lesenswert?

Also ich habe es fürs Erste so hinbekommen, vielen Dank. Also ich habe 
ja quasi meine eigene Schnittstelle geschaffen. Theoretisch könnte ich 
so weitere ADS7816P an meinem ATmega betreiben. In kommenden Schritten 
werde ich vielleicht mal versuchen den ADS übde die SPI laufen zu 
lassen, wie c-hater es anführt. Laufen andere ADS über SPI oder brauchen 
die auch ihre eigene Schnittstelle?

Nachtrag:

Ich muss die for-Schleife von 12 bis 0, statt von 11 bis 0 laufen 
lassen. Weiß jemand warum?

: Bearbeitet durch User
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.