PIC24FJ64GB110 und 25AA160

Ich habe einen 25AA160 mit einem PIC24FJ64GB110 (100-polig) verdrahtet:

SO - RD3 (Pin78) SI - RD2 (Pin77) SCK - RD1 (Pin76)

SS wird nicht verwendet. CS\ ist mit GND verdrahtet und WP\, HOLD\ sind mit VDD verdrahtet.

Ich kopiere/füge Code von Microchip ein und ändere einige Zeilen, um meine Hardwarekonfiguration zu erreichen.

Dies ist der Code (sorry etwas lang):

#define EEPROM_PAGE_SIZE    (unsigned)64
#define EEPROM_PAGE_MASK    (unsigned)0x003f
#define EEPROM_CMD_READ     (unsigned)0b00000011
#define EEPROM_CMD_WRITE    (unsigned)0b00000010
#define EEPROM_CMD_WRDI     (unsigned)0b00000100
#define EEPROM_CMD_WREN     (unsigned)0b00000110
#define EEPROM_CMD_RDSR     (unsigned)0b00000101
#define EEPROM_CMD_WRSR     (unsigned)0b00000001

#define EEPROM_SCK_TRIS     TRISDbits.TRISD1
#define EEPROM_SDO_TRIS     TRISDbits.TRISD3
#define EEPROM_SDI_TRIS     TRISDbits.TRISD2

struct  STATREG{
    unsigned    WIP:1;
    unsigned    WEL:1;
    unsigned    BP0:1;
    unsigned    BP1:1;
    unsigned    RESERVED:3;
    unsigned    WPEN:1;
};

union _EEPROMStatus_{
    struct  STATREG Bits;
    unsigned char   Char;
};

#define Hi(X)   (unsigned char)((X>>8)&0x00ff)
#define Lo(X)   (unsigned char)(X&0x00ff)

void SPI2INTInit()  
{  
    IFS2bits.SPI2IF = 0;    // clear interrupt flag  
    IEC2bits.SPI2IE = 0;    // enable interrupt  
    SPI2CON1 = SPI_MASTER;  // select mode    SPI_MASTER = 0x0120  
    SPI2STAT = SPI_ENABLE;  // enable the peripheral  SPI_ENABLE = 0x8000  
} 

void __attribute__((interrupt, no_auto_psv)) _SPI2Interrupt()  
{  
   IFS2bits.SPI2IF = 0;  
}

void EEPROMWriteEnable()  
{
    unsigned char Local_8;  
    Local_8 = writeSPI2(EEPROM_CMD_WREN);  
}

void EEPROMWriteDisable()  
{
    unsigned char Local_8;  
    Local_8 = writeSPI2(EEPROM_CMD_WRDI);  
}


void EEPROMWriteByte(unsigned char Data, unsigned int Address)  
{  
    unsigned char Local_8;  

    Local_8 = writeSPI2(EEPROM_CMD_WRITE);  

    Local_8 = writeSPI2(Hi(Address));  
    Local_8 = writeSPI2(Lo(Address));  

    Local_8 = writeSPI2(Data);  


    // wait for completion of previous write operation  
    while(EEPROMReadStatus().Bits.WIP);  

}

unsigned char EEPROMReadByte(unsigned int Address)
{
    unsigned char Local_8;


    Local_8 = writeSPI2(EEPROM_CMD_READ);

    Local_8 = writeSPI2(Hi(Address));
    Local_8 = writeSPI2(Lo(Address));

    Local_8 = writeSPI2(0);

    return Local_8;
}

union _EEPROMStatus_ EEPROMReadStatus()
{
    unsigned char Local_8;

    Local_8 = writeSPI2(EEPROM_CMD_RDSR);
    Local_8 = writeSPI2(0);

    return (union _EEPROMStatus_)Local_8;
}


void main()
{
WORD rxData;
    WORD txData = 0x5AAC;

SPI2INTInit();

    // Write MS byte into EEPROM address. 
    EEPROMWriteByte(Hi(txData), 0x10);
    // Write LS byte into EEPROM address. 
    EEPROMWriteByte(Lo(txData), 0x11);

   // Now Readback one data from the serial eeprom.

    // Read MS byte from EEPROM address.
    rxData =  EEPROMReadByte(0x10);
    rxData = (rxData<<8) & 0xff00;
    // Read LS byte from EEPROM address.
    rxData |= (EEPROMReadByte(0x11) & 0x00ff);
    // verify write and read SPI EEPROM (single byte)

    if( rxData != txData )
    DebugMsg("EEPROM error");
}

Ich bekam immer "EEPROM-Fehler" und konnte auf dem Oszilloskop keine Impulse auf SO, SI und SCK sehen.

Ich denke, irgendwo in meinem Code muss ich SPI2 anweisen, diese drei I/O-Leitungen als SO, SI und SCK zu verwenden:

#define EEPROM_SCK_TRIS     TRISDbits.TRISD1
#define EEPROM_SDO_TRIS     TRISDbits.TRISD3
#define EEPROM_SDI_TRIS     TRISDbits.TRISD2

aber wie? Habe ich recht?

Vielen Dank

Wei

