24c02 的I2C协议问题

[复制链接]
4207|10
 楼主| zaq9999 发表于 2008-8-6 14:18 | 显示全部楼层 |阅读模式
下面是24C02的子程序

DelayMs(1); 大约是50uS延时
调用方式是
addr2=readByteC;                
ReadI2C(addr2,0x00,3);               
a=readByteC[0];
b=readByteC[1];
c=readByteC[2];

我读取的时候老出错换了个24C02却一点问题都没有
但是读取出错的24c02,拿到烧写器上读取 却一点问题都没。

void Start()
{
    SDA=1;
    DelayMs(1);
    SCL=1;
    DelayMs(1);
    SDA=0;
    DelayMs(1);
    SCL=0;
    DelayMs(1);
}
//终止信号函数
void Stop()
{
    SCL=0;
    DelayMs(1);
    SDA=0;
    DelayMs(1);
    SCL=1;
    DelayMs(1);
    SDA=1;
    DelayMs(1);
}
//发送应答位函数
void Ack()
{
    SDA=0;
    DelayMs(1);
    SCL=1;
    DelayMs(1);
    SCL=0;
    DelayMs(1);
    SDA=1;
    DelayMs(1);
}
//发送非应答位函数
void NoAck()
{
    SDA=1;
    DelayMs(1);
    SCL=1;
    DelayMs(1);
    SCL=0;
    DelayMs(1);
}
//应答位检查函数
bit TestAck()
{
    bit ErrorBit;
    SDA=1;
    DelayMs(1);
    SCL=1;
    DelayMs(1);
    ErrorBit=SDA;                            //读入数据线上的应答状态
    DelayMs(1);
    SCL=0;
    DelayMs(1);
    return(ErrorBit);                        //返回应答状态,0为正常应答信号,1为非应答信号
}
//写一个字节数据函数
bit Write8Bit(unsigned char input)
{                                            //input为待发送的数据
    unsigned char temp;
    for(temp=8;temp!=0;temp--)                //循环移位,逐位发送数据
    {
        SDA=(bit)(input&0x80);                //取数据的最高位
        DelayMs(1);
        SCL=1;
        DelayMs(1);
        SCL=0;
        DelayMs(1);
        input=input<<1;                        //左移一位
    }
    return 1;
}
//写n个字节数据函数
void WriteI2C(unsigned char *Wdata,unsigned char RomAddress,unsigned char number)
{
    Start();                                //启动
    Write8Bit(WriteDeviceAddress);            //写写器件的寻址地址
    TestAck();                                //应答检查
    Write8Bit(RomAddress);                    //写入I2C器件内部的数据存储首地址
    TestAck();                                //应答检查
    for(;number!=0;number--)                //循环,逐个字节发送
    {
        Write8Bit(*Wdata);                    //写一个字节
        TestAck();                            //应答检查
        Wdata++;                            //指针增加,指向下一个数据
    }
    Stop();                                    //停止
    DelayMs(10);
}
//读一个字节数据函数
unsigned char Read8Bit()
{
    unsigned char temp,rbyte=0;
    for(temp=8;temp!=0;temp--)                //循环,逐位读入字节数据
    {
        SCL=1;
        DelayMs(1);
        rbyte=rbyte<<1;                        //左移一位
        DelayMs(1);
        rbyte=rbyte|((unsigned char)(SDA));    //数据线SDA上的数据存入rbyte的最低位
        SCL=0;
        DelayMs(1);
    }
    return(rbyte);                            //返回读入的字节数据
}
//读n个字节数据函数
void ReadI2C(unsigned char *RamAddress,unsigned char RomAddress,unsigned char bytes)
{
    Start();                                //启动
    Write8Bit(WriteDeviceAddress);            //写写器件的寻址地址
    TestAck();                                //应答检查
    Write8Bit(RomAddress);                    //写I2C器件内部数据的读取首地址
    TestAck();                                //应答检查
    Start();                                //重新启动
    Write8Bit(ReadDviceAddress);            //写读器件的寻址地址
    TestAck();                                //应答检查
    while(bytes!=1)                            //循环读入字节数据
    {
        *RamAddress=Read8Bit();                //读入一个字节
        Ack();                                //应答
        RamAddress++;                        //地址指针递增
        bytes--;                            //待读入数据个数递减
    }
    *RamAddress=Read8Bit();                    //读入最后一个字节数据
    NoAck();                                //非应答
    Stop();                                    //停止
}
 楼主| zaq9999 发表于 2008-8-6 15:30 | 显示全部楼层

没人回复么

没人回复么
ayb_ice 发表于 2008-8-6 16:34 | 显示全部楼层

如果沒有應答應該stop才對


Start();                                //启动
    Write8Bit(WriteDeviceAddress);            //写写器件的寻址地址
    TestAck();                                //应答检查
    Write8Bit(RomAddress);                    //写I2C器件内部数据的读取首地址
    TestAck();  // ????
Start(); 
.......
 楼主| zaq9999 发表于 2008-8-6 18:05 | 显示全部楼层

我补充一下

那个24c02有个奇怪的问题
就是第一次读取正确,后面无论读取多少次都是正确的,如果第一次读取错误,后面无论读取多少次都是错误的,而且错误的值都是一样的。
用烧写器进行读取 没有发生过读取错误
lyjian 发表于 2008-8-6 19:09 | 显示全部楼层

有点疑问

TestAck()后既然没任何动作,你做这个TestAck()是否多余的?   
 楼主| zaq9999 发表于 2008-8-6 23:49 | 显示全部楼层

TestAck

TestAck(); 在这里是多余的。但应该不影响时序的
ayb_ice 发表于 2008-8-7 08:17 | 显示全部楼层

如果接收者沒有收到數據會怎樣

你的程序始終認為是正確的,這當然可能產生問題了
dream2010 发表于 2008-8-7 14:22 | 显示全部楼层

程序  读数据出现了问题
 楼主| zaq9999 发表于 2008-8-7 16:36 | 显示全部楼层

问题已解决

已经查出原因 是因为继电器吸合,导致开关电源电压回落。去掉大滤波电容就好了
ayb_ice 发表于 2008-8-8 08:22 | 显示全部楼层

问题已解决不能說明程序沒有問題

yangwh0729 发表于 2009-11-5 21:56 | 显示全部楼层
好东西
本文来自: 电子工程师之家http://www.eehome.cn
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

57

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部