打印
[STC单片机]

AT24C02读写问题

[复制链接]
5498|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xu0801hua|  楼主 | 2014-1-10 14:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
怎么对AT24C02好坏进行测试?
    是不是对0x00~0xff地址循环测试(for(dz=0;dz<=255;dz++))?????
    for(dz=0;dz<=255;dz++)
  {
   write_add(dz,0xAA);//写dz,0xaa数据
    delayms(1);    //延时1ms
   read_add(dz);    //读出dz的值
   //if(temp0==0xAA)
   a[4]=22;a[5]=22;a[6]=22;a[7]=22;//数码管显示————
   biaoz1=1;      //出标志1
   display();     //显示
  }

相关帖子

沙发
旭日东起| | 2014-1-10 14:22 | 只看该作者
delayms(1);    //延时1ms            /延时 加长到 10MS 左右为好,你可以这样子测试的

使用特权

评论回复
板凳
xu0801hua|  楼主 | 2014-1-10 14:24 | 只看该作者
旭日东起 发表于 2014-1-10 14:22
delayms(1);    //延时1ms            /延时 加长到 10MS 左右为好,你可以这样子测试的 ...

我写了10ms还是没反应?不知高手,看看我写的对吗?????

使用特权

评论回复
地板
旭日东起| | 2014-1-10 14:25 | 只看该作者
xu0801hua 发表于 2014-1-10 14:24
我写了10ms还是没反应?不知高手,看看我写的对吗?????

思路是对的,但读写函数有没有对,我就不知道了

使用特权

评论回复
5
xu0801hua|  楼主 | 2014-1-10 14:30 | 只看该作者
旭日东起 发表于 2014-1-10 14:25
思路是对的,但读写函数有没有对,我就不知道了

这是我写的AT24c02的读写程序:::(请高手看看)
//微秒级延时函数(晶振为11.0592MHz, 延时大概4~5微秒, 用来操作I2C总线用)
void delay()
{
    ;
    ;
}
//发送启动信号: scl为高电平期间, sda发生负跳变
void start()
{
    sda = 1;
    delay();
    scl = 1;
    delay();
    sda = 0;
    delay();
}

//发送停止信号: scl为高电平, sda发生正跳变
void stop()
{
    sda = 0;
    delay();
    scl = 1;
    delay();
    sda = 1;
    delay();
}

//应答信号: scl为高电平期间, sda被接受设备拉为低电平, 最后scl置0
void response()
{
    uchar i;

    scl = 1;
    delay();
    while((sda == 1) && (i < 250))
        i++;

    scl = 0;
    delay();
}

//总线初始化: 将总线拉高以释放总线
void init()
{
    sda = 1;
    delay();
    scl = 1;
    delay();
}

//写字节数据: 将8位数据通过左移到CY(进位),然后赋值给数据线SDA
//每发送一位,scl出现正跳变
//发送完数据后,需要将scl置0, sda置1
void write_byte(uchar dat)
{
    uchar i, temp;

    temp = dat;
    for (i = 0; i < 8; i++)
    {
        temp = temp << 1;
        scl = 0;
        delay();
        sda = CY;
        delay();
        scl = 1;
        delay();
    }
    scl = 0;
    delay();
    sda = 1;
    delay();
}

//读字节数据: 将数据一位一位从sda中获取, 每读取一位scl出现负跳变
//通过变量k将8位数据整合为1个字节数据
//读数据前, 先将scl置0, sda置1
uchar read_byte()
{
    uchar i, k;

    scl = 0;
    delay();
    sda = 1;
    delay();
    for (i = 0; i < 8; i++)
    {
        scl = 1;
        delay();
        k = (k << 1) | sda;
        scl = 0;
        delay();
    }

    return k;
}

//特定地址写数据
void write_add(uchar address, uchar dat)
{
    //发送启动信号
    start();
   
    //发送控制字
    //at24c02的芯片地址为1010,地址控制字格式为1010A2A1A0R/W
    //1010对应16进制为a, R/W为0(写操作), 合并起来就是0xa0
    write_byte(0xa0);
    //写入地址后,需要响应
    response();
    //送一个字节存储单元的子地址
    write_byte(address);
    //写入地址后,需要响应
    response();
    //发送8为数据位
    write_byte(dat);
    //响应信号
    response();
    //发送停止信号
    stop();
}

