大家有没有觉得STM32的I2C有比较严重的问题?SR1和SR2的值经常莫名的变,还有连续读写也会有问题,这里说的连续读写不是指24cxx的页读写,而是说,我如果先读10个字节,然后发停止位,后面跟着又读10个字节,就会失败了。请有使用经验的人指点,谢谢,下面是我的读写24c256的程序,请大家帮忙分析: /***************************************************************************** * 函数名:read_24cxx * 参数:读缓冲区:read_buff,读操作其始地址:read_address 读字节数量:num * 返回:操作的结果 * ******************************************************************************/ INT8U read_24cxx(INT8U *read_buff , INT16U read_address, INT8U length) { INT32U i, wait_timer; INT8U address_8bit; if((I2C1->SR1&0x0040)!=0) i=I2C1->DR; //清除SR1里的RXNE位,这一位经常无故置位 wait_timer=0xffff; // Send I2C1 START condition I2C_GenerateSTART(I2C1, ENABLE); // Test on I2C1 EV5 and clear it while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))&&(wait_timer)) wait_timer--; if(wait_timer==0) return TIME_OUT; wait_timer=0xffff; // Send I2C2 slave Address for write I2C_Send7bitAddress(I2C1, __24C_SLAVE1_ADDRESS7, I2C_Direction_Transmitter); // Test on I2C1 EV6 and clear it while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))&&(wait_timer)) wait_timer--; if(wait_timer==0) return TIME_OUT; wait_timer=0xffff; address_8bit = (INT8U)(read_address>>8); I2C_SendData(I2C1, address_8bit); //send the writing address. while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))&&(wait_timer)) wait_timer--; if(wait_timer==0) return TIME_OUT; wait_timer=0xffff; address_8bit = (INT8U)(read_address); I2C_SendData(I2C1, address_8bit); //send the writing address. while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))&&(wait_timer)) wait_timer--; if(wait_timer==0) return TIME_OUT;
wait_timer=0xffff; I2C_GenerateSTART(I2C1, ENABLE); // Test on I2C1 EV5 and clear it while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))&&(wait_timer)) wait_timer--; if(wait_timer==0) return TIME_OUT; // Send I2C2 slave Address for write wait_timer=0xffff; I2C_Send7bitAddress(I2C1, __24C_SLAVE1_ADDRESS7, I2C_Direction_Receiver); // Test on I2C1 EV6 and clear it while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))&&(wait_timer)) wait_timer--; if(wait_timer==0) return TIME_OUT; for(i=0;i<length;i++) { wait_timer=0xffff; while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))&&(wait_timer)) wait_timer--; if(wait_timer==0) break; else { read_buff=I2C_ReceiveData(I2C1); } } // Send I2C1 STOP Condition I2C_GenerateSTOP(I2C1, ENABLE);
if(wait_timer==0) return TIME_OUT; else return NO_ERROR; }
/***************************************************************************** * 函数名:write_24cxx * 参数:写缓冲区:write_buff,读操作其始地址:write_address 读字节数量:num(<=64) * 返回:操作的结果 * ******************************************************************************/ INT8U write_24cxx(INT8U * write_buff, INT16U write_address, INT8U length) { INT32U i, wait_timer; INT8U address_8bit; if(length>64) return QUANTITY_OVERRUN; //写入数量超过一页(64byte) EN_24C_WRITE; //关闭写保护 I2C_EE_WaitEepromStandbyState(); //等待E2准备好 wait_timer=0xffff; // Send I2C1 START condition I2C_GenerateSTART(I2C1, ENABLE); // Test on I2C1 EV5 and clear it while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))&&(wait_timer)) wait_timer--; if(wait_timer==0) { DIS_24C_WRITE; //恢复写保护 return TIME_OUT; } wait_timer=0xffff; // Send I2C2 slave Address for write I2C_Send7bitAddress(I2C1, __24C_SLAVE1_ADDRESS7, I2C_Direction_Transmitter); // Test on I2C1 EV6 and clear it while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))&&(wait_timer)) wait_timer--; if(wait_timer==0) { DIS_24C_WRITE; return TIME_OUT; } wait_timer=0xffff; address_8bit = (INT8U)(write_address>>8); I2C_SendData(I2C1, address_8bit); //send the writing address. while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))&&(wait_timer)) wait_timer--; if(wait_timer==0) { DIS_24C_WRITE; return TIME_OUT; } wait_timer=0xffff; address_8bit = (INT8U)(write_address); I2C_SendData(I2C1, address_8bit); //send the writing address. while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))&&(wait_timer)) wait_timer--; if(wait_timer==0) { DIS_24C_WRITE; return TIME_OUT; } for(i=0;i<length;i++) { wait_timer=0xffff; I2C_SendData(I2C1, write_buff); while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))&&(wait_timer)) wait_timer--; if(wait_timer==0) break; } // Send I2C1 STOP Condition I2C_GenerateSTOP(I2C1, ENABLE); OSTimeDly(5); //延时等待器件内部写操作结束 DIS_24C_WRITE; //恢复写保护 if(wait_timer==0) return TIME_OUT; else return NO_ERROR; } |