www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit MCP3903 AD Wandler und PIC µC (SPI Kommunikation)


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: MeisterFrager (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche eine SPI Kommunikation zwischen einem MCP3903 AD Wandler 
(Slave) und einem PIC32MX460F512L Mikrocontroller (Master) herzustellen. 
Die SPI Kommunikation des Mikrocontrollers mit einem weiteren IC über 
das SPI1 Modul funktioniert bereits. Ich habe die SPI2 Schnittstelle 
genau gleich konfiguriert und nur die Frequenz angepasst. Der µC läuft 
mit einer System Clock von 80MHz. Die maximale SPI Frequenz des MCP3903 
ist 10 MHz.
Die Konfiguration erfolgt folgendermaßen:
void SPI2_MasterInit(void) {
    char rData;
    PORTSetPinsDigitalOut(SPI2_Port, SPI2_MOSI | SPI2_SCK);
    PORTSetPinsDigitalIn(SPI2_Port, SPI2_MISO);
    SPI2CONbits.ON = 0; //disabkle SPI to reset any previous

    rData = SPI2BUF; //Clears receive buffer
    //    SPI1CONbits.ENHBUF = 0;
    IFS0CLR = 0x03800000; //Clears any existing event (rx / tx/ fault interrupt)
    SPI2STATCLR = 0x40; //Clears overflow
    //Enables the SPI channel (channel, master mode enable | use 8 bit mode | turn on, clock divider)
    //    SpiChnOpen(1, SPI_CON_CKE | SPI_CON_MSTEN | SPI_CON_MODE8 | SPI_CON_ON, 1024); // divide fpb by 1024, configure the I/O ports.
    SPI2BRG = 511; //SPI Baudrate, bei SPIxBRG = 9 entspricht dies einer Frequens von 4 MHz
    SPI2CONbits.MSTEN = 1; // enable master mode
    SPI2CONbits.CKE = 0; // set clock-to-data timing
    SPI2CONbits.ON = 1; // turn SPI on
    SPI2CONbits.MODE16 = 0;
    SPI2CONbits.MODE32 = 0;
    //Enable Recieve and Transmit Interrupts
    EnableIntSPI2;
}

Der Chip Select PIN wird an anderer Stelle konfiguriert und bei einer 
Kommunikation auf 0 gesetzt.
Ich habe nun eine Endlosschleife programmiert um die Kommunikation mit 
einem recht einfachen Oszilloskop überwachen zu können. Der Programmteil 
sieht folgendermaßen aus:
    while(1){
    //DelayMS(1);
    mcp3903_actComm(); //Chip Select auf 0 setzen
    SPI2_MasterTransmit(channel); //Control Byte des AD Wandlers schreiben, in diesem Fall lesen des Config Register
    HB = SPI2_MasterReceive(0xAA); //Müll senden um etwas zu emfpangen
    MB = SPI2_MasterReceive(0x00); //Müll senden um etwas zu emfpangen
    LB = SPI2_MasterReceive(0xAA); //Müll senden um etwas zu emfpangen
    SPI2_MasterReceive(0xFF); //Müll senden um Buffer zu leeren
    mcp3903_deactComm(); //Chip Select auf 1 setzen
    }

Das Oszi erzeugt dann die angehängten Bilder. Bild 1 ist der SPI Takt, 
Bild 2 der Master Output und Bild 3 der Slave Output. Mir sticht beim 
Slave Output in Bild 3 natürlich gleich die abfallende Flanke ins Auge. 
Ich weiss jedoch nicht wie diese entstehen könnte. Der Receive Buffer 
des Mikrocontroller gibt mir immer nur 0xFF zurück, egal was ich an den 
AD Wandler sende. Bei den Bildern ist zu beachten das diese zeitlich 
verschoben sind. Ein besseres Oszi steht mir leider nicht zur Verfügung.
Alle Anschlüss Pins zwischen µC und AD Wandler sind direkt verbunden. 
Könnte es ein Problem mit der internen Konfiguration der PINS geben? 
Muss ich statt die TRIS Register in die jeweiligen Outputs und Inputs zu 
setzen evtl noch Pull Up Konfigurationen durchführen? Oder liegt hier 
wohl eher ein Fehler im Platinenlayout vor? Vielen Dank schonmal für 
jede Hilfe.

Viele Grüße,

MeisterFrager

Autor: Daddeldu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich hab mir den MCP3903 ebenfalls gegönnt und versuche den mit Arduino 
zum Laufen zu bewegen.
Bevor ich starte google ich erstmal, was bereits vorhanden ist. Das ist 
bei dem netten AD-Wandler sehr wenig.
Ich muß sagen, daß ich noch nichts aufgebaut habe und wollte mal 
nachfragen, ob dieses Projekt in der Zwischenzeit von Erfolg gekrönt 
ist.

Am Datenblatt fiel mir erstmal auf:
7.6 Config Register - Configuration Register
[...]
EXTCLK Clock Mode
XT Mode - A crystal must be placed between OSC1/OSC2 (default)
Ist der schon dran?

Also ich geh jetzt mal davon aus, daß:
    HB = SPI2_MasterReceive(0xAA); //Müll senden um etwas zu emfpangen
    MB = SPI2_MasterReceive(0x00); //Müll senden um etwas zu emfpangen
    LB = SPI2_MasterReceive(0xAA); //Müll senden um etwas zu emfpangen
das wirklich nur Müll ist, oder wird damit was konfiguriert?

Ich kümmer mich die nächste Zeit mal um diesen ADC und äre für einen 
"Anfahrhilfe" sehr dankbar.

Gruß

Autor: MeisterFrager (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Daddeldu,

das Projekt ist mittlerweile tatsächlich von Erfolg gekrönt und der 
AD-Wandler verrichtet seinen Dienst.

Der von dir zitierte Quellcode ist nur zum Auslesen der Register 
gedacht. Da ich ja über SPI kommuniziere muss ich "Müll" senden damit 
mir der AD-Wandler seine Register zurückschickt.

Um z.B. das Config Register zu beschreiben habe ich folgende Funktion 
programmiert:
void mcp3903_ADwConfigReg(u8 HB, u8 MB, u8 LB) {
    unsigned char t;
    mcp3903_actComm();
    CS_setup_time;
    SPI2_ClearBuffer();
    SPI2_MasterTransmit(SPI_device_address | (CONFIG << 1) | SPI_write_command);
    CS_setup_time;;
    SPI2_MasterTransmit(HB);
    CS_setup_time;
    SPI2_MasterTransmit(MB);
    CS_setup_time;
    SPI2_MasterTransmit(LB);
    CS_hold_time;
    mcp3903_deactComm();
    CS_disable_time;
}

Wichtig beim Lesen und Schreiben der Register ist es die im Datenblatt 
hinterlegten Zeitwerte für den Chip Select einzuhalten.

Ich habe mir dabei sehr viel von dem Beispielcode des MCP3903 Eval 
Boards von Microchip abgeschaut den kannst du hier runterladen:

http://www.microchip.com/stellent/idcplg?IdcServic...

Wenn du den AD-Wandler im Config Register auf EXTCLK = 0 schreibst dann 
brauchst du zwischen OSC1 und OSC2 einen Oszillator hinsetzen. Wenn du 
EXTCLK = 1 stellst dann kannst du den AD-Wandler auch mit einem selbst 
erzeugeten Takt betreiben (z.B. Timer Interrupt vom Mikrocontroller). 
Der AD-Wandler hat aber keinen eigenen Quarz, also ohne externe Takt 
Generierung wird er nicht laufen. Das steht auch alles im Datenblatt 
unter Kapitel "3.10 Oscillator and Master Clock Input Pins".

Ich hoffe das hilft dir weiter.

Viele Grüße

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




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.