打印

24c02 的I2C协议问题

[复制链接]
3227|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有个奇怪的问题
就是第一次读取正确,后面无论读取多少次都是正确的,如果第一次读取错误,后面无论读取多少次都是错误的,而且错误的值都是一样的。
用烧写器进行读取 没有发生过读取错误

使用特权

评论回复
5
lyjian| | 2008-8-6 19:09 | 只看该作者

有点疑问

TestAck()后既然没任何动作,你做这个TestAck()是否多余的?   

使用特权

评论回复
6
zaq9999|  楼主 | 2008-8-6 23:49 | 只看该作者

TestAck

TestAck(); 在这里是多余的。但应该不影响时序的

使用特权

评论回复
7
ayb_ice| | 2008-8-7 08:17 | 只看该作者

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

你的程序始終認為是正確的,這當然可能產生問題了

使用特权

评论回复
8
dream2010| | 2008-8-7 14:22 | 只看该作者

程序  读数据出现了问题

使用特权

评论回复
9
zaq9999|  楼主 | 2008-8-7 16:36 | 只看该作者

问题已解决

已经查出原因 是因为继电器吸合,导致开关电源电压回落。去掉大滤波电容就好了

使用特权

评论回复
10
ayb_ice| | 2008-8-8 08:22 | 只看该作者

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

使用特权

评论回复
11
yangwh0729| | 2009-11-5 21:56 | 只看该作者
好东西
本文来自: 电子工程师之家http://www.eehome.cn

使用特权

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

本版积分规则

12

主题

57

帖子

0

粉丝