У меня есть 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
но как? Я прав?
Большое спасибо
Вэй
Микроконтроллеры 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;
Вэй