#include "AT24Cxx.h"
/**********************************************************************/
// 功能描述: 初始化EEPROM(定义时钟,数据对应的端口及PIN脚,和操作速度)
// 输入参数:无
// 输出参数:无
// 返 回 值:无
// 编写时间:2014.11.26
// 作 者:胡安勤
// 修改记录:
/**********************************************************************/
void AT24CxxInit(const IIC_PIN *PIN)
{
IIC_Init(PIN);
// GPIO_PortClock(PIN.WP.port,true);
// GPIO_PinConfigure(PIN.WP.port,PIN.WP.num,GPIO_PIN_OUT_MODE,IIC_IO_SPEED);
// GPIO_PinWrite(PIN.WP.port,PIN.WP.num,AT24Cxx_WRITE_DISABLE); //写保护使能
}
/**********************************************************************/
// 功能描述: EEPROM单字节写操作
// 输入参数:addr:数据存储地址 ch:待写入数据
// 输出参数:无
// 返 回 值:无
// 编写时间:2014.11.26
// 作 者:胡安勤
// 修改记录:
/**********************************************************************/
IIC_STATUS AT24CxxWriteByte(const IIC_PIN *PIN, uint16_t addr, uint8_t ch)
{
IIC_STATUS status;
IIC_Start(PIN);
IIC_WriteByte(PIN, PIN->ADDR);
status = IIC_Wait_ACK(PIN);
#if ( ADDR_LENGTH == 2) //地址是否超过8位,越过,加入高位地址写操作
IIC_WriteByte(PIN, (uint8_t)((addr >> 8) & 0xFF)); //超过,写高位地址
status |= IIC_Wait_ACK(PIN);
#endif
IIC_WriteByte(PIN, (uint8_t)(addr & 0xFF)); //低位地址写入
status |= IIC_Wait_ACK(PIN);
IIC_WriteByte(PIN, ch); //数据写入
status |= IIC_Wait_ACK(PIN);
IIC_Stop(PIN); //停止
if(status)
{
return(IIC_WRITE_ERR);
}
else
{
return(IIC_OK);
}
}
/**********************************************************************/
// 功能描述: EEPROM多字节写操作
// 输入参数:addr:数据存储地址 *str:待写入数据串首指针 len:写入数据长度
// 输出参数:无
// 返 回 值:无
// 编写时间:2014.11.26
// 作 者:胡安勤
// 修改记录:
/**********************************************************************/
IIC_STATUS AT24CxxWriteStr(const IIC_PIN *PIN, uint16_t addr, uint8_t *str,
uint16_t len)
{
uint16_t i;
IIC_STATUS status;
//GPIO_PinWrite(PIN.WP.port,PIN.WP.num,AT24Cxx_WRITE_ENABLE);
IIC_Start(PIN);
IIC_WriteByte(PIN, PIN->ADDR);
status = IIC_Wait_ACK(PIN);
#if ( ADDR_LENGTH == 2)
IIC_WriteByte(PIN, (uint8_t)((addr >> 8) & 0xFF));
status |= IIC_Wait_ACK(PIN);
#endif
IIC_WriteByte(PIN, (uint8_t)(addr & 0xFF));
status |= IIC_Wait_ACK(PIN);
for(i = 0; i < len; i++)
{
if (((addr + i) % PAGE_LENGTH == 0) && (i > 0))
{
//判断是地址是否到达分页,是则完成页写。启动新页写操作
IIC_Stop(PIN);
//status |= IIC_Wait_ACK(PIN);
osDelay(10); //两个写操作之间,(参见芯片手册,最小值为5ms)
IIC_Start(PIN);
IIC_WriteByte(PIN, PIN->ADDR);
status |= IIC_Wait_ACK(PIN);
#if ( ADDR_LENGTH == 2)
IIC_WriteByte(PIN, (uint8_t)(((addr + i) >> 8) & 0xFF));
status |= IIC_Wait_ACK(PIN);
#endif
IIC_WriteByte(PIN, (uint8_t)((addr + i) & 0xFF));
status |= IIC_Wait_ACK(PIN);
}
IIC_WriteByte(PIN, *str++);
status |= IIC_Wait_ACK(PIN);
}
IIC_Stop(PIN);
//GPIO_PinWrite(PIN.WP.port,PIN.WP.num,AT24Cxx_WRITE_DISABLE);
osDelay(10);
if(status)
{
return (IIC_WRITE_ERR);
}
else
{
return (IIC_OK);
}
}
/**********************************************************************/
// 功能描述: EEPROM单字节读操作
// 输入参数:addr:数据存储地址
// 输出参数:无
// 返 回 值:读取到的数据
// 编写时间:2014.11.26
// 作 者:胡安勤
// 修改记录:
/**********************************************************************/
IIC_STATUS AT24CxxReadByte(const IIC_PIN *PIN, uint16_t addr, uint8_t *data)
{
uint8_t ch;
IIC_STATUS status;
IIC_Start(PIN);
IIC_WriteByte(PIN, PIN->ADDR);
status = IIC_Wait_ACK(PIN);
#if ( ADDR_LENGTH == 2)
IIC_WriteByte(PIN, (uint8_t)((addr >> 8) & 0xFF));
status |= IIC_Wait_ACK(PIN);
#endif
IIC_WriteByte(PIN, (uint8_t)(addr & 0xFF));
status |= IIC_Wait_ACK(PIN);
IIC_Start(PIN);
IIC_WriteByte(PIN, PIN->ADDR | 0x01);
status |= IIC_Wait_ACK(PIN);
IIC_ReadByte(PIN, &ch);
IIC_NACK(PIN);
IIC_Stop(PIN);
*data = ch;
if(status)
{
return (IIC_READ_ERR);
}
else
{
return (IIC_OK);
}
}
/**********************************************************************/
// 功能描述: EEPROM多字节读操作
// 输入参数:addr:数据存储地址 len:读取长度
// 输出参数:*str:存储缓冲区首指针
// 返 回 值:读取到的数据
// 编写时间:2014.11.26
// 作 者:胡安勤
// 修改记录:
/**********************************************************************/
IIC_STATUS AT24CxxReadStr(const IIC_PIN *PIN, uint16_t addr, uint8_t *str, uint16_t len)
{
uint16_t i;
IIC_STATUS status;
IIC_Start(PIN);
IIC_WriteByte(PIN, PIN->ADDR);
status = IIC_Wait_ACK(PIN);
#if ( ADDR_LENGTH == 2)
IIC_WriteByte(PIN, (uint8_t)((addr >> 8) & 0xFF));
status |= IIC_Wait_ACK(PIN);
#endif
IIC_WriteByte(PIN, (uint8_t)(addr & 0xFF));
status |= IIC_Wait_ACK(PIN);
IIC_Start(PIN);
IIC_WriteByte(PIN, PIN->ADDR | 0x01);
status |= IIC_Wait_ACK(PIN);
for(i = 0; i < len; i++)
{
if(i != 0 )
{
IIC_ACK(PIN);
}
IIC_ReadByte(PIN, str++);
}
IIC_NACK(PIN);
IIC_Stop(PIN);
if(status)
{
return (IIC_READ_ERR);
}
else
{
return (IIC_OK);
}
}
#ifndef _AT24CXX_HEAD_
#define _AT24CXX_HEAD_
#include "main.h"
#include "stdio.h"
#include "stdint.h"
#include "hal_iic.h"
#include "cmsis_os.h" //FreeRTOS系统中调用osDelay()
#define PAGE_LENGTH 64 //C01,C02为8字节,C04及以上为16字节,C64 32
#define ADDR_LENGTH 2 //地址长度C01,C02为1个字节,C04及以上为2字节
#define AT24Cxx_ADDR 0xA0 //定义器件地址
#define AT24Cxx_WRITE_ENABLE 0x00 //使能数据写入
#define AT24Cxx_WRITE_DISABLE 0x01 //禁止数所写入
void AT24CxxInit(const IIC_PIN *PIN);
IIC_STATUS AT24CxxWriteByte(const IIC_PIN *PIN, uint16_t addr, uint8_t ch);
IIC_STATUS AT24CxxReadByte(const IIC_PIN *PIN, uint16_t addr, uint8_t *data);
IIC_STATUS AT24CxxWriteStr(const IIC_PIN *PIN, uint16_t addr, uint8_t *str, uint16_t len);
IIC_STATUS AT24CxxReadStr(const IIC_PIN *PIN, uint16_t addr, uint8_t *str, uint16_t len);
#endif
24C02中文(商家版).pdf