OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 235|回复: 0

AT24C512 读取问题

[复制链接]

5

主题

8

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2026-2-9
在线时间
16 小时
发表于 7 天前 | 显示全部楼层 |阅读模式
1金钱
AT24C512 在硬件读取时即读取正常,但在块读取时加电后只能正确读取一次,以后只读取第一个字节,其他的都是0XFF

代码如下。

void I2C_Config()
{        RCC->APB2ENR|=1<<3;    //使能PORTB时钟       
          RCC->APB1ENR|=1<<21;   //使能I2C1时钟
        GPIOB->CRL&=0X00FFFFFF;
        GPIOB->CRL|=0XFF000000;//PB.5 推挽输出            
   GPIOB->ODR|=1<<6;      //PB.5 输出高
        I2C1->TRISE=0X25;
        I2C1->CR2=0X0024;
        I2C1->CCR=0XB4;
        I2C1->CR1=0X0401;
}


//***********************************************************************************************************************************************************************************
u8 AT24Cxxx_ReadOneByte(u16 ReadAddr)
{        u8 temp=0;                                                                                                                                                                      
        I2C1->CR1|=0X0100;                                                //起始信号                       
        while(!(I2C1->SR1&(1<<0)));                        //等待起始信号发送完成       
        if(EE_TYPE>AT24C16)
        {        I2C1->DR=(0XA0);           //发送写命令
                while(!(I2C1->SR1&(1<<1)));               
                I2C1->DR=(ReadAddr>>8);//发送高地址            
        }else
                I2C1->DR=0XA0+(ReadAddr/256<<1);
        while(!(I2C1->SR1&(1<<1)));                        //等待地址发送完成
        temp=I2C1->SR2;
        I2C1->DR=ReadAddr%256;
        while(!(I2C1->SR1&(1<<7)));                        //等待发送缓冲区空
        I2C1->CR1|=0X0100;
        while(!(I2C1->SR1&(1<<0)));                        //等待起始信号发送完成
        I2C1->DR=0XA1;
        while(!(I2C1->SR1&(1<<1)));                        //等待地址发送完成
        temp=I2C1->SR2;
        while(!(I2C1->SR1&(1<<6)));                         //等待收到数据
        temp=I2C1->DR;       
        I2C1->CR1&=~0X0400;                                                 //关闭应答
        I2C1->CR1|=0X0200;                                                 //产生停止信号
        return temp;
}

void AT24Cxxx_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{        u8 temp;                                                                                                                                                                          
        I2C1->CR1|=0X0100;                                                //起始信号                       
        while(!(I2C1->SR1&(1<<0)));                        //等待起始信号发送完成
        if(EE_TYPE>AT24C16)
        {        I2C1->DR=(0XA0);           //发送写命令
                while(!(I2C1->SR1&(1<<1)));               
                I2C1->DR=(WriteAddr>>8);//发送高地址            
        }else
                I2C1->DR=0XA0+((WriteAddr/256)<<1);
        while(!(I2C1->SR1&(1<<1)));                       
        temp=I2C1->SR2;
        I2C1->DR=WriteAddr%256;                                 //发送低地址
        while(!(I2C1->SR1&(1<<7)));       
        I2C1->DR=DataToWrite;                                         //发送字节       
        while(!(I2C1->SR1&(1<<7)));               
        I2C1->CR1|=0X0200;                                                 //产生停止信号
        delay_ms(10);                                         //EEPROM的写入速度比较慢,加入延迟
}





//***********************************************************************************************************************************************************************************
#if AT24Cx_Write
        void  AT24Cxxx_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
        {        while(NumToWrite--)
                {        AT24Cxxx_WriteOneByte(WriteAddr,*pBuffer);
                        WriteAddr++;
                        pBuffer++;
                }
        }
#else
        void AT24Cxxx_PWrite(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
        {        u8 temp;               
                I2C1->CR1|=0X0100;                                                //起始信号                       
                while(!(I2C1->SR1&(1<<0)));                        //等待起始信号发送完成
                if(EE_TYPE>AT24C16)
                {        I2C1->DR=(0XA0);           //发送写命令
                        while(!(I2C1->SR1&(1<<1)));               
                        I2C1->DR=(WriteAddr>>8);//发送高地址            
                }else
                        I2C1->DR=0XA0+((WriteAddr/256)<<1);
                while(!(I2C1->SR1&(1<<1)));                       
                temp=I2C1->SR2;
                I2C1->DR=WriteAddr%256;                                 //发送低地址
                while(!(I2C1->SR1&(1<<7)));       
                while(NumToWrite--)
                {        I2C1->DR=*pBuffer++;                                        
                        while(!(I2C1->SR1&(1<<7)));       
                }
                I2C1->CR1|=0X0200;                                                 //产生停止信号
                delay_ms(10);                                         //EEPROM的写入速度比较慢,加入延迟
        }

////***********************************************************************************************************************************************************************************
        void AT24Cxxx_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
        {        u8 i;
        w:        if (WriteAddr%AT24+NumToWrite<=AT24)  
                {        AT24Cxxx_PWrite(WriteAddr,pBuffer,NumToWrite);goto p;        }
                if (WriteAddr%AT24+NumToWrite>AT24)
                {        i=AT24-WriteAddr%AT24;
                        AT24Cxxx_PWrite(WriteAddr,pBuffer,i);
                        if (WriteAddr==0)
                        {        NumToWrite=NumToWrite-AT24;
                                WriteAddr+=AT24;
                                pBuffer+=AT24;
                        }else
                        {        NumToWrite=NumToWrite-i;
                                WriteAddr+=i;
                                pBuffer+=i;
                        }
                        goto w;
                }
                p:i++;
        }
#endif
//--------------------------------------------------------------------------------
#if AT24Cx_Read
        void AT24Cxxx_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
        {        while(NumToRead)
                {        *pBuffer++=AT24Cxxx_ReadOneByte(ReadAddr++);       
                        NumToRead--;
                }
        }
#else
        void AT24Cxxx_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
        {        u8 temp=0;                                                                                                                                                                      
                I2C1->CR1|=0X0100;                                                //起始信号                       
                while(!(I2C1->SR1&(1<<0)));                        //等待起始信号发送完成       
                if(EE_TYPE>AT24C16)
                {        I2C1->DR=(0XA0);           //发送写命令
                        while(!(I2C1->SR1&(1<<1)));               
                        I2C1->DR=(ReadAddr>>8);//发送高地址            
                }else
                        I2C1->DR=0XA0+(ReadAddr/256<<1);
                while(!(I2C1->SR1&(1<<1)));                        //等待地址发送完成
                temp=I2C1->SR2;
                I2C1->DR=ReadAddr%256;
                while(!(I2C1->SR1&(1<<7)));                        //等待发送缓冲区空       

                I2C1->CR1|=0X0100;                                                //起始信号
                while(!(I2C1->SR1&(1<<0)));                        //等待起始信号发送完成
                I2C1->DR=0XA1;
                while(!(I2C1->SR1&(1<<1)));                        //等待地址发送完成
                temp=I2C1->SR2;
                while(NumToRead--)
                {        while(!(I2C1->SR1&(1<<6)));                         //等待收到数据
                        temp=I2C1->SR2;
                        *pBuffer++=I2C1->DR;       
                       
                }
                I2C1->CR1&=~0X0400;                                                 //关闭应答
                I2C1->CR1|=0X0200;                                                 //产生停止信号
        }
#endif














回复

使用道具 举报

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

本版积分规则


关闭

原子哥极力推荐上一条 /1 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2026-3-10 20:12

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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