五、实例演示: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);
- }
|