野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 26458|回复: 5

at24c1024

[复制链接]
发表于 2016-9-3 23:18:15 | 显示全部楼层 |阅读模式
at24c1024数据怎么写不进去?写的数据读出来都是0./*******************************************************************/
/* 函数功能:给AT24C1024写数据                                     */
/* 入口参数?StartAddr:起始地址,跨页写时,需要重新写入地址数据。  */
/*           *pData:把这个数组中的数据写入                         */
/*           nBytes:要写的数据字节个数                            */
/*******************************************************************/

void AT24C1024_Write(uint8_t *pData,uint32_t StartAddr, uint16_t nBytes)
{
         uint16_t i;
         uint8_t StartAddr_L, StartAddr_H, P0;
         
          while(nBytes != 0)                       // 所有数据发送完毕,退出循环
          {
                        StartAddr_L = StartAddr & 0x0000ff;     // 计算低位地址
                        StartAddr_H = (StartAddr >> 8) & 0x0ff; // 计算高位地址
                        P0 = (StartAddr / 0x10000) << 1;        // 计算第17位,即P0
       
                        /* 第0步:发停止信号,启动内部写操作 */
                        i2c_Stop();
                        for (i = 0; i < 100; i++)
                        {                               
                                /* 第1步:发起I2C总线启动信号 */
                                i2c_Start();
                               
                                /* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
                                i2c_SendByte(AT24C1024_Addr | P0 | I2C_WR);        /* 此处是写指令 */
                               
                                /* 第3步:发送一个时钟,判断器件是否正确应答 */
                                if (i2c_WaitAck() == 0)
                                {
                                        break;
                                }
                        }
                        if (i  == 1000)
                        {
                                goto cmd_fail;        /* EEPROM器件写超时 */
                        }
                       
                        i2c_SendByte(AT24C1024_Addr | P0 | I2C_WR);     // 带P0发送器件地址
                        if (i2c_WaitAck() != 0)
                        {
                                goto cmd_fail;        /* EEPROM器件无应答 */
                        }
                       
                        i2c_SendByte(StartAddr_H);                    // 发送高位地址
                        if (i2c_WaitAck() != 0)
                        {
                                goto cmd_fail;        /* EEPROM器件无应答 */
                        }               
                       
                        i2c_SendByte(StartAddr_L);                    // 发送低位地址
                        if (i2c_WaitAck() != 0)
                        {
                                goto cmd_fail;        /* EEPROM器件无应答 */
                        }       
                       
                        while(nBytes != 0)                      // 数据未发送完,循环
                        {
                                i2c_SendByte(*pData);
                                if (i2c_WaitAck() != 0)
                                {
                                        goto cmd_fail;        /* EEPROM器件无应答 */
                                }       
                       
                                pData++;
                                nBytes--;               
                                StartAddr++;
                                if((StartAddr & 0x00ff) == 0)           // 跨页,终止当前页循环,重新写入新地址
                                        break;
                         }       
                       
                }
                 i2c_Stop();
                        delay_ms(3);
                       
                 
cmd_fail:                       
                                        i2c_Stop();                              
                                        delay_ms(3);   
                                               
}


/************************************************************/
/* 函数功能:从AT24C1024中读数据                            */
/* 入口参数?StartAddr:起始地址,经测试跨页时地址会自动加1。*/
/*           *pData:读入的数据放到这个数组中                */
/*           nBytes:要写的数据字节个数                     */
/************************************************************/

void AT24C1024_Read(uint8_t *pData,uint32_t StartAddr, uint16_t nBytes)
{
        uint16_t i;
        uint8_t StartAddr_L, StartAddr_H, P0;
        StartAddr_L = StartAddr & 0x0000ff;     // 计算低位地址
        StartAddr_H = (StartAddr >> 8) & 0x0ff; // 计算高位地址
        P0 = (StartAddr / 0x10000) << 1;

        /* 采用串行EEPROM随即读取指令序列,连续读取若干字节 */
       
        /* 第1步:发起I2C总线启动信号 */
        i2c_Start();
       
        /* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
        i2c_SendByte(AT24C1024_Addr | P0 | I2C_WR);        /* 此处是写指令 */
       
        /* 第3步:发送ACK */
        if (i2c_WaitAck() != 0)
        {
                goto cmd_fail;        /* EEPROM器件无应答 */
        }

        /* 第4步:发送字节地址,24C02只有256字节,因此1个字节就够了,如果是24C04以上,那

么此处需要连发多个地址 */
        i2c_SendByte(StartAddr_H);
       
        /* 第5步:发送ACK */
        if (i2c_WaitAck() != 0)
        {
                goto cmd_fail;        /* EEPROM器件无应答 */
        }
       
       
                /* 第4步:发送字节地址,24C02只有256字节,因此1个字节就够了,如果是24C04

以上,那么此处需要连发多个地址 */
        i2c_SendByte(StartAddr_L);
       
        /* 第5步:发送ACK */
        if (i2c_WaitAck() != 0)
        {
                goto cmd_fail;        /* EEPROM器件无应答 */
        }
       
       
        /* 第6步:重新启动I2C总线。前面的代码的目的向EEPROM传送地址,下面开始读取数据 */
        i2c_Start();
       
        /* 第7步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
        i2c_SendByte(AT24C1024_Addr | P0 | I2C_RD);        /* 此处是读指令 */
       
        /* 第8步:发送ACK */
        if (i2c_WaitAck() != 0)
        {
                goto cmd_fail;        /* EEPROM器件无应答 */
        }       
       
        /* 第9步:循环读取数据 */
        for (i = 0; i < nBytes; i++)
        {
                pData = i2c_ReadByte();        /* 读1个字节 */
               
                /* 每读完1个字节后,需要发送Ack, 最后一个字节不需要Ack,发Nack */
                if (i != nBytes - 1)
                {
                        i2c_Ack();        /* 中间字节读完后,CPU产生ACK信号(驱动SDA = 0) */
                }
                else
                {
                        i2c_NAck();        /* 最后1个字节读完后,CPU产生NACK信号(驱动SDA = 1) */
                }
        }
       
cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
        /* 发送I2C总线停止信号 */
        i2c_Stop();
        i2c_Delay();
}


回复

使用道具 举报

发表于 2016-9-4 10:05:12 来自手机 | 显示全部楼层
帮顶,可以参考下霸道的视频教程的i2C章节
回复 支持 反对

使用道具 举报

发表于 2016-9-5 08:52:39 | 显示全部楼层
应该就只是地址的区别,没有其它了
回复 支持 反对

使用道具 举报

发表于 2021-1-9 23:23:22 | 显示全部楼层
楼主大哥,请问你解决了,我在写24C64的模拟i2c,也是读写不一致,能把你的程序分享一下吗
回复 支持 反对

使用道具 举报

发表于 2021-1-12 23:16:06 | 显示全部楼层
你看看发送地址,at24cxxx还有1024那?就用过256的。凭经验说下,既然是1024的话,那么应该是1024kb个bit,那么就是1024*1024 / 8 = 131,072个字节,已经超过short(uint16_t)65535了。如果一个地址装一个字节的话,也就是说你这个地址肯定超过short'了,你这个应该得发三次或四次地址(具体看手册)才行吧。建议先看看手册吧,有结果记得说下啊,学习下。
回复 支持 反对

使用道具 举报

发表于 2021-1-13 15:19:43 | 显示全部楼层
你写完数据之后,一定要延时几毫秒再去读数据,不然读出来都是0.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-23 18:43 , Processed in 0.029542 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表