打印

at24c1024

[复制链接]
261|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
无幻|  楼主 | 2019-11-1 16:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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();
}

使用特权

评论回复

相关帖子

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

本版积分规则

431

主题

436

帖子

0

粉丝