I2C with AT24C02

Dependencies:   mbed

Fork of I2C_on_mbed_AT24cxxx by RedBearLab

main.cpp

Committer:
makeworks
Date:
2017-10-09
Revision:
3:488563715282
Parent:
0:a9d57902bf67

File content as of revision 3:488563715282:


#include "mbed.h"

#define DEV_ADDR                0xA0
#define I2C_PageSize            8            /* AT24C02每页有8个字节 */

I2C     i2c(I2C_SDA, I2C_SCL);
Serial  pc(USBTX, USBRX);

/**********************************************************************
* @brief            :  Write data to AT24C02
*
* @param[in] addr   : The address of stored
* @param[in] *pbuf  : The pointer of data
* @param[in] length : The length of data
*
* @return none
24C02一页的大小是8,所以写入的时候每到8的倍数的时候要等5ms换页
**********************************************************************/
void AT24C02_WriteBytes(uint8_t addr, const uint8_t *const pbuf, uint16_t length)
{
    char *_pbuf = (char *)pbuf;
    uint8_t NumOfFirstPageAvailable = I2C_PageSize - addr % I2C_PageSize;
    //页是绝对的,按整页大小排列,不是从开始写入的地址开始算。
    //页写与字节写的区别就是,页写可以一次写多个数据,而字节写只能一次写一个数据。
    //但由于AT24C02A的一页才8个字节,所以页写也最多写8个数据,而且只能在该页内写,不会发生一次页写同时写两页的情况。
    if (length <= NumOfFirstPageAvailable)
    {
        char buf[length+1];
        buf[0] = (char)(addr);
        memcpy(&buf[1], _pbuf, length);
        i2c.write(DEV_ADDR, buf, length+1, false);
        wait_ms(5);
    }
    else
    {
        char buf[NumOfFirstPageAvailable+1];
        buf[0] = (char)(addr);
        memcpy(&buf[1], _pbuf, NumOfFirstPageAvailable);
        i2c.write(DEV_ADDR, buf, NumOfFirstPageAvailable+1, false);
        wait_ms(5);
        
        uint16_t NumOfRemainPages = (length - NumOfFirstPageAvailable) / I2C_PageSize;
        uint8_t NumOfRemainBytes = (length - NumOfFirstPageAvailable) % I2C_PageSize;

        addr +=  NumOfFirstPageAvailable;//修改寄存器写入地址
        _pbuf += NumOfFirstPageAvailable;//修改buf地址
        while (NumOfRemainPages--)//按page写入
        {
            //一次可以写入8个字节的数据
            char buf[I2C_PageSize+1];
            buf[0] = (char)(addr);
            memcpy(&buf[1], _pbuf, I2C_PageSize);
            i2c.write(DEV_ADDR, buf, I2C_PageSize+1, false);
            wait_ms(5);
            addr +=  I2C_PageSize;//修改寄存器写入地址
            _pbuf += I2C_PageSize;//修改buf地址
        }
        if (NumOfRemainBytes != 0)//将剩下的不足一个page的写入
        {
            char buf[NumOfRemainBytes+1];
            buf[0] = (char)(addr);
            memcpy(&buf[1], _pbuf, NumOfRemainBytes);
            i2c.write(DEV_ADDR, buf, NumOfRemainBytes+1, false);
            wait_ms(5);
        }
    }
}

/**********************************************************************
* @brief            :  Read data from AT24C02
*
* @param[in] addr   : The address of read in AT24C02
* @param[out] *pbuf : The pointer of buffer
* @param[in] length : The length of data
*
* @return none
读取数据可以一直读到最后一个地址.序列读没有一页8个字节的限制
读没有页的问题,可以从任意地址开始读取任意大小数据,只是超过整个存储器容量时地址才回卷。
**********************************************************************/
void AT24C02_ReadBytes(uint8_t addr, uint8_t *const pbuf, uint16_t length)
{
    uint8_t *_pbuf = (uint8_t *)pbuf;
    char buf[1];
    buf[0] = (char)(addr);
    i2c.write(DEV_ADDR, buf, 1, false);
    i2c.read(DEV_ADDR, (char *)_pbuf, length, false);
}


uint8_t w_buf[]= "Abcdefghijklmnopqrstuvwxyz1234567890";
uint8_t r_buf[100];


int main(void)
{
    uint8_t index;
    int len = sizeof(w_buf) - 1;
    pc.printf("len = %d\r\n", len);
    
    pc.baud(9600);
    pc.printf("IIC Demo Start \r\n");

    while(1) {
        wait(2);
        AT24C02_WriteBytes(0, w_buf, len);
        wait(0.5);
        AT24C02_ReadBytes(0, r_buf, len);
        for(index=0; index<len; index++)
            pc.printf("%c", r_buf[index]);

        pc.printf("\r\n");
    }
}