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


von MeisterFrager (Gast)


Angehängte Dateien:

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:
1
void SPI2_MasterInit(void) {
2
    char rData;
3
    PORTSetPinsDigitalOut(SPI2_Port, SPI2_MOSI | SPI2_SCK);
4
    PORTSetPinsDigitalIn(SPI2_Port, SPI2_MISO);
5
    SPI2CONbits.ON = 0; //disabkle SPI to reset any previous
6
7
    rData = SPI2BUF; //Clears receive buffer
8
    //    SPI1CONbits.ENHBUF = 0;
9
    IFS0CLR = 0x03800000; //Clears any existing event (rx / tx/ fault interrupt)
10
    SPI2STATCLR = 0x40; //Clears overflow
11
    //Enables the SPI channel (channel, master mode enable | use 8 bit mode | turn on, clock divider)
12
    //    SpiChnOpen(1, SPI_CON_CKE | SPI_CON_MSTEN | SPI_CON_MODE8 | SPI_CON_ON, 1024); // divide fpb by 1024, configure the I/O ports.
13
    SPI2BRG = 511; //SPI Baudrate, bei SPIxBRG = 9 entspricht dies einer Frequens von 4 MHz
14
    SPI2CONbits.MSTEN = 1; // enable master mode
15
    SPI2CONbits.CKE = 0; // set clock-to-data timing
16
    SPI2CONbits.ON = 1; // turn SPI on
17
    SPI2CONbits.MODE16 = 0;
18
    SPI2CONbits.MODE32 = 0;
19
    //Enable Recieve and Transmit Interrupts
20
    EnableIntSPI2;
21
}

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:
1
    while(1){
2
    //DelayMS(1);
3
    mcp3903_actComm(); //Chip Select auf 0 setzen
4
    SPI2_MasterTransmit(channel); //Control Byte des AD Wandlers schreiben, in diesem Fall lesen des Config Register
5
    HB = SPI2_MasterReceive(0xAA); //Müll senden um etwas zu emfpangen
6
    MB = SPI2_MasterReceive(0x00); //Müll senden um etwas zu emfpangen
7
    LB = SPI2_MasterReceive(0xAA); //Müll senden um etwas zu emfpangen
8
    SPI2_MasterReceive(0xFF); //Müll senden um Buffer zu leeren
9
    mcp3903_deactComm(); //Chip Select auf 1 setzen
10
    }

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

von Daddeldu (Gast)


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ß

von MeisterFrager (Gast)


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:
1
void mcp3903_ADwConfigReg(u8 HB, u8 MB, u8 LB) {
2
    unsigned char t;
3
    mcp3903_actComm();
4
    CS_setup_time;
5
    SPI2_ClearBuffer();
6
    SPI2_MasterTransmit(SPI_device_address | (CONFIG << 1) | SPI_write_command);
7
    CS_setup_time;;
8
    SPI2_MasterTransmit(HB);
9
    CS_setup_time;
10
    SPI2_MasterTransmit(MB);
11
    CS_setup_time;
12
    SPI2_MasterTransmit(LB);
13
    CS_hold_time;
14
    mcp3903_deactComm();
15
    CS_disable_time;
16
}

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?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en555093

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

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.