STM32 (基于HAL库) 硬件IIC任意地址读写任意字节—-AT24CXX芯片
STM32 (基于HAL库) 硬件IIC任意地址读写任意字节—-AT24CXX芯片
EEPROM芯片读写程序相关索引
1.AT24C04、AT24C08、AT24C16系列EEPROM芯片单片机读写驱动程序
2.STM32 (基于HAL库) 硬件IIC读写任意AT24CXX芯片
一、概述
转了一圈,发现有关STM32的iic的硬件是使用比较少,基于HAL库的就更少,传统的,大家都是采用软件模拟的。由于iic的协议相对复杂,同时灵活,尤其是不同的设备的I2C通信组合变化也不同,使用灵活的软件模拟也是可以理解的,在加上I2C的设备读写速度都比较低,硬件读写的优势就更无法体现,哪怕硬件I2C可以开启DMA,甚至在随机的读取少量字节的情况下。开启DMA反而效果更差。自然而然的硬件I2C就无人问津了。只是最近在学习HAL库的开发,本想着学习的态度,加上开发版上自带AT24C04的EEPROM芯片,以及引脚以链接硬件的I2C的引脚,就学习一下使用硬件I2C,在此非常感谢,“相关索引”的两位作者,通过上面的两篇文章,参考及学习才有我的AT24CXX芯片任意地址读写任意字节的代码。
二、代码分享
代码逻辑很简单,通读一遍代码基本解可以理解了,加上代码的注释,基本就可以明白了。在这我就不班门弄斧多加解释了!唯一需要说明的是写操作要用HAL库的阻塞模式下的I2C的硬件库函数(HAL_I2C_Mem_Write ),而读操作要用非阻塞模式的库函数(HAL_I2C_Master_Receive),不然硬件的I2C对 EEPROM芯片读写格式不符合芯片规定格式,无法正常读取,这里与“嵌入式设计开发er”作者的代码有点出入。理论上,分享的代码适用于AT24C02、AT24C04、AT24C08、AT24C16系列EEPROM芯片,实际验证于AT24C04芯片。至于更高容量的待验证,或者感兴趣的朋友可以自行验证,有问题可以邮件联系我!联系邮箱为:tcxfjt@126.com
24CXX.h文件代码如下:
#ifndef AT24CXX_H__
#define AT24CXX_H__
/*****************************************
本驱动文件仅适配HAL库版本
作者:痕迹(Hamaliel)
******************************************/
#include "stm32f1xx_hal.h" //链接HAL库
#include "./SYSTEM/sys/sys.h"
/* Exported constants (常量) --------------------------------------------------------*/
/* Exported macro (宏) --------------------------------------------------------------*/
#define READ_CMD 1
#define WRITE_CMD 0
#define USE_HARDWARE_IIC 1
#define x24C04//器件名称,x24C04、x24C08或x24C16
#define DEV_ADDR 0xA0 //设备硬件地址
#ifdef x24C04
#define PAGE_NUM 32 //页数
#define PAGE_SIZE 16 //页面大小(字节)
#define CAPACITY_SIZE (PAGE_NUM * PAGE_SIZE) //总容量(字节)
#define ADDR_BYTE_NUM 1 //地址字节个数
#endif
#ifdef x24C08
#define PAGE_NUM 64 //页数
#define PAGE_SIZE 16 //页面大小(字节)
#define CAPACITY_SIZE (PAGE_NUM * PAGE_SIZE) //总容量(字节)
#define ADDR_BYTE_NUM 1 //地址字节个数
#endif
#ifdef x24C16
#define PAGE_NUM 128 //页数
#define PAGE_SIZE 16 //页面大小(字节)
#define CAPACITY_SIZE (PAGE_NUM * PAGE_SIZE) //总容量(字节)
#define ADDR_BYTE_NUM 1 //地址字节个数
#endif
#define AT24C01 127
#define AT24C02 255
#define AT24C04 511
#define AT24C08 1023
#define AT24C16 2047
#define AT24C32 4095
#define AT24C64 8191
#define AT24C128 16383
#define AT24C256 32767
//我使用的是AT24C04,容量4kbit(512byte)地址范围0~511
/* I2C1 引脚 定义 */
#define I2C1_SCL_GPIO_PORT GPIOB
#define I2C1_SCL_GPIO_PIN GPIO_PIN_6
#define I2C1_SCL_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0) /* PA口时钟使能 */
#define I2C1_SDA_GPIO_PORT GPIOB
#define I2C1_SDA_GPIO_PIN GPIO_PIN_7
#define I2C1_SDA_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0) /* PA口时钟使能 */
/* I2C1 相关定义 */
#define I2C1_I2C I2C1
#define I2C1_I2C_CLK_ENABLE() do{ __HAL_RCC_I2C1_CLK_ENABLE(); }while(0) /* I2C1时钟使能 */
#define I2C1_I2C_CLK_DISABLE() do{ __HAL_RCC_I2C1_CLK_DISABLE(); }while(0) /* I2C1时钟失能 */
/* Exported variables (变量)---------------------------------------------------------*/
/* Exported functions (函数) ------------------------------------------------------- */
#define EE_TYPE AT24C04
void AT24CXX_Init(void);
void AT24CXX_Write(uint16_t WriteAddr,uint8_t *pBuffer,uint16_t NumToWrite);
void AT24CXX_Read(uint16_t ReadAddr,uint8_t *pBuffer,uint16_t NumToRead);
uint8_t AT24CXX_Check(void);
void AT24CXX_PAGE_Check(void);
#endif
24CXX.c文件代码如下:
nclude "./BSP/24CXX/24CXX.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
//初始化IIC接口
/* Exported constants (常量) --------------------------------------------------------*/
/* Exported macro (宏) --------------------------------------------------------------*/
#define AT24CXX_HANDLE &g_iic_handler /* IIC接口 */
#define AT24C_DEV_ADDR 0XA0 /* 设备地址 */
/* Exported variables (变量)---------------------------------------------------------*/
I2C_HandleTypeDef g_iic_handler; /* I2C句柄 */
/* Exported functions (函数) ------------------------------------------------------- */
/*****************************************
函数名:void IIC_Init(void)
参数:无
功能描述:
返回值:无
*****************************************/
void IIC_Init(void)
{
g_iic_handler.Instance = I2C1_I2C; /* IIC1 */
g_iic_handler.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; /* 地址模式(7位) */
g_iic_handler.Init.ClockSpeed = 300000; /* 设置SCL时钟频率,该值要低于400k */
g_iic_handler.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; /* 不使用STM32的IIC设备地址2 */
g_iic_handler.Init.DutyCycle = I2C_DUTYCYCLE_2; /* 时钟占空比即low/high = 2:1 或 16:9 */
g_iic_handler.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; /* IIC从模式时广播模式设置(主机模式时不使用) */
g_iic_handler.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; /* IIC禁止时钟延长模式设置(从模式使用,主模式关闭) */
g_iic_handler.Init.OwnAddress1 = 0x0A; /* STM32的IIC设备地址1(支持7bit或10bit) */
g_iic_handler.Init.OwnAddress2 = 0;
HAL_I2C_Init(&g_iic_handler);
}
/**
* @brief IIC底层驱动,时钟使能,引脚配置
* @note 此函数会被HAL_SPI_Init()调用
* @param hspi:SPI句柄
* @retval 无
*/
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(i2cHandle->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
/* I2C1 clock enable */
I2C1_I2C_CLK_ENABLE();//放到了前面
I2C1_SCL_GPIO_CLK_ENABLE();
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = I2C1_SCL_GPIO_PIN|I2C1_SDA_GPIO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; /*开漏输出模式*/
GPIO_InitStruct.Pull = GPIO_NOPULL; /*不使用内部上拉或下拉电阻*/
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(I2C1_SCL_GPIO_PORT, &GPIO_InitStruct);
/* I2C1 interrupt Init */
// HAL_NVIC_SetPriority(I2C1_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(I2C1_IRQn);
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
}
}
void AT24CXX_Init(void)
{
IIC_Init();//IIC初始化
AT24CXX_Check();
}
/*****************************************
函数名:void AT24CXX_WriteOneByte(uint16_t WriteAddr,uint8_t DataToWrite)
参数:WriteAddr :要写入数据的地址 DataToWrite:要写入的数据
功能描述:从指定地址开始写入1个字节数据
返回值:无
*****************************************/
void AT24CXX_WriteOneByte(uint16_t WriteAddr,uint8_t * DataToWrite)
{
#if USE_HARDWARE_IIC == 1
uint8_t buf[2] = {WriteAddr>>8,WriteAddr%256};
if(EE_TYPE>AT24C16)
{
if(HAL_I2C_Mem_Write(AT24CXX_HANDLE,AT24C_DEV_ADDR,WriteAddr,I2C_MEMADD_SIZE_8BIT,DataToWrite,1,HAL_MAX_DELAY) != HAL_OK)
{
}
}
else
{
if(EE_TYPE>AT24C16)
{
if(HAL_I2C_Mem_Write(AT24CXX_HANDLE,AT24C_DEV_ADDR,WriteAddr,I2C_MEMADD_SIZE_8BIT,DataToWrite,1,HAL_MAX_DELAY) != HAL_OK)
{
}
}
else
if(HAL_I2C_Mem_Write(AT24CXX_HANDLE,AT24C_DEV_ADDR|((*buf& 0x07)<<1),*(buf+1),I2C_MEMADD_SIZE_8BIT,DataToWrite,1,HAL_MAX_DELAY) != HAL_OK)
{
}
}
#else
/* 根据不同的24CXX型号,发送高位地址
* 1,24C16以上的型号,分2个字节发送地址
* 2,24C16及以下的型号,发送1个低字节地址 + 占用器件地址的bit1~bit3位(用于表示高位地址,最多11位地址)
* 对于24C01/02,其器件地址格式(8bit)为: 1 0 1 0 A2 A1 A0 R/W
* 对于24C04, 其器件地址格式(8bit)为: 1 0 1 0 A2 A1 a8 R/W
* 对于24C08, 其器件地址格式(8bit)为: 1 0 1 0 A2 a9 a8 R/W
* 对于24C16, 其器件地址格式(8bit)为: 1 0 1 0 a10 a9 a8 R/W
* R/W : 读/写控制位,0:写;1:读
* A0/A1/A2 : 对应器件的1/2/3引脚(只有24C01/02/04/08有这些脚)
* a8/a9/a10: 对应存储整列的高位地址,11bit地址最多可以表示2048个位置,可以寻址24C16及以内的型号
*/
iic_start(); /* 产生IIC起始信号 */
if (EE_TYPE > AT24C16) /* 24C16以上的型号,分2个字节发送地址 */
{
iic_send_byte(AT24C_DEV_ADDR); /* 发送写命令 */
iic_wait_ack(); /* 每发送完一个字节都要等待ACK */
iic_send_byte(WriteAddr >> 8); /* 发送高字节地址 */
}
else /* 24C16及以下的型号,发送1个低字节地址 + 占用器件地址的bit1~bit3位(用于表示高位地址,最多11位地址) */
{
iic_send_byte(AT24C_DEV_ADDR + ((WriteAddr >> 8) << 1)); /* 发送0xA0+高位a8/a9/a10地址,写命令 */
}
iic_wait_ack(); /* 每发送完一个字节都要等待ACK */
iic_send_byte(WriteAddr % 256); /* 发送低位地址 */
iic_wait_ack();
iic_send_byte(WriteAddr); /* IIC发送一个字节 */
iic_wait_ack();
iic_stop(); /* 产生IIC停止信号 */
HAL_Delay(10); /* EEPROM的写入比较慢,必须等到10ms后再写下一个字节 */
#endif
}
/*****************************************
函数名:AT24CXX_WritePage(uint16_t WriteAddr,uint8_t u8Len, uint8_t *pData)
参数: WriteAddr : 要写入数据的地址
u8Len:要写入的数据
pData:要写入的数据的首地址
功能描述:从指定地址开始写入1个字节数据
返回值:无
*****************************************/
void AT24CXX_WritePage(uint16_t WriteAddr,uint8_t u8Len, uint8_t *pData)
{
#if USE_HARDWARE_IIC == 1
uint8_t buf[2] = {WriteAddr>>8,WriteAddr%256};
if (u8Len > PAGE_SIZE)//长度大于页的长度
{
u8Len = PAGE_SIZE;
}
if ((WriteAddr + (uint16_t)u8Len) > CAPACITY_SIZE)//超过容量
{
u8Len = (uint8_t)(CAPACITY_SIZE - WriteAddr);
}
if (((WriteAddr % PAGE_SIZE) + (uint16_t)u8Len) > PAGE_SIZE)//判断是否跨页
{
u8Len -= (uint8_t)((WriteAddr + (uint16_t)u8Len) % PAGE_SIZE);//跨页,截掉跨页的部分
}
if(EE_TYPE>AT24C16)
{
if(HAL_I2C_Mem_Write(AT24CXX_HANDLE,AT24C_DEV_ADDR,WriteAddr,I2C_MEMADD_SIZE_8BIT,pData,u8Len,HAL_MAX_DELAY) != HAL_OK)
{
}
}
else
{
if(EE_TYPE<=AT24C02)
{
HAL_I2C_Mem_Write(AT24CXX_HANDLE,AT24C_DEV_ADDR,*(buf+1),I2C_MEMADD_SIZE_8BIT,pData,u8Len,HAL_MAX_DELAY);
}
else
if(HAL_I2C_Mem_Write(AT24CXX_HANDLE,AT24C_DEV_ADDR|((*buf& 0x07)<<1),*(buf+1),I2C_MEMADD_SIZE_8BIT,pData,u8Len,HAL_MAX_DELAY) != HAL_OK)
{
}
}
#endif
}
/*****************************************
函数名:uint8_t AT24CXX_ReadOneByte(uint16_t ReadAddr)
参数: ReadAddr:要读取数据的地址 pBuffer:回填数据首地址
功能描述:从指定地址开始读取1个字节数据
返回值:返回读取到的数据
*****************************************/
uint8_t AT24CXX_ReadOneByte(uint16_t ReadAddr)
{
#if USE_HARDWARE_IIC == 1
uint8_t buf[2] = {ReadAddr>>8,ReadAddr%256},DataToRead = 0;
if(EE_TYPE>AT24C16)
{
if(HAL_I2C_Master_Transmit(AT24CXX_HANDLE,AT24C_DEV_ADDR,buf,2,0xff) != HAL_OK)
{
}
}else{
if(HAL_I2C_Master_Transmit(AT24CXX_HANDLE,AT24C_DEV_ADDR|((*buf& 0x07)<<1),buf+1,1,0xff) != HAL_OK)
{
}
}
if(HAL_I2C_Master_Receive(AT24CXX_HANDLE,AT24C_DEV_ADDR|((*buf& 0x07)<<1),&DataToRead,1,0xff) != HAL_OK)
{
}
return DataToRead;
#else
uint8_t data;
/* 根据不同的24CXX型号,发送高位地址
* 1,24C16以上的型号,分2个字节发送地址
* 2,24C16及以下的型号,发送1个低字节地址 + 占用器件地址的bit1~bit3位(用于表示高位地址,最多11位地址)
* 对于24C01/02,其器件地址格式(8bit)为: 1 0 1 0 A2 A1 A0 R/W
* 对于24C04, 其器件地址格式(8bit)为: 1 0 1 0 A2 A1 a8 R/W
* 对于24C08, 其器件地址格式(8bit)为: 1 0 1 0 A2 a9 a8 R/W
* 对于24C16, 其器件地址格式(8bit)为: 1 0 1 0 a10 a9 a8 R/W
* R/W : 读/写控制位,0:写;1:读
* A0/A1/A2 : 对应器件的1/2/3引脚(只有24C01/02/04/08有这些脚)
* a8/a9/a10: 对应存储整列的高位地址,11bit地址最多可以表示2048个位置,可以寻址24C16及以内的型号
*/
iic_start(); /* 产生IIC起始信号 */
if (EE_TYPE > AT24C16) /* 24C16以上的型号,分2个字节发送地址 */
{
iic_send_byte(AT24C_DEV_ADDR); /* 发送写命令 */
iic_wait_ack(); /* 每发送完一个字节都要等待ACK */
iic_send_byte(ReadAddr >> 8); /* 发送高字节地址 */
}
else /* 24C16及以下的型号,发送1个低字节地址 + 占用器件地址的bit1~bit3位(用于表示高位地址,最多11位地址) */
{
iic_send_byte(AT24C_DEV_ADDR + ((ReadAddr >> 8) << 1)); /* 发送0xA0+高位a8/a9/a10地址,写命令 */
}
iic_wait_ack(); /* 每发送完一个字节都要等待ACK */
iic_send_byte(ReadAddr % 256); /* 发送低位地址 */
iic_wait_ack();
iic_start(); /* 产生IIC起始信号 */
iic_send_byte(AT24C_DEV_ADDR+1); /* 发送读命令 */
iic_wait_ack();
data = iic_read_byte(0); /* IIC读取一个字节 */
iic_stop(); /* 产生IIC停止信号 */
return data;
#endif
}
/*****************************************
函数名:uint8_t AT24CXX_ReadOneByte(uint16_t ReadAddr)
参数: ReadAddr:要读取数据的地址 pBuffer:回填数据首地址
参数: WriteAddr : 读取的首地址
u8Len:读取数据字节数,最大为CAPACITY_SIZE
pBuff:读取数据存入的缓存
功能描述:从指定地址开始读取1个字节数据
返回值:返回读取到的数据
*****************************************/
void x24Cxx_ReadNByte(uint16_t ReadAddr, uint8_t *pBuff, uint16_t u16Len)
{
#if USE_HARDWARE_IIC == 1
uint8_t buf[2] = {ReadAddr>>8,ReadAddr%256};
if(EE_TYPE<=AT24C16)
{//器件寻址+写+页选择位的处理
if(EE_TYPE>AT24C02)
buf[0]=AT24C_DEV_ADDR|((*buf& 0x07)<<1);
else
buf[0]=AT24C_DEV_ADDR;
}
if (u16Len > CAPACITY_SIZE)//读取长度大于存储器的总容量(字节)
u16Len = CAPACITY_SIZE;
if ((ReadAddr + (uint16_t)u16Len) > CAPACITY_SIZE)//超过容量,截掉超过的部分
u16Len = (uint8_t)(CAPACITY_SIZE - ReadAddr);
if(EE_TYPE>AT24C16)
{
if(HAL_I2C_Master_Transmit(AT24CXX_HANDLE,AT24C_DEV_ADDR,buf,2*u16Len,0xff) != HAL_OK)
{
}
}else
{
if(HAL_I2C_Master_Transmit(AT24CXX_HANDLE,buf[0],buf+1,1,0xff) != HAL_OK)
{
}
}
if(HAL_I2C_Master_Receive(AT24CXX_HANDLE,buf[0],pBuff,u16Len,0xff) != HAL_OK)
{
}
#endif
}
/*****************************************
函数名:void AT24CXX_Write(uint16_t WriteAddr,uint8_t *pBuffer,uint16_t NumToWrite)
参数:WriteAddr :要写入数据的地址 pBuffer:要写入的数据的首地址 NumToWrite:要写入数据的长度
功能描述:从指定地址开始写入多个字节数据
返回值:无
*****************************************/
void AT24CXX_Write(uint16_t WriteAddr,uint8_t *pBuffer,uint16_t NumToWrite)
{
uint8_t Fill_PAGE_SIZ,Number_PAGE_SIZ,Broken_PAGE_SIZ;
Fill_PAGE_SIZ=PAGE_SIZE - (WriteAddr % PAGE_SIZE); //从写入地址开始填满一页所需的字节
if(NumToWrite>Fill_PAGE_SIZ)
Number_PAGE_SIZ=(NumToWrite-Fill_PAGE_SIZ)>>4; //需要填写的页数
else
Number_PAGE_SIZ=0;
if(NumToWrite>Fill_PAGE_SIZ) //最后不够一页的字节
Broken_PAGE_SIZ=NumToWrite-Fill_PAGE_SIZ-Number_PAGE_SIZ*PAGE_SIZE;
else
Broken_PAGE_SIZ=0;
if(NumToWrite>1)
{
if(NumToWrite>CAPACITY_SIZE)
NumToWrite=CAPACITY_SIZE;
if ((WriteAddr + (uint16_t)NumToWrite) > CAPACITY_SIZE)//超过容量
{
NumToWrite = (uint8_t)(CAPACITY_SIZE - WriteAddr);
}
if(NumToWrite>Fill_PAGE_SIZ)
{
AT24CXX_WritePage(WriteAddr,Fill_PAGE_SIZ,pBuffer);//从写的起始地址中写满一页
WriteAddr+=Fill_PAGE_SIZ;
pBuffer+=Fill_PAGE_SIZ;
delay_ms(5);
for(uint8_t i=0;i<Number_PAGE_SIZ;i++)//写完剩下的页数
{
AT24CXX_WritePage(WriteAddr,PAGE_SIZE,pBuffer);
WriteAddr+=PAGE_SIZE;
pBuffer+=PAGE_SIZE;
delay_ms(5);
}
delay_ms(5);
if(Broken_PAGE_SIZ!=0)
AT24CXX_WritePage(WriteAddr,Broken_PAGE_SIZ,pBuffer);//写完剩下的不够一页的字节
}
else
{
AT24CXX_WritePage(WriteAddr,NumToWrite,pBuffer);//写完不够一页的字节
}
// AT24CXX_WritePage(WriteAddr,NumToWrite,pBuffer);
}
else
{
AT24CXX_WriteOneByte(WriteAddr,pBuffer);
delay_ms(5);
}
}
/*****************************************
函数名:AT24CXX_Read(uint16_t ReadAddr,uint8_t *pBuffer,uint16_t NumToRead)
参数: ReadAddr:要读取数据的地址 pBuffer:回填数据首地址 NumToRead:数据长度
功能描述:从指定地址开始读取多个字节数据
返回值:无
*****************************************/
void AT24CXX_Read(uint16_t ReadAddr,uint8_t *pBuffer,uint16_t NumToRead)
{
if(NumToRead>1)
{
x24Cxx_ReadNByte(ReadAddr,pBuffer,NumToRead);
}
else
{
pBuffer[0] = AT24CXX_ReadOneByte(ReadAddr);
}
}
/*****************************************
函数名:uint8_t AT24CXX_Check(void)
参数:无
功能描述:检查AT24CXX是否正常,这里用了24XX的最后一个地址(255)来存储标志字.如果用其他24C系列,这个地址要修改
返回值:检测成功返回0 失败返回1
*****************************************/
uint8_t AT24CXX_Check(void)
{
uint8_t temp;
uint8_t data = 0XAC;
AT24CXX_Read(EE_TYPE,&temp,1);//避免每次开机都写AT24CXX
if(temp == 0XAC)
return 0;
AT24CXX_Write(EE_TYPE,&data,1);
AT24CXX_Read(EE_TYPE,&temp,1);
if(temp != 0XAC)
return 1;
return 0;
}
/*****************************************
函数名:void AT24CXX_PAGE_Check(void)
参数: 无
功能描述: 检查AT24CXX在页与页之间随机的任意地址写入任意长度的数据(数据长度不能超过存储容量)
返回值: 无
*****************************************/
void AT24CXX_PAGE_Check(void)
{ uint8_t judge=0XA5;
uint8_t temp[40]={0};
uint8_t data[PAGE_SIZE*2]={0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,\
0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC};
//0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC,0XAC
//0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5,0XA5
AT24CXX_Write(0,data,5);
delay_ms(5);
printf("写入5个数据...\r\n");
AT24CXX_Read(0,temp,5);
if(temp[0] != judge)
{
printf("AT24CXX NG!\r\n");
}
else
{
printf("读取写入数据组1!\r\n");
for(uint8_t i=0;i<sizeof(temp) / sizeof(temp[0]);i++)
{
printf("%#02X ",temp[i]);
if(i>0&(i+1)%16==0)
printf("\r\n");
}
}
AT24CXX_Write(240,data,16);
delay_ms(5);
printf("\r\n写入16个数据...\r\n");
AT24CXX_Read(240,temp,16);
if(temp[0] != judge)
{
printf("AT24CXX NG!\r\n");
}
else
{
printf("读取写入数据组2!\r\n");
for(uint8_t i=0;i<sizeof(temp) / sizeof(temp[0]);i++)
{
printf("%#02X ",temp[i]);
if(i>0&(i+1)%16==0)
printf("\r\n");
}
}
AT24CXX_Write(240,data,20);
delay_ms(5);
printf("\r\n写入20个数据...\r\n");
AT24CXX_Read(240,temp,20);
if(temp[0] != judge)
{
printf("AT24CXX NG!\r\n");
}
else
{
printf("读取写入数据组3!\r\n");
for(uint8_t i=0;i<sizeof(temp) / sizeof(temp[0]);i++)
{
printf("%#02X ",temp[i]);
if(i>0&(i+1)%16==0)
printf("\r\n");
}
}
AT24CXX_Write(240,data,32);
delay_ms(5);
printf("\r\n写入32个数据...\r\n");
AT24CXX_Read(240,temp,32);
if(temp[0] != judge)
{
printf("AT24CXX NG!\r\n");
}
else
{
printf("读取写入数据组4!\r\n");
for(uint8_t i=0;i<sizeof(temp) / sizeof(temp[0]);i++)
{
printf("%#02X ",temp[i]);
if(i>0&(i+1)%16==0)
printf("\r\n");
}
}
AT24CXX_Write(245,data,32);
delay_ms(5);
printf("\r\n偏移5个地址写入32个数据...\r\n");
AT24CXX_Read(245,temp,32);
if(temp[0] != judge)
{
printf("AT24CXX NG!\r\n");
}
else
{
printf("读取写入数据组5!\r\n");
for(uint8_t i=0;i<sizeof(temp) / sizeof(temp[0]);i++)
{
printf("%#02X ",temp[i]);
if(i>0&(i+1)%16==0)
printf("\r\n");
}
}
}
作者:qq_3227305