mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Digitales Potentiometer (Poti) AD8400 erwartet 10bit von ATMEGA128 über SPI


Autor: Fabian (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Liebe Forenleser und uC-Anwender

Habe eine Frage betreffend Digitalem Potentiometer von Analog Device 
(AD8400) und ATMEGA 128.
Der ATMEGA128 läuft mit einem clock von 16Mhz und ist auf einem Display 
3000 2.1" montiert.
(Link Display 3000: http://www.display3000.com/)

Das Problem sieht wie folgt aus:

Der Digitale Potentiometer von Analog Device (AD8400) erwartet eine 
10bit-Nachricht um den Poti einzustellen.
(Link zu AD8400: 
http://www.analog.com/en/digital-to-analog-convert...)
Die ersten 2bits definieren die Adresse des RDAC-Speicher und da es nur 
einen einzigen gibt also folgendermassen A1=A0=0.
Alle nächsten 8bits (von der 10bit Nachricht) sind die Einstellungswerte 
von 0-255.
Programmiert wird der AD8400 über SPI, zu finden auf dem ATMEL 128 bei 
den Pins CLK (PB1), SS (PB0) und MOSI (PB2).
Da aber der SPI nur eine 8bit-Nachricht (SPSR) ausgeben kann, habe ich 
die Nachricht in 2x8bit aufgeteilt.
In der ersten 8bit-Nachricht sind lauter NULLEN und in der 
2ten-8bit-Nachricht der einzustellende Wert.
Leider übernimmt mir der Digitale Potentiometer die Einstellungen nicht 
und ich weiss nicht wieso.
Hat jemand von euch eine Idee oder einen anderen Lösungsvorschlag?

------------------code---------------------
#include <avr/io.h>
#include <avr/wdt.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdlib.h>

/**************************/
// Variablen
/**************************/

unsigned char poti_init = 0; //
unsigned char poti_adress = 0b00;//0 in 8Bit
//unsigned char poti_data = 0b11001100;//127 in 8Bit
//unsigned char poti_adress = 0;//0 in 8Bit
unsigned char poti_data = 25; //127 in 8Bit


void SPI_MasterInit(void)
{
  /*Set SS(PB0), SCK(PB1) and MOSI(PB2) output, all others input */
  DDRB = (1<<DDB0) | (1<<DDB1) | (1<<DDB2);

  /*Enable SPI, Data Order, Master Select, set clock rate fck/16 */
  SPCR = (1<<SPE) | (1<<DORD) | (1<<MSTR);


}

void SPI_MasterTransmitDelete(unsigned char poti_init)
{
  //PORTB |= (1<<PB0); // CS (oder SS hier bei ATMEG128) auf High setzen
  PORTB &= ~ (1<<PB0); // CS (oder SS hier bei ATMEG128) auf Low setzen
  /*---------------------*/
  /*Start 1. transmission*/
  SPDR = poti_init;
  /*Wait for 1. transmission complete*/
  while (!(SPSR & (1<<SPIF)))
    {
    ;
  }
  /*1. transmission finished*/

  //PORTB |= (1<<PB0); // CS (oder SS hier bei ATMEG128) auf High setzen
  //PORTB &= ~ (1<<PB0); // CS (oder SS hier bei ATMEG128) auf Low 
setzen
  /*---------------------*/
  /*Start 2. transmission*/
  SPDR = poti_init;
  /*Wait for 2. transmission complete*/
  while (!(SPSR & (1<<SPIF)))
    {
    ;
  }
  /*2. transmission finished*/
  /*---------------------*/
  /*Start 3. transmission*/
  SPDR = poti_init;
  /*Wait for 3. transmission complete*/
  while (!(SPSR & (1<<SPIF)))
    {
    ;
  }
  /*3. transmission finished*/
  /*---------------------*/
  PORTB |= (1<<PB0); // CS (oder SS hier bei ATMEG128) auf High setzen
  //PORTB &= ~ (1<<PB0); // CS (oder SS hier bei ATMEG128) auf Low 
setzen
}

void SPI_MasterTransmit(unsigned char poti_adress, unsigned char 
poti_data)
{
  //PORTB |= (1<<PB0); // CS (oder SS hier bei ATMEG128) auf High setzen
  PORTB &= ~ (1<<PB0); // CS (oder SS hier bei ATMEG128) auf Low setzen

  /*Start transmission*/
  //SPDR = poti_adress;

  /*Wait for transmission complete*/
  /*while (!(SPSR & (1<<SPIF)))
    {
    ;
  }*/
  //PORTB |= (1<<PB0); // CS (oder SS hier bei ATMEG128) auf High setzen

  //PORTB &= ~ (1<<PB0); // CS (oder SS hier bei ATMEG128) auf Low 
setzen

  SPDR = poti_data;
  while (!(SPSR & (1<<SPIF)))
    {
    ;
  }

  PORTB |= (1<<PB0); // CS (oder SS hier bei ATMEG128) auf High setzen
  //PORTB &= ~ (1<<PB0); // CS (oder SS hier bei ATMEG128) auf Low 
setzen
}

int main(void)
{
  SPI_MasterInit();
  //SPI_MasterTransmitDelete(poti_init);
  //_delay_ms(1);
  //sei();
  SPI_MasterTransmitDelete(poti_init);
  _delay_ms(2000);
  SPI_MasterTransmit(poti_adress, poti_data);

  /*while(1){

  _delay_ms(10);
  }*/
  return 0;
}
------------------code---------------------

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das wird so nicht klappen, weil du ja innerhalb der 1. Schreiboperation 
das CS bedienen müsstest. Du müsstest entweder eine Software-SPI 
realisieren, oder 8 Bit schicken, dann die ports auf normale I/O 
umschalten und noch 2 Bits manuell hinterher klappern.

Autor: Fabian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Christian

Danke für die Infos.

Verstehe jedoch deine erste Bemerkung nicht ganz oder interpretiere sie 
falsch: "Das wird so nicht klappen, weil du ja innerhalb der 1. 
Schreiboperation das CS bedienen müsstest."

Über die 2. Idee hatte ich bereits nachgedacht, würde dies jedoch anders 
realisieren.
Ich würde die ersten 2bit (A1=A0=0) über GPIO senden.
Danach das SPI "Enablen" und die 8bit Daten über SPI senden.
Dies bedeutet jedoch die ganzen Signale (clock, CS, Data) 
Softwaretechnisch zu realisieren, was nach meinem Wissensstand (Bin 
nicht der Profiprogrammierer!) zeitaufwändig wäre.

Die andere Variante (1. Variante) mit der Software-SPI hört sich 
verlockend an.
Wie müsste ich dies realisieren oder könntest du mir einen Anhaltspunkt 
(Buch, Website, Link) angeben?

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So wie ich Datenblatt verstanden habe, ist das ein echtes SPI.

Das heißt:
Du kannst soviel Bits da durch schieben, wie du willst. Sobald das CS 
auch HIGH geht, sind die letzten 10Bits gültig. Das ist SPI.

Also muss es gehen, wenn du:

- CS auf LOW legst,
- zwei Addressbits als unteren zwei von acht Bit ausgibst (MSB first),
- acht Datenbits ausgibst (MSB fisrt),
- CS auf HIGH ziehst.

Dann muss das laut SPI gehen.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Steht leider nicht so eindeutig im Datenblatt. So wie ich sein erstes 
Posting verstehe, macht er das ja schon so, aber der Chip reagiert 
nicht.

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, aus den Ausführungen unter "digital Interface" (Seite21) würde ich 
das aber so herauslesen.

Autor: Ralph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Les mal im Datenblatt deines Atmel.

Viele µC, ich weiß nicht ob es dein Atmel auch kann, können auch auf 
exotische Bitzahlen auf der SPI eingestellt werden. Es lässt sich dort 
also einstellen das zb 10 Bit gesendet werden.

Autor: Dieter Werner (dds5)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ralph wrote:
> Viele µC, ich weiß nicht ob es dein Atmel auch kann, können auch auf
> exotische Bitzahlen auf der SPI eingestellt werden.

Hast Du dafür vielleicht zufällig ein Beispiel?
Ich kenne keinen Controller bei dem das mit der Hardware-SPI möglich 
ist.

Autor: Ralph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zb XC866 von Infineon, ist ein 8052 compatibler 8 Bitter.
Datenbreite auf SPI kann von 2 - 8 Bit eingestellt werden.
Für diesen Fall müsste erst mit 2 Bit Einstellung das Kommando/Adresse 
und danach mit 8 Bit das Datenbyte gesendet werden.

Bei 32 Bit µC wäre es der TMS 470 von TI ist ein ARM7TDMI derivat.
Hier lassen sich 3 bis 16 Bit einstellen.

Autor: Markus Hu (markus5)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Fabian

Das sollte doch kein Problem sein. schick einfach 2 Byte. Zuerst Die 
Adresse und als nächstes die Daten. Die ersten 6 Bits der Daten sollten 
eigentlich aus dem Register des AD8400 rausgeschoben werden.


MOSI   X   X   X   X   X   X  A1  A0  D7  D6  D5  D4  D3  D2  D1  D0

CS  1  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   1

falls nicht: software SPI!

Autor: Ralph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist ja wieder mal ein typisches Beispiel dafür das die ATMEL AVR nur zum 
Spielen geeignet sind.
Für sinnvolle Anwendungen muss mann dann doch andere µC verwenden.

DUCKUNDWEG

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Ralph (Gast)

>Ist ja wieder mal ein typisches Beispiel dafür das die ATMEL AVR nur zum
>Spielen geeignet sind.

Das mal wieder ein typische Beispiel dafür, dass einige Entwickler von 
ICs nicht gerafft haben, dass SPI byteorientiert arbeitet. Die TLC59xx 
LED Treiber fallen mir da spontan ein. Sechzehn einfache FlopFlops a 6 
Transistoren hätten dort das Problem der 7 Bit/Digit gelöst. Wieviel 
Quadratmikrometer hätten diese 96 Transistoren gekostet? Um wieviel wäre 
IC dadurch teurer geworden?

MFG
Falk

P.S. Ich hab den virtuellen Smily schon gesehen ;-)

Autor: Fabian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
An Alle

Es funktioniert jetzt.
Habe den Poti durch einen neuen AD8400 ersetzt sowie den Code nochmals 
von Anfang an neu geschrieben.
Jetzt funktioniert alles wie es soll.
Es werden wie von Markus betont die ersten 6bits herausgeschoben.

Besten Dank und nochmals herzlichen Dank für Eure beispiellose Hilfe.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.