maomaomao007 发表于 2011-11-8 10:56:10

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

昨天学习I2C总线读写24C02,实物上总有问题,所以搬到了PROTEUS上来,用I2C DEBUGGER调试了下,发现了一个很奇怪的问题,上网搜了下,说这个的问题很少.所以贴出来,请各位大侠指导.
问题是这样的,我写了I2C的协议的一些函数,然后向24C02写一组数据,然后再把刚才写进去的数据读出来,以检测我写的函数的正确性.
源程序如下:
void main()
{
        U8 data dataWr        = { 1,2,3,4,5,6};                //存到24C02的数据
        U8 data dataRd = 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原理图见图一,
http://cache.amobbs.com/bbs_upload782111/files_47/ourdev_692958EA7LED.jpg
(原文件名:图片一1.jpg)


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

http://cache.amobbs.com/bbs_upload782111/files_47/ourdev_692959Y1O564.jpg
(原文件名:图二二.jpg)

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

http://cache.amobbs.com/bbs_upload782111/files_47/ourdev_692960J659JQ.jpg
(原文件名:图三三.jpg)

maomaomao007 发表于 2011-11-8 21:49:01

没人顶,,,,自己来一个./emotion/em024.gif

maomaomao007 发表于 2011-11-8 22:48:31

啊哈,,,,原来我忽略了写周期,,,,,呜呼呜呼,,,,,搞了我半天,,,,,,,,

yuando 发表于 2011-11-9 12:35:19

笑而不语。。。。

youthdou 发表于 2012-4-5 17:00:58

写周期是不是等待24c02内部将数据存入指定地址。我的写周期设为for(10000)延迟,还有没有反应。。。。。。

youthdou 发表于 2012-4-5 17:15:12

youthdou 发表于 2012-4-5 17:00 static/image/common/back.gif
写周期是不是等待24c02内部将数据存入指定地址。我的写周期设为for(10000)延迟,还有没有反应。。。。。。 ...

代码敲错了,导致没延迟。。。。。。。
页: [1]
查看完整版本: proteus的I2C总线读写调试 24c02 EEPRAM I2C总线一个神奇的问题