上篇針對AT24C256B DataSheet當中的地址以及功能說明,這一篇會使用STM32去對EEPROM做寫入與讀取。
首先先看一下接線的部分(x :不用接)
AT24C256B | L476RG |
---|---|
VCC | 5V |
Gnd | Gnd |
SCL | PB6 |
SDA | PB7 |
A0 | x |
A1 | x |
A2 | x |
WD | x |
照上方的接法地址會變成(1 0 1 0 0 0 0 R/W ),這時就可以知道寫入與讀取的設備地址拉,分別是0XA0(寫入)與0XA1(讀取)。
void I2C_Start()
{
HAL_GPIO_WritePin(GPIOB, SCL_Pin, SET);
HAL_GPIO_WritePin(GPIOB, SDA_Pin, SET);
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOB, SDA_Pin, RESET);
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOB, SCL_Pin, RESET);
HAL_Delay(1);
}
}
void I2C_Stop()
{
HAL_GPIO_WritePin(GPIOB, SDA_Pin, RESET);
HAL_GPIO_WritePin(GPIOB, SCL_Pin, SET);
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOB, SDA_Pin, SET);
}
void I2C_WriteByte(unsigned char dat)
{
unsigned char i = 0;
for(i=0;i<8;i++)
{
//HAL_GPIO_WritePin(GPIOB, SCL_Pin, 0);
if(dat & 0x80)
HAL_GPIO_WritePin(GPIOB,SDA_Pin ,1);
else
HAL_GPIO_WritePin(GPIOB, SDA_Pin, 0);
HAL_GPIO_WritePin(GPIOB, SCL_Pin, 1);
dat<<=1;
HAL_GPIO_WritePin(GPIOB, SCL_Pin, 0);
}
HAL_GPIO_WritePin(GPIOB, SDA_Pin, 0);
HAL_GPIO_WritePin(GPIOB, SCL_Pin, 0);
HAL_GPIO_WritePin(GPIOB, SCL_Pin, 1);
HAL_GPIO_WritePin(GPIOB, SCL_Pin, 0);
}
unsigned char I2C_ReadByte(int ACK)
{
unsigned char dat = 0, i = 0;
for(i = 0; i < 8; i++)
{
HAL_GPIO_WritePin(GPIOB, SCL_Pin, 1);
dat<<=1;
if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_3)==1)
{
dat |= 0x01;
}
//HAL_GPIO_WritePin(GPIOB, SCL_Pin, 1);
HAL_GPIO_WritePin(GPIOB, SCL_Pin, 0);
}
if(ACK == 1)
HAL_GPIO_WritePin(GPIOB, SDA_Pin, 0);
else
HAL_GPIO_WritePin(GPIOB, SDA_Pin, 1);
HAL_GPIO_WritePin(GPIOB, SCL_Pin, SET);
HAL_GPIO_WritePin(GPIOB, SCL_Pin, RESET);
HAL_GPIO_WritePin(GPIOB, SDA_Pin, RESET);
return dat;
}
void At24c256_Write(unsigned char Paddr,unsigned char Waddr, unsigned char dat)
{
I2C_Start();
I2C_WriteByte(0xA0);
HAL_Delay(1);
I2C_WriteByte(Paddr);
HAL_Delay(1);
I2C_WriteByte(Waddr);
HAL_Delay(1);
I2C_WriteByte(dat);
HAL_Delay(1);
I2C_Stop();
}
unsigned char At24c256_Read(unsigned char Paddr ,unsigned char Addr)
{
unsigned char dat = 0;
I2C_Start();
I2C_WriteByte(0xA0);
HAL_Delay(1);
I2C_WriteByte(Paddr);
HAL_Delay(1);
I2C_WriteByte(Addr);
I2C_Start();
I2C_WriteByte(0xA1);
HAL_Delay(1);
dat = I2C_ReadByte(0);
HAL_Delay(1);
I2C_Stop();
return dat;
}
手邊有LA可以接上去看看I2C是否正確,地址會顯示0x50是正常的因為最低位是R/W,實際地址為 1 0 1 0 0 0 0!
可以確定一下在寫入每一筆資料時是ACK(也就是SDA = 0),而讀取資料是NACK(也就是SDA = 1)。