24c64驱动

/*

  • File : 24clxx.c
  • This file is part of eeprom driver for 24clxx,such as at24c02/at24c16.
  • COPYRIGHT © 2014 - 2016,
  • Change Logs:
  • Date Author Notes
  • Depend on:
  • i2c_bitops.c
  • Note:
  • 24c04 24c08 24c16 地址为8位,超过0xff地址后,注意页的选择读写
  • 24c32 及以上地址为16位
  • EEPROM 页读写需要作应答查询或作短暂延时以等待数据写入完成;FM24CLXX则不需要
    */

#define USE_24CLXX_EN 1
#define USE_24CLXX_DEBUG 0

#if USE_24CLXX_EN
#include “main.h”

//eeprom/fram 参数
#define EEPROM_TYPE 0 //0->EEPROM 1->FRAM
#define EEPROM_MODEL 16 //EEPROM 类型 24c16
#define EE24CLXX_SLAVE_ADDR 0x50 //注意读写位,实际地址为0x50
#define EE24CLXX_PageSize 16 //AT24C16每页有16个字节 24C02->8 24c64->32

static void I2C_24CLXXWaitStandby(u8 slave_addr);

//页写延时,FRAM不用
static void I2C_24CLXXWaitStandby(u8 slave_addr)
{
#if EEPROM_TYPE

#else
u16 i;
i = 0xFFFF;
while (i–);
#endif
}

//写多字节,需确保当前写地址+写入数据长度不能超过EEPROM的一页
static void i2c_24clxx_write( u16 WriteAddr, char* pBuffer,u16 NumByteToWrite)
{
struct st_i2c_msg ee24_msg[2];
u8 buf[2];
u8 slave_addr;

            //if(WriteAddr+NumByteToWrite > EE24CLXX_PageSize)
            //                return;
            if(EEPROM_MODEL > 16)
            {//大于2k字节时,地址为16位
                            slave_addr = EE24CLXX_SLAVE_ADDR;
                            buf[0] = (WriteAddr >>8)& 0xff;
                            buf[1] = WriteAddr & 0xff;
                            ee24_msg[0].size  = 2;
            }
            else
            {
                            slave_addr = EE24CLXX_SLAVE_ADDR | (WriteAddr>>8);
                            buf[0] = WriteAddr & 0xff;
                            ee24_msg[0].size  = 1;
            }
            ee24_msg[0].addr = slave_addr;
            ee24_msg[0].flags = ST_I2C_WR;
            ee24_msg[0].buff  = buf;
            ee24_msg[1].addr = slave_addr;
            ee24_msg[1].flags = ST_I2C_WR  | ST_I2C_NO_START;        
            ee24_msg[1].buff  = (u8*)pBuffer;
            ee24_msg[1].size  = NumByteToWrite;
            i2c_bitops_bus_xfer(&i2c1_dev,ee24_msg,2);

}

/*******************************************************
**
** 外部函数
**
*******************************************************/

//写一字节
char ee_24clxx_writebyte(u16 addr,u8 data)
{
struct st_i2c_msg ee24_msg[2];
u8 buf[3];
u8 slave_addr;

            if(EEPROM_MODEL > 16)
            {//大于2k字节时,地址为16位
                            slave_addr = EE24CLXX_SLAVE_ADDR;
                            buf[0] = (addr >>8)& 0xff;   //高位地址在前
                            buf[1] = addr & 0xff;
                            buf[2] = data;
                            ee24_msg[0].size  = 3;
            }
            else
            {
                            slave_addr = EE24CLXX_SLAVE_ADDR | (addr>>8);
                            buf[0] = addr & 0xff;
                            buf[1] = data;
                            ee24_msg[0].size  = 2;
            }
            ee24_msg[0].addr = slave_addr;
            ee24_msg[0].flags = ST_I2C_WR;
            ee24_msg[0].buff  = buf;
            i2c_bitops_bus_xfer(&i2c1_dev,ee24_msg,1);
            
            return 0;

}