//特定地址读数据
uchar read_add(uchar address)
{
    uchar dat;

    //发送启动信号
    start();
    //发送写控制字
    //at24c02的芯片地址为1010,地址控制字格式为1010A2A1A0R/W
    //1010对应16进制为a, R/W为0(写操作), 合并起来就是0xa0
    write_byte(0xa0);
    //写入地址后,需要响应
    response();
    //送一个字节存储单元的子地址
    write_byte(address);
    //写入地址后,需要响应
    response();

    //发送启动信号
    start();
    //发送读控制字
    //at24c02的芯片地址为1010,地址控制字格式为1010A2A1A0R/W
    //1010对应16进制为a, R/W为1(读操作), 合并起来就是0xa1
    write_byte(0xa1);
    //读地址后,需要响应
    response();
    //读取数据赋值给变量dat
    dat = read_byte();
    //发送停止信号
    stop();

    return dat;
}

使用特权

评论回复
6
xu0801hua|  楼主 | 2014-1-10 14:31 | 只看该作者
旭日东起 发表于 2014-1-10 14:25
思路是对的,但读写函数有没有对,我就不知道了

这是我写的读写程序::::(请高手看看)
//微秒级延时函数(晶振为11.0592MHz, 延时大概4~5微秒, 用来操作I2C总线用)
void delay()
{
    ;
    ;
}
//发送启动信号: scl为高电平期间, sda发生负跳变
void start()
{
    sda = 1;
    delay();
    scl = 1;
    delay();
    sda = 0;
    delay();
}

//发送停止信号: scl为高电平, sda发生正跳变
void stop()
{
    sda = 0;
    delay();
    scl = 1;
    delay();
    sda = 1;
    delay();
}

//应答信号: scl为高电平期间, sda被接受设备拉为低电平, 最后scl置0
void response()
{
    uchar i;

    scl = 1;
    delay();
    while((sda == 1) && (i < 250))
        i++;

    scl = 0;
    delay();
}

//总线初始化: 将总线拉高以释放总线
void init()
{
    sda = 1;
    delay();
    scl = 1;
    delay();
}

//写字节数据: 将8位数据通过左移到CY(进位),然后赋值给数据线SDA
//每发送一位,scl出现正跳变
//发送完数据后,需要将scl置0, sda置1
void write_byte(uchar dat)
{
    uchar i, temp;

    temp = dat;
    for (i = 0; i < 8; i++)
    {
        temp = temp << 1;
        scl = 0;
        delay();
        sda = CY;
        delay();
        scl = 1;
        delay();
    }
    scl = 0;
    delay();
    sda = 1;
    delay();
}

//读字节数据: 将数据一位一位从sda中获取, 每读取一位scl出现负跳变
//通过变量k将8位数据整合为1个字节数据
//读数据前, 先将scl置0, sda置1
uchar read_byte()
{
    uchar i, k;

    scl = 0;
    delay();
    sda = 1;
    delay();
    for (i = 0; i < 8; i++)
    {
        scl = 1;
        delay();
        k = (k << 1) | sda;
        scl = 0;
        delay();
    }

    return k;
}

//特定地址写数据
void write_add(uchar address, uchar dat)
{
    //发送启动信号
    start();
   
    //发送控制字
    //at24c02的芯片地址为1010,地址控制字格式为1010A2A1A0R/W
    //1010对应16进制为a, R/W为0(写操作), 合并起来就是0xa0
    write_byte(0xa0);
    //写入地址后,需要响应
    response();
    //送一个字节存储单元的子地址
    write_byte(address);
    //写入地址后,需要响应
    response();
    //发送8为数据位
    write_byte(dat);
    //响应信号
    response();
    //发送停止信号
    stop();
}

