STM32—基於模擬IIC方式讀取EEPROM
阿新 • • 發佈:2019-02-16
前言:
最近在除錯STM32L152晶片利用IIC介面讀取EEPROM的程式,總結下STM32的 IIC介面 讀取EEPROM的使用方法。
PS:由於STM32的硬體IIC存在一些問題,本文暫時使用模擬IIC進行EEPROM的讀取。STM32的硬體IIC使用方法見另外兩篇文章:傳送門1和傳送門2。
硬體平臺:STM32L152
軟體平臺:keil v5+cubeMX
函式庫:HAL函式庫
1:配置iic引腳,本例對應PC2和PC3管腳,移植修改對應管腳。
#define I2C_SCL GPIO_PIN_2 //PC2 #define I2C_SDA GPIO_PIN_3 //PC3 #define I2C_SCL_H HAL_GPIO_WritePin(GPIOC,I2C_SCL,GPIO_PIN_SET) #define I2C_SCL_L HAL_GPIO_WritePin(GPIOC,I2C_SCL,GPIO_PIN_RESET) #define I2C_SDA_H HAL_GPIO_WritePin(GPIOC,I2C_SDA,GPIO_PIN_SET) #define I2C_SDA_L HAL_GPIO_WritePin(GPIOC,I2C_SDA,GPIO_PIN_RESET)
void I2C_INIT() { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.Pin= I2C_SCL|I2C_SDA; GPIO_InitStructure.Mode=GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Pull =GPIO_NOPULL; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; HAL_GPIO_Init(GPIOC,&GPIO_InitStructure); I2C_SCL_H; I2C_SDA_H; }
2: 編寫開始、停止、應答、非應答、傳送、接收等訊號程式;
//SDA資料輸入函式
void I2C_SDA_OUT() { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.Pin =I2C_SDA; GPIO_InitStructure.Mode =GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Pull =GPIO_PULLUP; GPIO_InitStructure.Speed =GPIO_SPEED_FREQ_VERY_HIGH; HAL_GPIO_Init(GPIOC,&GPIO_InitStructure); }
//SDA資料輸出函式
void I2C_SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin =I2C_SDA;
GPIO_InitStructure.Mode =GPIO_MODE_INPUT;
GPIO_InitStructure.Pull =GPIO_NOPULL;
GPIO_InitStructure.Speed =GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOC,&GPIO_InitStructure);
}
//產生IIC開始訊號函式
void I2C_Start(void)
{
I2C_SDA_OUT();
I2C_SDA_H;
I2C_SCL_H;
delay_us(5);
I2C_SDA_L;
delay_us(6);
I2C_SCL_L;
}
//產生IIC停止訊號函式
void I2C_Stop(void)
{
I2C_SDA_OUT();
I2C_SCL_L;
I2C_SDA_L;
I2C_SCL_H;
delay_us(6);
I2C_SDA_H;
delay_us(6);
}
//IIC應答函式
void I2C_Ack(void)
{
I2C_SCL_L;
I2C_SDA_OUT();
I2C_SDA_L;
delay_us(2);
I2C_SCL_H;
delay_us(5);
I2C_SCL_L;
}
//IIC非應答函式
void I2C_NAck(void)
{
I2C_SCL_L;
I2C_SDA_OUT();
I2C_SDA_H;
delay_us(2);
I2C_SCL_H;
delay_us(5);
I2C_SCL_L;
}
//IIC等待應答函式
u8 I2C_Wait_Ack(void)
{
u8 tempTime=0;
I2C_SDA_IN();
I2C_SDA_H;
delay_us(1);
I2C_SCL_H;
delay_us(1);
while(HAL_GPIO_ReadPin(GPIO_I2C,I2C_SDA))
{
tempTime++;
if(tempTime>250)
{
I2C_Stop();
return 1;
}
}
I2C_SCL_L;
return 0;
}
//IIC傳送一個位元組函式
void I2C_Send_Byte(u8 txd)
{
u8 i=0;
I2C_SDA_OUT();
I2C_SCL_L;
for(i=0;i<8;i++)
{
if((txd&0x80)>0) //0x80 1000 0000
I2C_SDA_H;
else
I2C_SDA_L;
txd<<=1;
I2C_SCL_H;
delay_us(2);
I2C_SCL_L;
delay_us(2);
}
}
//I2C 讀取一個位元組函式
u8 I2C_Read_Byte(u8 ack)
{
u8 i=0,receive=0;
I2C_SDA_IN();
for(i=0;i<8;i++)
{
I2C_SCL_L;
delay_us(2);
I2C_SCL_H;
receive<<=1;
if(HAL_GPIO_ReadPin(GPIO_I2C,I2C_SDA))
receive++;
delay_us(1);
}
if(ack==0)
I2C_NAck();
else
I2C_Ack();
return receive;
}
3:編寫寫入EEPROM AT24C02程式。
從EEPROM中讀取一位元組資料函式。
u8 AA24x_ReadOneByte(u8 addr)
{
u8 temp=0;
I2C_Start();
I2C_Send_Byte(0xA0);//1010000
I2C_Wait_Ack();
I2C_Send_Byte(addr);
I2C_Wait_Ack();
I2C_Start();
I2C_Send_Byte(0xA1);//10100001
I2C_Wait_Ack();
temp=I2C_Read_Byte(0);
I2C_NAck();
I2C_Stop();
return temp;
}
從EEPROM中寫入一位元組資料函式。
void AA24x_WriteOneByte(u8 addr,u8 dt)
{
I2C_Start();
I2C_Send_Byte(0xA0);
I2C_Wait_Ack();
I2C_Send_Byte(addr);
I2C_Wait_Ack();
I2C_Send_Byte(dt);
I2C_Wait_Ack();
I2C_Stop();
delay_ms(10);
}