Hallo Muss ich Pull-up-Widerstände auf SO-, SI- und SCK-Leitungen verwenden? Ich glaube nicht, dass ich das tue. Ich habe beides probiert (mit und ohne), keine Wirkung. Wei

Antworten (1)

Die PIC24FJ-Mikrocontroller verwenden Peripheral Pin Select-Register, um Peripheriegeräte wie die UART- und SPI-Ports bestimmten Pins zuzuordnen.

Verfügbare Pins, die für die Neuzuordnung verwendet werden können, sind im Pin-Diagramm (100-Pin-TQFP) für den PIC24FJGB110 als RPxx oder RPIxx (nur Eingang) gekennzeichnet.

Die Zuordnung der Pins in Ihrem Fall wäre:

RD1 (SCK) ist auch RP24, RD2 (SDI) ist auch RP23 und RD3 (SDO) ist auch RP22.

Der zugehörige Code zum Einrichten:

#include <PPS.h>    // bring in header for pin remapping peripheral library functions

#define EEPROM_SDI_PIN     23
#define EEPROM_SDO_PIN     OUT_PIN_PPS_RP22
#define EEPROM_SCK_PIN     OUT_PIN_PPS_RP24

IN_FN_PPS_SDI2 = EEPROM_SDI_PIN;           // map SDI2 to RP23 
EEPROM_SDO_PIN = OUT_FN_PPS_SDO2;          // map SDO2 to RP22 
EEPROM_SCK_PIN = OUT_FN_PPS_SCK2OUT;       // map SCK2 to RP24

Beachten Sie, dass bei Eingängen Pins einer Funktion zugeordnet sind; während bei Ausgängen Funktionen einem Pin zugewiesen werden. Weitere Informationen finden Sie im Abschnitt Peripheral Pin Select im PIC24FJGB110-Datenblatt.

Sie sollten auch die TRIS-Pins für die Ausgangspins auf 0 setzen:

EEPROM_SCK_TRIS = 0;
EEPROM_SDO_TRIS = 0;
Hallo Danke für deine Hilfe!!! Ich habe folgendes gelesen: TABELLE 4-27: PERIPHERIE-PIN-AUSWAHLREGISTRIERUNGSPLAN. Ich bin so nah, aber nur das letzte bisschen: ' EEPROM_SCK_TRIS = 0; EEPROM_SDO_TRIS = 0; // Eingabe: Weisen Sie einer Funktion eine RPxx-Nummer zu RPINR22bits.SDI2R = 23; // Ausgang: Weisen Sie einem RPxx-Pin eine Funktion zu RPOR11bits.RP22R = x; RPOR12bits.RP24R = y; ' Welchen Wert sollte ich x und y geben, um SPI2 - SO und SPI2 - SCK anzuzeigen? Prost wei
@Wei, OUT_FN_PPS_SDO2 ist als 10 definiert und OUT_FN_PPS_SCK2OUT ist als 11 in der Datei PPS.h definiert - ich habe vergessen, das als Include-Anweisung hinzuzufügen. Ich habe meine Antwort bearbeitet. Auf meinem System befindet sich PPS.h unter C:\Program Files (x86)\Microchip\mplabc30\v3.30b\support\peripheral_24F\PPS.h Möglicherweise müssen Sie den entsprechenden Pfad zu Ihren Include-Verzeichnissen hinzufügen.
Dank dafür! Ich habe jetzt Pulse auf SCK und MOSI, aber nichts auf MISO. Muss ich einen Pullup-Widerstand verwenden? Ich habe 10K auf MISO ausprobiert, der Prozessor ist beim Schreiben eines Befehls hängen geblieben. Beifall
Stellen Sie sicher, dass die Leitungen richtig angeschlossen sind. Der SO-Pin des EEPROM sollte mit dem SDI-Pin des PIC24 verbunden werden, und der SI-Pin des EEPROM sollte mit SDO des PIC24 verbunden werden. Außerdem sollten WPbar und HOLDbar des EEPROM an VCC gebunden sein, es sei denn, Sie steuern sie vom PIC aus an. Das Datenblatt für das EEPROM erwähnt nichts über einen Pullup, der für SO benötigt wird.
Hallo Vielen Dank! Es stellte sich ein defekter EEPROM-Chip heraus. Ich habe einen neuen ersetzt, es funktioniert wie ein Zauber. Danke nochmal für all deine Hilfe. Meine nächste Herausforderung beim Lesen von A/D-Daten von MCP3425 über I2C. Ich hoffe, es wäre nicht zu schwer. Übrigens: Schreibe ich deinen Namen richtig, nenne dich einfach 'Tcrosley', okay? Ich versuche höflich zu sein. Gruß Wei
@Wei, mein Benutzername setzt sich aus dem Anfangsbuchstaben meines Vornamens und dann meinem Nachnamen zusammen. Manche machen es andersherum, Vorname und Anfangsbuchstabe des Nachnamens. Dann verwenden andere einfach ihren Vornamen, andere ihren vollständigen Namen oder vielleicht etwas völlig Unabhängiges. In meinem Fall kannst du meinen echten Namen in meinem Profil sehen.