读AT24C08时, 频繁开机出现读出数据不正确. 请高手花费时间看一下啊!
写时可以均可以.看看程序有没能问题啊?
这和刚开机时,主机时钟稳定有关吧?
/* ========================================================= * 函 数 名: vvoid I2Cm_SetPinOUT(void) * 功能描述: 设置数据口为输触 * 调用方法: * 输入变量: * 输出变量: ========================================================= */ void I2Cm_SetPinOUT(void) { /11*****************************/ I2CDATADDR_OUT; I2CDATAOR_OUT; }
/* ========================================================= * 函 数 名: void I2Cm_SetPinIn(void) * 功能描述: 设置数据口为输入 * 调用方法: * 输入变量: * 输出变量: ========================================================= */ void I2Cm_SetPinIn(void) {
I2CDATADDR_IN; I2CDATAOR_IN; } /* ========================================================= * 函 数 名: void I2Cm_Start(void) * 功能描述: 开始 * 调用方法: * 输入变量: * 输出变量: ========================================================= */ void I2Cm_Start(void) { I2C_CLK = 1; I2C_DATA = 1; I2Cm_SetPinOUT(); I2C_DATA = 0; I2C_CLK = 0; }
/* ========================================================= * 函 数 名: void I2Cm_Stop(void) * 功能描述: 开始 * 调用方法: * 输入变量: * 输出变量: ========================================================= */ void I2Cm_Stop(void) { I2C_DATA = 0; I2Cm_SetPinOUT(); I2C_CLK = 1; I2C_DATA = 1; }
/* ========================================================= * 函 数 名:unsigned char I2Cm_CheckBusy(void) * 功能描述: 检测忙否 * 调用方法: * 输入变量: * 输出变量: ========================================================= */ void I2Cm_Reset(void) { unsigned char i; for (i = 0; i < 20; i++) { I2C_CLK = 0; I2C_CLK = 1; } I2Cm_Start(); I2C_DATA = 1; I2Cm_SetPinOUT(); I2Cm_SetPinIn(); I2C_CLK = 1; }
/* ========================================================= * 函 数 名:unsigned char I2Cm_CheckBusy(void) * 功能描述: 检测忙否 true 为不忙 false 为忙 * 调用方法: * 输入变量: * 输出变量: ========================================================= */ unsigned char I2Cm_CheckBusy(void) { unsigned char nEEPCycleCount; // EEP一次写入计数器,防止死循环 nEEPCycleCount = 0; I2C_CLK = 0; do { I2C_DATA = 1; I2Cm_SetPinOUT(); I2Cm_SetPinIn(); I2C_CLK = 1; nEEPCycleCount++; if (nEEPCycleCount > 50) I2Cm_Reset(); // 复位 if (nEEPCycleCount > 100) return false; }while (!I2C_DATA); // 检测应答位是否正确 return true; }
/* ========================================================= * 函 数 名: unsigned char I2Cm_TxByte (unsigned char I2c_TxData) * 功能描述: 发送一个字节 * 调用方法: * 输入变量: * 输出变量: ========================================================= */ unsigned char I2Cm_TxByte (unsigned char I2c_TxData) { unsigned char i, j; unsigned char nEEPCycleCount; //EEP一次写入计数器,防止死循环 nEEPCycleCount = 0; do { f_MCU_FeedDog(); if (nEEPCycleCount) I2Cm_Start(); I2Cm_SetPinOUT(); for (i = 0; i < 8; i++) { I2C_CLK = 0; j = 1 << (7 - i); if (I2c_TxData & j) I2C_DATA = 1; else I2C_DATA = 0; I2C_CLK = 1; } I2C_CLK = 0; I2Cm_SetPinIn(); I2C_CLK = 1; nEEPCycleCount++; //Prevent From Dead Cycle if (nEEPCycleCount > 20) return false; }while (I2C_DATA); //检测应答位是否正确 I2C_CLK = 0; return true; } /* ========================================================= * 函 数 名: unsigned char I2Cm_RxByte(void) * 功能描述: 读入一个字节 * 调用方法: * 输入变量: * 输出变量: ========================================================= */ unsigned char I2Cm_RxByte(void) { unsigned char i, nValue = 0; f_MCU_FeedDog(); I2Cm_SetPinIn(); for (i = 0; i < 8; i++) { I2C_CLK = 0; //时钟为低 Nop(); Nop(); I2C_CLK = 1; //时钟为高 nValue <<= 1; if(!I2C_DATA) nValue |= 0; else nValue |= 1; } I2C_CLK = 0; //时钟为低 I2Cm_Stop(); //结束位 return nValue; } /* ========================================================= * 函 数 名: unsigned char I2Cm_Read(unsigned char I2c_Address) * 功能描述: 读数据 * 调用方法: * 输入变量: * 输出变量: ========================================================= */ //unsigned char I2Cm_Read(unsigned char I2c_Address) rzm-- 8.12 int I2Cm_Read(unsigned char I2c_Address) { if(I2Cm_CheckBusy() == false) // return false; return -1; I2Cm_Start(); if(I2Cm_TxByte(0xa0) == false) // return false; return -1; if(I2Cm_TxByte(I2c_Address) == false) // return false; return -1; I2Cm_Start(); if(I2Cm_TxByte(0xa1) == false) // return false; return -1; return I2Cm_RxByte(); }
|