打印

频繁上电时,用模拟I2C读24C08有时读的出,有时不能读出!!!请高

[复制链接]
2040|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
rzm2001|  楼主 | 2008-8-19 14:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
读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();
}
沙发
outstanding| | 2013-7-18 11:18 | 只看该作者
好好看看时序

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

18

主题

46

帖子

0

粉丝