Forum: Mikrocontroller und Digitale Elektronik Pic 24 SPI verbindung zu einem AD Wandler


von Christian (Gast)


Lesenswert?

Hallo, ich hätte hier ein Problem bei dem ich hoffe das mir irgendjemand 
damit etwas helfen könnte.

Ich versuche den PIC24FJ128Ga010 mit einem AD Wandler von TI (TLC1514) 
zu verbinden. Jedoch bekomme ich aus meinem SDO noch nicht einmal bits 
heraus (Oszi hängt dran).

Eine vermutung ist das ich die Pins falsch konfiguriert habe, doer an 
den komplett falschen pins bin. Ich verwende:
SPI2 : RG6 SCK2 , RG7 SDI2 , RG8 SDO2

Ich habe schon das Forum hier durchwühlt, jedoch leider ohne erfolg...
Schon einmal danke im Vorraus.

Code:
SPI.h
#include <p24FJ128GA010.h>


#define SPI2_CS     TRISF
#define SPI2_CS1    PORTFbits.RF2

void SPI2Init(void);

int writeSPI2 (int data);

int readSPI2(int data);



main.c

#include "SPI1.h"

//#define SPI2_CS     TRISF
//#define SPI2_CS1    PORTFbits.RF2

#define WRITE_CFR 0xA000        // write CFR register followed by 12 bit 
data
#define READ_CFR  0x9000        // read CFR register data show as SDO
#define READ_SDO  0xE000        // FIFO read, FIFO contents shown as SDO
#define A0        0x0000

#define SPI_MASTER 0x0120
#define SPI_ENABLE 0x8000


void SPI2Init(void)
{
    //config SPI2

    SPI2_CS      = 0xff00;   // set Port F as Output
    SPI2_CS1              = 1;     // disable SPI2 CS1
    SPI2CON1                    = SPI_MASTER;
    SPI2STAT                    = SPI_ENABLE;
}

int writeSPI2( int data )
{
    SPI2BUF = data;                    // write to buffer for TX
    while(!SPI2STATbits.SPIRBF);          // wait for transfer to 
complete
    return SPI2BUF;                       // read the received value
}

int readSPI2(int data)
{
    SPI2BUF = data ;                  // write to buffer for TX
    while(!SPI2STATbits.SPIRBF);      // wait for transfer to complete
    return SPI2BUF;                   // read the received value
}



void configADC(void)
{
    short int cmd,cfr,cmdw,test;
    cmd = 0x0020;                               // config
    SPI2_CS1 = 0;                              // select the adc
    writeSPI2(0xA000);                         // Wake up the adc
    SPI2_CS1 = 1;                              // deselect the adc
    cmdw = WRITE_CFR | cmd;                 // form write cmd + config
    while (1)
    {
        SPI2_CS1 = 0;                     // select adc
        //writeSPI2(WRITE_CFR&cmd);
        writeSPI2(cmdw);                   // write cmd + config
        writeSPI2(READ_CFR);              // write see cmd for config
        cfr = readSPI2(0);                  // receive config
        cfr = cfr & 0x0FFF;     // only the last three bytes are 
necessary
        SPI2_CS1 = 1;             // deselect adc
    if (cfr == cmd)            // if config correct, break and return 
main
        break;
    }
    //SPI2_CS1 = 1;
}

 void main (void)
{
    int value[100],i;

    SPI2Init();                          // Init SPI mode
    configADC();                         // config the adc through SPI

    for(i=0; i<100; i++)                 // read the first 500 ad values
    {
        SPI2_CS1 = 0;                   // select adc
        writeSPI2(READ_SDO);            // write see cmd for the FIFO
        value[i] = readSPI2 (0);       // receive FIFO
        SPI2_CS1 = 1;                    // deselect adc
    }

}

mfg Christian

von gonzo (Gast)


Lesenswert?

1.) Ist das ein PIC24 mit Peripheral Pin Select? Wenn ja, hast Du die 
Pinfunktionen entsprechend konfiguriert?

2.) Man liest von den PORT-Registern, man schreibt aber bei den PICs 
üblicherweise in die LAT-Register!
#define SPI2_CS1    LATFbits.LATF2

Was macht das Scope denn an der Clock-Leitung? Tut sich da auch nichts?

von Christian (Gast)


Angehängte Dateien:

Lesenswert?

Danke erstmal für die schnelle Antwort.

1.) PPS wird im Datenblatt zwars erwähnt aber auf eine andere Quelle 
verwiesen, "Section 12. “I/O Ports with Peripheral Pin Select (PPS)”".
Ob es unterstütz wird steht ex­pli­zit nicht dabei. Aber da dieser 
Verweis dort vorhanden ist vermute ich mal ja.

2.)damit definiere ich mein Chip Select welches bereits funktioniert.
Ich habe dies von einem Projekt übernommen und auf meinen Ausgang nur 
angepasst

3.)Einen Takt bekomme ich heraus, und mein SDO ausgang scheint auch 
etwas zu schicken.
Im Anhang habe ich das Scope bild.

Er scheint mir 0b0010 0000 0000 0000 heraus zu geben, sprich 0x2000 was 
zumindest ähnlichkeiten mit meiner Konfiguration von 0x0020 hat vll 
vertausche ich auch gerade lsb und msb, da ich nicht genau weis wann der 
Takt angefangen hat. Jedoch scheint er auch den schreib cmd (0xA000) zu 
verschlucken. Werde das noch einmal überprüfen.

von gonzo (Gast)


Lesenswert?

Ich habe mir jetzt ehrlichgesagt nicht die Mühe gemacht, Deine 
SPI-Konfig im Detail auseinanderzunehmen. Übersichtlicher wird das ganze 
beim Debuggen nämlich, wenn man die enstprechenden Bits konkret 
anspricht. Hier ein Beispiel:

SPI1STAT = 0x0000;
SPI1CON1 = 0x0000;
SPI1CON2 = 0x0000;

SPI1CON1bits.CKE = 0;    // data transmitted on rising edge
SPI1CON1bits.CKP = 0;    // clock idle state low
SPI1CON1bits.MODE16 = 0;  // 8-bit transfers
SPI1CON1bits.MSTEN = 1;    // Master Mode Enabled
SPI1CON2bits.SPIBEN = 0;  // Enhanced Buffer disabled

// 4 MHz SPI
SPI1CON1bits.SPRE = 0b111;  // Secondary Prescaler 1:1
SPI1CON1bits.PPRE = 0b01;  // Primary Prescaler 4:1
SPI1STATbits.SPIEN = 1;    // enable SPI

Was mir aber bei Deiner Config aufgefallen ist: Du scheinst die SPI im 
Byte-Modus zu initialisieren (MODE16 = 0), versuchst aber Words zu 
senden. Klar, dass er da was verschluckt ;-)

von gonzo (Gast)


Lesenswert?

Christian schrieb:
> 2.)damit definiere ich mein Chip Select welches bereits funktioniert.
> Ich habe dies von einem Projekt übernommen und auf meinen Ausgang nur
> angepasst

Ist mir schon klar, was Du damit vor hast und es ist auch schön, dass es 
in Deinem vorherigen Projekt (zufällig) gut funktioniert hat. Abgewöhnen 
solltest Du es Dir aber trotzdem ganz schnell, denn Du provozierst damit 
Read-Write-Modify-Probleme. Um genau das zu verhindern, hat uns der 
liebe Gott die LAT-Register gegeben ;-)

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.