用STMF103 I2C2中断读写24C32,读指定长度数据没有问题,
但写超过多余一页的数据,多余一页的数据有时能写进去,有时只写了一页数据后面的数据没有写进去。
如:
I2C_EE_IRQ_Writ(buf, 0, 255);只能写到32字节(24C32 page为32Bbyte),后面的数据都没有写进去,
仿真时每写完一页数据都能进EV8-2事件中,进行写总数据减、地址增加等直到255字节的数据写完,但读出来发现,只有前面32个字节数据写进去了。
现在没有想到问题出在哪里?
下面是各个子函数:
//EEPROM写数据函数
void I2C_EE_IRQ_Write(u8* pBuffer, u16 WriteAddr, u16 NumByteToWrite)
{
u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;
Addr = WriteAddr % I2C_PageSize;
count = I2C_PageSize - Addr;
NumOfPage = NumByteToWrite / I2C_PageSize;
NumOfSingle = NumByteToWrite % I2C_PageSize;
I2C2Buf.NumByteWri
tingNow=0;
if(Addr == 0) /* If WriteAddr is I2C_PageSize aligned */
{
if(NumOfPage == 0) /* If NumByteToWrite < I2C_PageSize */
{
I2C_EE_IRQ_PageWrite(pBuffer, WriteAddr, NumOfSingle);
I2C2Buf.NumByteWritingNow=NumOfSingle;
}
else /* If NumByteToWrite > I2C_PageSize */
{
I2C_EE_IRQ_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
I2C2Buf.NumByteWritingNow=I2C_PageSize;
}
}
else /* If WriteAddr is not I2C_PageSize aligned */
{
if(NumOfPage== 0) /* If NumByteToWrite < I2C_PageSize */
{
I2C_EE_IRQ_PageWrite(pBuffer, WriteAddr, NumOfSingle);
I2C2Buf.NumByteWritingNow=NumOfSingle;
}
else/* If NumByteToWrite > I2C_PageSize */
{
if(count != 0)
{
I2C_EE_IRQ_PageWrite(pBuffer, WriteAddr, count);
I2C2Buf.NumByteWritingNow=count;
}
}
}
}
//EEPROM页写入函数
void I2C_EE_IRQ_PageWrite(u8* pBuffer, u16 WriteAddr, u16 NumByteToWrite)
{
I2C2Buf.MasterDirection= Transmitter;
I2C2Buf.MasterWComplete=0;
I2C2Buf.Wdatalen=NumByteToWrite;
I2C2Buf.SlaveADDR= EEPROM_ADDRESS;
I2C2Buf.Device_AddrOffset= WriteAddr;
I2C2Buf.Device_Addr_OffsetDone=0;
I2C_AcknowledgeConfig(I2C2, ENABLE);
I2C_ITConfig(I2C2, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR, ENABLE);
/* Send START condition */
if(I2C2->CR1 0x200)I2C2->CR1 = 0xFDFF;
I2C_GenerateSTART(I2C2, ENABLE);
}
//进入下面中断事件处理
void i2c2_evt_isr(void)
{
uint32_t lastevent= I2C_GetLastEvent(I2C2);
switch (lastevent)
{
/************************** Master Invoke**************************************/
case I2C_EVENT_MASTER_MODE_SELECT: // 0x00030001. 发送启动条件时产生的事件: EV5
{/* EV5 */
if (I2C2Buf.MasterDirection == Receiver)//I2C主模式接收
{
if (!I2C2Buf.Device_Addr_OffsetDone)
{
I2C_Send7bitAddress(I2C2,I2C2Buf.SlaveADDR,I2C_Direction_Transmitter);
}
else
{
/* Send slave Address for read */
I2C_Send7bitAddress(I2C2,I2C2Buf.SlaveADDR,I2C_Direction_Receiver);
I2C2Buf.Device_Addr_OffsetDone=0;
}
}
else//I2C主模式发送
{
I2C_Send7bitAddress(I2C2, I2C2Buf.SlaveADDR, I2C_Direction_Transmitter);
}
I2C_ITConfig(I2C2, I2C_IT_BUF , ENABLE);
break;
}
/********************** Master Receiver events ********************************/
case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: // 0x00030002. 发出读指定I2C从设备时产生的事件:EV6
{/* EV6 */
break;
}
case I2C_EVENT_MASTER_BYTE_RECEIVED: //0x00030040主收到一个字节时产生的事件:EV7
{/* EV7 */
I2C2Buf.RBuf[I2C2Buf.RCount++] = I2C_ReceiveData (I2C2);//I2C2中断读取数据
if(I2C2Buf.RCount == (I2C2Buf.Rdatalen - 1))//判断是否为倒数第2个数据
{
I2C_AcknowledgeConfig(I2C2, DISABLE);
I2C_GenerateSTOP(I2C2, ENABLE);
}
if(I2C2Buf.RCount == I2C2Buf.Rdatalen)//读到最后一个数据
{
I2C_EE_ReadClearStatus();
I2C_ITConfig(I2C2, I2C_IT_EVT | I2C_IT_ERR , DISABLE);
}
break;
}
/************************* Master Transmitter events **************************/
case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: // 0x00070082. 发出写指定I2C从设备时产生的事件:EV8 just after EV6
{/* EV8 just after EV6 */
#if (EE_ADDRESS_NUM>1)//EEPROM内部地址是16位
I2C2Buf.Addr_Count++;
if (I2C2Buf.Addr_Count < (EE_ADDRESS_NUM))
{
I2C_SendData(I2C2, I2C2Buf.Device_AddrOffset>>8);
}
#else//EEPROM内部地址是8位
I2C_SendData(I2C2, I2C2Buf.Device_AddrOffset);
I2C2Buf.RegAddr_OffsetDone=1;//EEPROM内部地址写完
#endif
break;
}
case I2C_EVENT_MASTER_BYTE_TRANSMITTING: // 0x00070080. 正在发送数据中......
{ /* EV8 */
#if (EE_ADDRESS_NUM>1)
if (!I2C2Buf.Device_Addr_OffsetDone)
{
if (I2C2Buf.Addr_Count < (EE_ADDRESS_NUM))
{
I2C_SendData(I2C2, I2C2Buf.Device_AddrOffset);
I2C2Buf.Addr_Count++;
}
else
{
I2C2Buf.Addr_Count=0;
I2C2Buf.Device_Addr_OffsetDone=1;
}
break;
}
#endif
if (I2C2Buf.MasterDirection == Receiver)
{
I2C_ITConfig(I2C2, I2C_IT_BUF , DISABLE);
I2C_GenerateSTART(I2C2, ENABLE);//I2C总线重启
break;
}
else
{
if(I2C2Buf.WCount < I2C2Buf.Wdatalen)
{
I2C_SendData(I2C2, buf[I2C2Buf.WCount++]);
}
else //小于或等于一页的数据写完成
{
I2C_ITConfig(I2C2,I2C_IT_BUF, DISABLE);
}
break;
}
}
case I2C_EVENT_MASTER_BYTE_TRANSMITTED: // 0x00070084. 一个字节数据发送完成.
{/* EV8-2 */
if (I2C2Buf.MasterDirection == Receiver)
{
break;
}
else
{
I2C_GenerateSTOP(I2C2, ENABLE);
I2C_ITConfig(I2C2, I2C_IT_EVT | I2C_IT_BUF |I2C_IT_ERR, DISABLE);
while(I2C_GetFlagStatus(I2C2 , I2C_FLAG_BUSY));//等待页写完
I2C2Buf.WBuf+= I2C2Buf.NumByteWritingNow;//写地址偏移上次写完数据的个数
I2C2Buf.WriteAddr+= I2C2Buf.NumByteWritingNow;//写地址偏移上次写的数据的个数
I2C2Buf.NumByteToWrite-= I2C2Buf.NumByteWritingNow;//写总的数据减去当前写的数据个数
if(I2C2Buf.NumByteToWrite>0)//判断数据是否写完
{
delay_ms(10);
I2C_EE_IRQ_Write(I2C2Buf.WBuf,I2C2Buf.WriteAddr,I2C2Buf.NumByteToWrite);//再次调入写数据函数
}
else
{
WriteComplete = 1;
I2C_EE_WriteClearStatus();
}
}
break;
}
}
}