AT25C02程序编写及疑问解析

I2C接口的EEPROM芯片有AT25C02,AT25C04,AT25C08,AT24C16等。

先来看看读写时序


void EEPROM_WriteChar(uint16_t addr, uint8_t dat)
{
    I2C_Start();
    I2C_WriteChar(0xA0);
    I2C_Ack();
    //I2C_WriteChar(addr>>8);
    //I2C_Ack();
    I2C_WriteChar(addr&0xff);
    I2C_Ack();
    I2C_WriteChar(dat);
    I2C_Ack();
    I2C_Stop();
}


int EEPROM_PageWrite(uint16_t addr, uint8_t *dat, uint8_t len)
{
    uint8_t i;
    uint8_t ack;;
    int ret;
    
    ack = 0;
    I2C_Start();
    I2C_WriteChar(0xA0);
    ack |= I2C_Ack();
    //I2C_WriteChar(addr>>8);
    //ack |= I2C_Ack();
    I2C_WriteChar(addr&0xff);
    ack |= I2C_Ack();
    for (i=0; i<len; i++)
    {
        I2C_WriteChar(*dat);
        dat++;
        ack |= I2C_Ack();
    }
    I2C_Stop();
    
    if (ack == 0)  ret = 0;
    else  ret = -1;
    return ret;
}


int EEPROM_WriteChars(uint16_t addr, uint8_t *dat, uint8_t len)
{
    uint8_t i;
    uint8_t page;
    uint8_t page_size;
    uint8_t offset;
    int ret;
    
    page_size = 16;
    page = len / page_size;
    for (i=0; i<page; i++)
    {
        offset = i * page_size;
        EEPROM_PageWrite(addr+offset, dat+offset, page_size);
    }
    page_size = len % page_size;
    if (page_size != 0)
    {
        offset = i * page_size;
        EEPROM_PageWrite(addr+offset, dat+offset, page_size);
    }
}


uint8_t EEPROM_ReadChar(uint16_t addr)
{
    uint8_t read_data;
    
    I2C_Start();
    I2C_WriteChar(0xA0);
    I2C_Ack();
    //I2C_WriteChar(addr>>8);
    //I2C_Ack();
    I2C_WriteChar(addr&0xff);
    I2C_Ack();
    I2C_Stop();
    
    I2C_Start();
    I2C_WriteChar(0xA1);
    I2C_Ack();
    read_data = I2C_ReadChar();
    I2C_NAck();
    I2C_Stop();
    
    return read_data;
}


int EEPROM_ReadChars(uint16_t addr, uint8_t *dat, uint8_t len)
{
    int ret = 0;
    uint8_t i;
    uint8_t ack;
    
    ack = 0;
    I2C_Start();
    I2C_WriteChar(0xA0);
    ack |= I2C_Ack();
    //I2C_WriteChar(addr>>8);
    //ack |= I2C_Ack();
    I2C_WriteChar(addr&0xff);
    ack |= I2C_Ack();
    I2C_Stop();
    
    I2C_Start();
    I2C_WriteChar(0xA1);
    ack |= I2C_Ack();
    for (i=0; i<len; i++)
    {
        dat[i] = I2C_ReadChar();
        I2C_SendAck();
    }
    ack |= I2C_NAck();
    I2C_Stop();
    
    if (ack == 0)  ret =0;
    else  ret = -1;
    return ret;
}


调试时去连续读取数据时,读取失败,原因是I2C_ReadChar()之后,需要主机发送ACK,而不是等待从机发送的ACK。修改之后,可以连续读取数据了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值