五、实例演示:MCU采用页写和顺序读操作时序完成EERPOM的访问。
1.I2C读写EEPROM芯片中断函数(I2C分为I2C1和I2C2)
void I2c1EepromReadWriteInterruptFunction(void)
{
u8State = I2C_GetState(CW_I2C1);// I2C:获取状态寄存器函数
switch(u8State)
{
case 0x08: //发送完START信号
I2C_GenerateSTART(CW_I2C1, DISABLE);// 发送START信号
I2C_Send7bitAddress(CW_I2C1, I2C_SLAVEADDRESS,0X00);// 做主时发送从机地址字节
break;
case 0x10: //发送完重复起始信号
I2C_GenerateSTART(CW_I2C1, DISABLE);
if(0 == Send**)
{
I2C_Send7bitAddress(CW_I2C1, I2C_SLAVEADDRESS,0X00); //写命令
}
else
{
I2C_Send7bitAddress(CW_I2C1, I2C_SLAVEADDRESS,0X01); //读命令,eeprom 随机读
}
break;
case 0x18: //发送完SLA+W/R字节
I2C_GenerateSTART(CW_I2C1, DISABLE);
I2C_SendData(CW_I2C1, u8Addr); //发送访问EEPROM的目标地址字节
break;
case 0x20: //发送完SLA+W后从机返回NACK
case 0x38: //主机在发送 SLA+W 阶段或者发送数据阶段丢失仲裁 或者 主机在发送 SLA+R 阶段或者回应 NACK 阶段丢失仲裁
case 0x30: //发送完一个数据字节后从机返回NACK
case 0x48: //发送完SLA+R后从机返回NACK
I2C_GenerateSTOP(CW_I2C1, ENABLE);
I2C_GenerateSTART(CW_I2C1, ENABLE);
break;
case 0x58: //接收到一个数据字节,且NACK已回复
u8Recdata[u8RecvLen++] = I2C_ReceiveData(CW_I2C1);//所有数据读取完成,NACK已发送
receivedflag =1;
I2C_GenerateSTOP(CW_I2C1, ENABLE);//发送停止条件
break;
case 0x28: //发送完1字节数据:发送EEPROM中memory地址也会产生,发送后面的数据也会产生
if(0 == Send**)
{
if(u8SendLen <WRITELEN)
{
I2C_SendData(CW_I2C1,u8Senddata[u8SendLen++]);
}
else
{
u8SendLen = 0;
Comm_** = 1;
Send** = 1;
I2C_GenerateSTOP(CW_I2C1, ENABLE);//发送完数据,发送停止信号
}
}
else//Send**=1为读,Send**=0为写。读数据发送完地址字节后,重复起始条件
{
CW_I2C1->CR_f.STA = 1; //set start //发送重复START信号,START生成函数改写后,会导致0X10状态被略过,故此处不调用函数
I2C_GenerateSTOP(CW_I2C1, DISABLE);
}
break;
case 0x40: //发送完SLA+R信号,开始接收数据
u8RecvLen = 0;
if(READLEN>1)
{
I2C_AcknowledgeConfig(CW_I2C1,ENABLE);//读取数据超过1个字节才发送ACK
}
break;
case 0x50: //接收完一字节数据,在接收最后1字节数据之前设置AA=0;
u8Recdata[u8RecvLen++] = I2C_ReceiveData(CW_I2C1);
if(u8RecvLen==READLEN-1)
{
I2C_AcknowledgeConfig(CW_I2C1,DISABLE);;
}
break;
}
I2C_ClearIrq(CW_I2C1);
}
|