//写多字节
//新的页写
char ee_24clxx_writebytes(u16 write_addr, char* pwrite_buff, u16 writebytes)
{
u8 write_len,page_offset;
u16 write_remain,write_current_addr;
char error = 0,*pbuff;

            pbuff                                        = pwrite_buff;                        //不要直接使用形参计算,特别是指针操作
            write_remain  = writebytes;
            write_current_addr = write_addr;
            while(write_remain > 0)
            {
                            page_offset = write_current_addr & 0x0f;                //write_current_addr%EE24CLXX_PageSize
                            write_len   = write_remain > (EE24CLXX_PageSize - page_offset) ? (EE24CLXX_PageSize - page_offset) : write_remain;
                            i2c_24clxx_write(write_current_addr,pbuff, write_len);
                            write_remain   = write_remain - write_len;
                            if(write_remain > 0)
                            {
                                            pbuff = pbuff + EE24CLXX_PageSize - page_offset;
                                            write_current_addr  =  write_current_addr + EE24CLXX_PageSize - page_offset;
                                            I2C_24CLXXWaitStandby(0);
                            }
            }
            I2C_24CLXXWaitStandby(0);
            {//校验数据
                            int i;
                            char checkdata;
                    
                            for(i = 0;i < writebytes;i++)
                            {
                                            ee_24clxx_readbytes(write_addr+i,&checkdata,1);        
                                            if(checkdata != pwrite_buff[i])
                                            {
                                                            error = 1;
                                                            break;
                                            }
                            }
            }
            return error;

}

//读多字节,连续读
void ee_24clxx_readbytes(u16 ReadAddr, char* pBuffer, u16 NumByteToRead)
{
struct st_i2c_msg ee24_msg[2];
u8 buf[2];
u8 slave_addr;

            if(EEPROM_MODEL > 16)
            {//大于2k字节时,地址为16位
                            slave_addr = EE24CLXX_SLAVE_ADDR;
                            buf[0] = (ReadAddr >>8)& 0xff;
                            buf[1] = ReadAddr & 0xff;
                            ee24_msg[0].size  = 2;
            }
            else
            {
                            slave_addr = EE24CLXX_SLAVE_ADDR | (ReadAddr>>8);
                            buf[0] = ReadAddr & 0xff;
                            ee24_msg[0].size  = 1;
            }
            ee24_msg[0].buff  = buf;
            ee24_msg[0].addr  = slave_addr;
            ee24_msg[0].flags = ST_I2C_WR;
            ee24_msg[1].addr  = slave_addr;
            ee24_msg[1].flags = ST_I2C_RD;
            ee24_msg[1].buff  = (u8*)pBuffer;
            ee24_msg[1].size  = NumByteToRead;
            i2c_bitops_bus_xfer(&i2c1_dev,ee24_msg,2);

}

//擦除EEPROM
char ee_24clxx_erasebytes(u16 WriteAddr, char Erasedata, u16 NumByteToErase)
{
char error = 0;
u16 i;
//char *buff;
char buff[2048]; //测试用,实际使用需动态分配内存

            //buff = (char*)malloc(2048);
            for(i = 0;i < NumByteToErase;i++)
            {
                            buff[i] = Erasedata;
            }
            error = ee_24clxx_writebytes(WriteAddr,buff,NumByteToErase);                                
            //free(buff);
            return error;

}

//eeprom test
#if USE_24CLXX_DEBUG
#define WRSIZE 2048
#define EEP_Firstpage 0
char I2c_Buf_Write[WRSIZE];
char I2c_Buf_Read[WRSIZE];
void EE24CLXX_Test(void)
{
u16 i,error = 0;

            for ( i=0; i<WRSIZE; i++ ) //填充缓冲
            {   
                            I2c_Buf_Write[i] = i;   
            }
            ee_24clxx_readbytes(EEP_Firstpage, I2c_Buf_Read, WRSIZE); 
            ee_24clxx_readbytes(EEP_Firstpage, I2c_Buf_Read, WRSIZE);
            error = ee_24clxx_writebytes(EEP_Firstpage, I2c_Buf_Write, WRSIZE);         
            Delayms(5);
            ee_24clxx_readbytes(EEP_Firstpage, I2c_Buf_Read, WRSIZE); 

            for ( i=0; i<WRSIZE; i++ ) //填充缓冲 
                            I2c_Buf_Write[i] = 0;   
            error = ee_24clxx_writebytes(EEP_Firstpage, I2c_Buf_Write, WRSIZE);
            Delayms(5);                
            ee_24clxx_readbytes(EEP_Firstpage, I2c_Buf_Read,WRSIZE); 
            //while(error);

}
#endif

#endif

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值