型号为 BR93L56-W SPI接口 4线连接,这里使用GPIO模拟SPI操作。
首先研究Timing
然后是代码:
void SPI_Init(void)
{
SPI_SCK_0;
SPI_CS_0;
SPI_MOSI_0;
}
void EEPROM_SendADDR(uint8_t send_addr)
{
uint8_t i;
for(i = 0;i<8;i++)
{
if(send_addr & 0x80)
{
SPI_MOSI_1;
}
else
{
SPI_MOSI_0;
}
send_addr<<=1;
delay_us(500);
SPI_SCK_1;
delay_us(500);
SPI_SCK_0;
}
}
uint16_t EEPROM_Receive(void)
{
uint16_t receive_data = 0;
uint8_t i;
for(i=0;i<16;i++)
{
SPI_SCK_1;
delay_us(500);
receive_data<<=1;
if(SPI_READ_MISO)
{
receive_data ++;
}
SPI_SCK_0;
delay_us(500);
}
return receive_data;
}
uint16_t EEPROM_Read(uint8_t read_addr)
{
uint16_t read_data;
uint8_t i;
uint8_t read_code = 0x06;
SPI_MOSI_0;
SPI_CS_1;
for(i = 0;i<4;i++)
{
if(read_code & 0x08)
{
SPI_MOSI_1;
}
else
{
SPI_MOSI_0;
}
read_code<<=1;
delay_us(500);
SPI_SCK_1;
delay_us(500);
SPI_SCK_0;
}
EEPROM_SendADDR(read_addr);
read_data = EEPROM_Receive();
SPI_CS_0;
return read_data;
}
void EEPROM_SendDATA(uint16_t send_data)
{
int i;
for(i = 0;i<16;i++)
{
if(send_data & 0x8000)
{
SPI_MOSI_1;
}
else
{
SPI_MOSI_0;
}
send_data<<=1;
delay_us(500);
SPI_SCK_1;
delay_us(500);
SPI_SCK_0;
}
}
void EEPROM_WEN(void)
{
SPI_MOSI_0;
SPI_CS_1;
uint8_t i;
uint8_t wen_code = 0x13;
for(i = 0;i<6;i++)
{
if(wen_code & 0x20)
{
SPI_MOSI_1;
}
else
{
SPI_MOSI_0;
}
wen_code<<=1;
delay_us(500);
SPI_SCK_1;
delay_us(500);
SPI_SCK_0;
}
wen_code = 0x01;
for(i = 0;i<6;i++)
{
if(wen_code & 0x20)
{
SPI_MOSI_1;
}
else
{
SPI_MOSI_0;
}
wen_code<<=1;
delay_us(500);
SPI_SCK_1;
delay_us(500);
SPI_SCK_0;
}
SPI_CS_0;
}
void EEPROM_Write(uint8_t write_addr,uint16_t write_data)
{
uint8_t i;
uint8_t write_code = 0x05;
EEPROM_WEN();
SPI_MOSI_0;
SPI_CS_1;
for(i = 0;i<4;i++)
{
if(write_code & 0x8)
{
SPI_MOSI_1;
}
else
{
SPI_MOSI_0;
}
write_code<<=1;
delay_us(500);
SPI_SCK_1;
delay_us(500);
SPI_SCK_0;
}
EEPROM_SendADDR(write_addr);
EEPROM_SendDATA(write_data);
SPI_CS_0;
delay_ms(6);
}
最后读写测试OK
几个注意点,主要还是得仔细看手册。
1 此EEPROM CS高电平有效
2 此EEPROM 时钟频率最快支持 2MHz clock,所以SCK延迟不能太小,频率计算要在2MHZ以下
3 此EEPROM SPI发送和接收数据 一次16bit,地址是8bit
4 Write enable (WEN)时,第6个SCK后的时钟也必须输入,也就是10011后的6-11个SCK不能忽略,数据可以任意