PIC24FJ64GB110 и 25AA160

У меня есть 25AA160, подключенный к PIC24FJ64GB110 (100-контактный):

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

СС не используется. CS\ подключается к GND, а WP\, HOLD\ подключаются к VDD.

Я копирую/вставляю код из Microchip и изменяю несколько строк, чтобы выполнить конфигурацию моего оборудования.

Это код (извините, что длинно):

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

Я всегда получал «Ошибка EEPROM», и я не мог видеть импульсы на SO, SI и SCK на осциллографе.

Я думаю, что где-то в моем коде я должен указать SPI2 использовать эти три линии ввода-вывода как SO, SI и SCK:

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

но как? Я прав?

Большое спасибо

Вэй

Привет Должен ли я использовать подтягивающие резисторы на линиях SO, SI и SCK? Я так не думаю. Пробовал и то, и другое (с и без), никакого эффекта. Вэй

Ответы (1)

Микроконтроллеры PIC24FJ используют регистры выбора периферийных контактов для сопоставления периферийных устройств, таких как порты UART и SPI, с определенными контактами.

Доступные контакты, которые можно использовать для переназначения, помечены как RPxx или RPIxx (только ввод) на схеме контактов (100-контактный TQFP) для PIC24FJGB110.

Отображение контактов в вашем случае будет:

RD1 (SCK) тоже RP24, RD2 (SDI) тоже RP23, RD3 (SDO) тоже RP22.

Связанный код для настройки:

#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

Обратите внимание, что в случае входов контакты назначаются функции; тогда как для выходов функции назначаются контакту. Дополнительную информацию см. в разделе «Выбор вывода периферийных устройств» в техническом описании PIC24FJGB110.

Вы также должны установить контакты TRIS для выходных контактов на 0:

EEPROM_SCK_TRIS = 0;
EEPROM_SDO_TRIS = 0;
Привет Спасибо за помощь!!! Я прочитал это: ТАБЛИЦА 4-27: КАРТА РЕГИСТРАЦИИ ВЫБОРА ПЕРИФЕРИЧЕСКОГО ПИН-кода. Я так близко, но только последний бит: ' EEPROM_SCK_TRIS = 0; EEPROM_SDO_TRIS = 0; // ввод: присвоить номер RPxx функции RPINR22bits.SDI2R = 23; // вывод: назначение функции выводу RPxx RPOR11bits.RP22R = x; RPOR12bits.RP24R = у; ' какое значение я должен указать для x и y, чтобы представить SPI2 - SO и SPI2 - SCK? ура Вэй
@Wei, OUT_FN_PPS_SDO2 определяется как 10, а OUT_FN_PPS_SCK2OUT определяется как 11 в файле PPS.h - я забыл добавить это как оператор включения. Я отредактировал свой ответ. В моей системе файл PPS.h находится в папке C:\Program Files (x86)\Microchip\mplabc30\v3.30b\support\peripheral_24F\PPS.h. Возможно, вам потребуется добавить соответствующий путь в каталоги включения.
Спасибо за это! Теперь у меня есть импульсы на SCK и MOSI, но ничего на MISO. Нужно ли использовать подтягивающий резистор? Пробовал 10К на MISO, процессор зависал при записи команды. ваше здоровье
Убедитесь, что линии подключены правильно. Вывод SO EEPROM должен быть подключен к выводу SDI PIC24, а вывод SI EEPROM должен быть подключен к SDO PIC24. Кроме того, WPbar и HOLDbar EEPROM должны быть привязаны к VCC, если вы не управляете ими с PIC. В таблице данных для EEPROM ничего не упоминается о подтягивании, необходимом для SO.
Привет Большое спасибо! Оказалось неисправна микросхема EEPROM. Я заменил новый, он работает как шарм. Еще раз спасибо за вашу помощь. Моя следующая задача — чтение аналогово-цифровых данных с MCP3425 через I2C. Надеюсь, это будет не слишком сложно. BTW: Как я правильно написал твое имя, просто называй тебя 'ткросли', ладно? Я пытаюсь быть вежливым. ура Вэй
@Wei, мое имя пользователя состоит из первой буквы моего имени, а затем моей фамилии. Некоторые другие делают это по-другому, имя и первый инициал фамилии. Тогда другие просто используют свое имя, третьи свое полное имя или, может быть, что-то совершенно не связанное. В моем случае вы можете увидеть мое настоящее имя в моем профиле.