//特定地址读数据
uchar read_add(uchar address)
{
    uchar dat;

    //发送启动信号
    start();
    //发送写控制字
    //at24c02的芯片地址为1010,地址控制字格式为1010A2A1A0R/W
    //1010对应16进制为a, R/W为0(写操作), 合并起来就是0xa0
    write_byte(0xa0);
    //写入地址后,需要响应
    response();
    //送一个字节存储单元的子地址
    write_byte(address);
    //写入地址后,需要响应
    response();

    //发送启动信号
    start();
    //发送读控制字
    //at24c02的芯片地址为1010,地址控制字格式为1010A2A1A0R/W
    //1010对应16进制为a, R/W为1(读操作), 合并起来就是0xa1
    write_byte(0xa1);
    //读地址后,需要响应
    response();
    //读取数据赋值给变量dat
    dat = read_byte();
    //发送停止信号
    stop();

    return dat;
}

使用特权

评论回复
7
ALISWANG| | 2014-1-12 19:14 | 只看该作者
我也搭车问下24C02的问题,我现在是存贮数据小与256时,掉电可以存,大与256就不能存进去了,请问是那里出问题。

使用特权

评论回复
8
ALISWANG| | 2014-1-12 19:17 | 只看该作者
LZ,你把delay改为100试下,写完后要delay时间长一点

使用特权

评论回复
9
ningling_21| | 2014-1-12 19:42 | 只看该作者
ALISWANG 发表于 2014-1-12 19:14
我也搭车问下24C02的问题,我现在是存贮数据小与256时,掉电可以存,大与256就不能存进去了,请问是那里出 ...

24c02最多能存多少呢?

使用特权

评论回复
10
ningling_21| | 2014-1-12 19:43 | 只看该作者
可以这样测试;
先写入已知的数据;
断电;
再读取数据,和之前的数据对比。

使用特权

评论回复
11
lirunze| | 2014-1-12 21:47 | 只看该作者
ningling_21 发表于 2014-1-12 19:42
24c02最多能存多少呢?

好像是按页存的啊,一页256啊

使用特权

评论回复
12
ayb_ice| | 2014-1-13 08:07 | 只看该作者
lirunze 发表于 2014-1-12 21:47
好像是按页存的啊,一页256啊

不是好象,根本就不是

使用特权

评论回复
13
ALISWANG| | 2014-1-13 08:11 | 只看该作者
ayb_ice 发表于 2014-1-13 08:07
不是好象,根本就不是

谢谢你,在你的另外一贴回复中找到答案了,要把数分解为2个8位的再存进去。

使用特权

评论回复
14
dota_yy| | 2014-1-13 10:42 | 只看该作者
延时好像有点问题,
发送数据的时候
要保证在SCL的高电平期间,SDA不能改变
数据建立也是有时间的
看下24C02的手册
只要时序对了
肯定是没问题的

使用特权

评论回复
15
无名芯片| | 2014-6-5 09:59 | 只看该作者
我也遇到了同样的问题   

使用特权

评论回复
16
coody| | 2014-6-5 12:01 | 只看该作者
I2C接口简单,只要时序对,跟用什么MCU都是没有关系的

使用特权

评论回复
17
beyond696| | 2014-6-5 13:21 | 只看该作者
无名芯片 发表于 2014-6-5 09:59
我也遇到了同样的问题

搞个纬图的Ginkgo USB-I2C适配器测试下

使用特权

评论回复
18
peter_wjp| | 2014-7-8 22:56 | 只看该作者
楼主 如果就连接一个EEPROM,在初始化的时候就不要考虑释放总线了,
IIC的协议初始化时候就让SDA=0;SCL=0; 还有就是最好是接上拉电阻,这样拉低的话,灌电流会很小。

读写时序里面,要保证每次函数执行完毕 SCL是0,这样才能方便后面任何操作。毕竟不管是启动 还是停止 还是应答 都是需要SCL在高电平时候有效的。平时SCL就拉低,这样才能防止数据不会错。

最好先把读写函数都单独调试 然后再连在一起单次调试。 还有就是 可以采取连续写入,然后再连续读出   写入的数据跟地址对应 比如说0x00写入0x00, 0x01--0x01然后读取时候每次读取完毕验证一下,在这中间不要发停止信号 利用SCL拉低来暂时停止数据读取,比较完毕后再继续读取。 如果读取过程中发现有问题 就直接跳出循环。

使用特权

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

本版积分规则

34

主题

81

帖子

1

粉丝