proteus的I2C总线读写调试 24c02 EEPRAM I2C总线一个神奇的问题

2020-02-04 09:18发布

昨天学习I2C总线读写24C02,实物上总有问题,所以搬到了PROTEUS上来,用I2C DEBUGGER调试了下,发现了一个很奇怪的问题,上网搜了下,说这个的问题很少.所以贴出来,请各位大侠指导.
问题是这样的,我写了I2C的协议的一些函数,然后向24C02写一组数据,然后再把刚才写进去的数据读出来,以检测我写的函数的正确性.
源程序如下:
void main()
{
        U8 data dataWr[6]        = { 1,2,3,4,5,6};                //存到24C02的数据
        U8 data dataRd[6] = 0;                                        //从24c02读出来的数据存放处
        SendNByteData(dataWr, 0x00, 6);  
        ReceiveNByteDAta(0x00,dataRd,6);   
        while(1);       
}


//===============================================================
//        name   : void SendNByteData(U8 *dat,U8 addr,U8 byteLength)
//  fuction: 从发送N字节长度数据 ,N = byteLength,写入以addr为起始地址的数据区
//  input  :  U8 *dat:数据指针(或数组),byteLength:数据长度(以字节单位)                 
//  output :  1: 读写成功   0: 读写失败
//===============================================================
bit SendNByteData(U8 *dat, U8 addr, U8 byteLength)
        {
                U8 i = 0;
                bit bStart = 0;          //启动标志
                I2C_Stop(); //停止总线,总线初始化
                bStart = I2C_Start();
                if (!bStart) return 0; //启动失败,返回读写失败
                I2C_SendByte(0xa0);   //I2C从地址,写
                I2C_ReadAck(); //读取应答
                I2C_SendByte(addr);          //发送起始地址
                I2C_ReadAck();
                for (i = 0; i < byteLength; i++)
                {
                        I2C_SendByte(*(dat+i));
       
                        I2C_ReadAck();        //接收应答       
                }
                I2C_Stop(); //停止总线
                return 1;
        }

//===============================================================
//        name   : bit ReceiveNByteDAta(U8 *dat; U8 byteLength)
//  fuction: 接收N字节数据,数据从addr字址读出,存在变量dat指向的N个字节数据区段,N = byteLength;
//  input  :  void
//  output :  TRUE : 读写成功   FALSE: 读写失败
//===============================================================
bit ReceiveNByteDAta(U8 addr, U8 *dat, U8 byteLength)
{

       
        U8 i = 0;
        bit bStart = 0;          //启动标志
        I2C_Stop(); //总线初始化
        bStart = I2C_Start();
        if (!bStart) return 0; //启动失败,返回读写失败
        I2C_SendByte(0xa0);   //I2C从地址,写
        I2C_ReadAck();//读取应答                     ************************   问题一
        I2C_SendByte(addr);          //发送读起始地址
        I2C_ReadAck();
        I2C_Start();           //依据时序,再次启动
        I2C_SendByte(0xa1);   //i2c从地址,读,设置字地址后主设备读读数据模式由写数据转读数据)
        I2C_ReadAck();
        for (i = 0; i < byteLength - 1; i++)
        {
                *(dat + i) = I2C_ReceiveByte();
                I2C_SendAck();        //发送应答       
        }
        *(dat + i) = I2C_ReceiveByte(); //最后一个字节数据,要发送非应答
        I2C_SendNoAck();  //发送非应答,通知停止发送方发送数据
        I2C_Stop(); //停止总线
        return 1;
}

Proteus原理图见图一,

(原文件名:图片一1.jpg)


这里有一个很神奇的问题:
问题一: 将上面函数写入proteus的单片机,发现main函数中: 第一个函数SendNByteData(dataWr, 0x00, 6); 所行完毕,很正常,第二个函数        ReceiveNByteDAta(0x00,dataRd,6);   竟然在第一个读取应答处,读到的不是应答信号,而是非应答信号.(注意两个函数前面部分是一样的代码,可是第一个函数都一步执行到尾了,第二个函数竟然没有应答啊?????????这是为什么)  ,proteus里的ic2 debuuger  调试结果见图二:


(原文件名:图二二.jpg)

问题二 :   当我将主函数将SendNByteData(dataWr, 0x00, 6)备注掉之后 ,即主函数是:
void main()
{
        U8 data dataWr[6]        = { 1,2,3,4,5,6};                //存到24C02的数据
        U8 data dataRd[6] = 0;                                        //从24c02读出来的数据存放处
        //   SendNByteData(dataWr, 0x00, 6);  
        ReceiveNByteDAta(0x00,dataRd,6);   
        while(1);       
}
神奇的一刻到了,,,,,,,,!!!!!!!!!!!!!!!!!!!!第二个函数,竟然可以完全执行完了,,,在问题一处出现的没有应答而卡住了的问题,竟然没有问题了,,,,,,,,!!!?????????,,,, proteus里的ic2 debuuger  调试结果见:见图三


(原文件名:图三三.jpg)
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。