PIC24FJ64GB110 y 25AA160

2

Tengo un 25AA160 conectado a un PIC24FJ64GB110 (100-pin):

SO - RD3 (pin78) SI - RD2 (pin77) SCK - RD1 (pin76)

SS no se utiliza. CS \ está conectado a GND y WP \, HOLD \ está conectado a VDD.

Copio / pego el código de Microchip y modifiqué algunas líneas para lograr la configuración de mi hardware.

Este es el código (lo siento un poco largo):

#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");
}

Siempre recibí un "error EEPROM" y no pude ver ningún pulso en SO, SI y SCK en el osciloscopio.

Creo que en algún lugar de mi código tengo que decirle a SPI2 que use estas tres líneas de E / S como SO, SI y SCK:

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

pero, ¿cómo? Estoy en lo correcto?

Muchas gracias

Wei

    
pregunta Wei

1 respuesta

3

Los microcontroladores PIC24FJ utilizan registros de selección de pin periférico para asignar periféricos como los puertos UART y SPI a pines específicos.

Los pines disponibles que se pueden usar para la reasignación están marcados como RPxx o RPIxx (solo entrada) en el Diagrama de pines (TQFP de 100 pines) para el PIC24FJGB110.

La asignación de pines en su caso sería:

RD1 (SCK) también es RP24, RD2 (SDI) también es RP23, y RD3 (SDO) también es RP22.

El código asociado para configurar esto:

#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

Nota en el caso de las entradas, los pines se asignan a una función; Mientras que para las salidas, las funciones se asignan a un pin. Consulte la sección Selección de pin periférico en la hoja de datos PIC24FJGB110 para obtener más información.

También debe establecer los pines TRIS para los pines de salida en 0:

EEPROM_SCK_TRIS = 0;
EEPROM_SDO_TRIS = 0;
    
respondido por el tcrosley

Lea otras preguntas en las etiquetas