您的位置 首页 观点

STM32的I2C-EEPROM已调试成功

万利的I2C-EEPROM例程有些问题,经本人两个昼夜的反复试验,已修改完善。修改了两个地方,在voidI2C_EE_BufferWrite(u8*pBuffer,u8…

万利的I2CEEPROM例程有些问题,经自己两个昼夜的重复实验,已修正完善。

修正了两个当地,在void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)写操作函数和void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)读操作函数体内的最初先要履行一句I2C_EE_WaitEepromStandbyState();

这样在今后调用写操作函数和读操作函数时就不必履行I2C_EE_WaitEepromStandbyState()了。但上电复位后先要履行一次读操作,今后就可以无限制的随意调用这两个函数了。

具体如下。

/* Includes ——————————————————————*/
#include “stm32f10x_lib.h”
#include “i2c_ee.h”
#include”delay.h”

/* Private typedef ———————————————————–*/
/* Private define ————————————————————*/
#define I2C_Speed 10000
#define I2C1_SLAVE_ADDRESS7 0xA0

#define I2C_PageSize 4

/* Private macro ————————————————————-*/
/* Private variables ———————————————————*/
u16 EEPROM_ADDRESS;

/* Private function prototypes ———————————————–*/

void I2C_Configuration(void);

/*******************************************************************************
* Function Name : I2C_Configuration
* Description : I2C Configuration
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void I2C_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;

/* Configure I2C1 pins: SCL and SDA */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;//开漏输出
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* I2C configuration */
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//设置 I2C为 I2C形式
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//I2C快速形式 Tlow / Thigh = 2

I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;//设置第一个设备地址
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;//使能应对
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//应对 7位地址
I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;//设置时钟频率
/* I2C Peripheral Enable */
I2C_Cmd(I2C1, ENABLE);//使能I2C外设
/* Apply I2C configuration after enabling it */
I2C_Init(I2C1, &I2C_InitStructure);
}

/*******************************************************************************
* Function Name : I2C_EE_Init
* Description : Initializes peripherals used by the I2C EEPROM driver.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void I2C_EE_Init()
{
/* I2C configuration */
I2C_Configuration();

/* depending on the EEPROM Address selected in the i2c_ee.h file */
#ifdef EEPROM_Block0_ADDRESS
/* Select the EEPROM Block0 to write on */
EEPROM_ADDRESS = EEPROM_Block0_ADDRESS;
#endif
#ifdef EEPROM_Block1_ADDRESS
/* Select the EEPROM Block1 to write on */
EEPROM_ADDRESS = EEPROM_Block1_ADDRESS;
#endif
#ifdef EEPROM_Block2_ADDRESS
/* Select the EEPROM Block2 to write on */
EEPROM_ADDRESS = EEPROM_Block2_ADDRESS;
#endif
#ifdef EEPROM_Block3_ADDRESS
/* Select the EEPROM Block3 to write on */
EEPROM_ADDRESS = EEPROM_Block3_ADDRESS;
#endif
}

/*******************************************************************************
* Function Name : I2C_EE_BufferWrite
* Description : Writes buffer of data to the I2C EEPROM.
* Input : – pBuffer : pointer to the buffer containing the data to be
* written to the EEPROM.
* – WriteAddr : EEPROMs internal address to write to.
* – NumByteToWrite : number of bytes to write to the EEPROM.
* Output : None
* Return : None
pBuffer:指向要写入数据数组的指针
WriteAddr:24c02中要写入数据的首地址
NumByteToWrite:写入的字节数
*******************************************************************************/
void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)//将缓冲器的数据写入EEPROM
{
u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;

Addr = WriteAddr % I2C_PageSize;//写入地址是每页的第几位
count = I2C_PageSize – Addr;//在开端的一页要写入的个数
NumOfPage = NumByteToWrite / I2C_PageSize;//要写入的页数
NumOfSingle = NumByteToWrite % I2C_PageSize;//缺乏一页的个数
I2C_EE_WaitEepromStandbyState();//EEPROM设为待命状况
/* If WriteAddr is I2C_PageSize aligned */
if(Addr == 0) //写入地址是页的开端
{
/* If NumByteToWrite < I2C_PageSize */
if(NumOfPage == 0) //数据小于一页
{
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);//写少于一页的数据
I2C_EE_WaitEepromStandbyState();//EEPROM设为待命状况
}
/* If NumByteToWrite > I2C_PageSize */
else //数据大于等于一页
{
while(NumOfPage–)//要写入的页数
{
I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize); //写一页的数据
I2C_EE_WaitEepromStandbyState();//EEPROM设为待命状况
WriteAddr += I2C_PageSize;
pBuffer += I2C_PageSize;
}

if(NumOfSingle!=0)//剩下数据小于一页
{
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);//写少于一页的数据
I2C_EE_WaitEepromStandbyState();//EEPROM设为待命状况
}
}
}
/* If WriteAddr is not I2C_PageSize aligned */
else //写入地址不是页的开端
{
/* If NumByteToWrite < I2C_PageSize */
if(NumOfPage== 0) //数据小于一页
{
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);//写少于一页的数据
I2C_EE_WaitEepromStandbyState();//EEPROM设为待命状况
}
/* If NumByteToWrite > I2C_PageSize */
else//数据大于等于一页
{
NumByteToWrite -= count;
NumOfPage = NumByteToWrite / I2C_PageSize; //从头核算要写入的页数
NumOfSingle = NumByteToWrite % I2C_PageSize;//从头核算缺乏一页的个数

if(count != 0)//在此处count必定不为0,此判别条件好象有点剩下
{
I2C_EE_PageWrite(pBuffer, WriteAddr, count);//将开端的空间写满一页
I2C_EE_WaitEepromStandbyState();//EEPROM设为待命状况
WriteAddr += count;
pBuffer += count;
}

while(NumOfPage–)//要写入的页数
{
I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);//写一页的数据
I2C_EE_WaitEepromStandbyState();//EEPROM设为待命状况
WriteAddr += I2C_PageSize;
pBuffer += I2C_PageSize;
}
if(NumOfSingle != 0)//剩下数据小于一页
{
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle); //写少于一页的数据
I2C_EE_WaitEepromStandbyState();//EEPROM设为待命状况
}
}
}
}

/*******************************************************************************
* Function Name : I2C_EE_ByteWrite
* Description : Writes one byte to the I2C EEPROM.
* Input : – pBuffer : pointer to the buffer containing the data to be
* written to the EEPROM.
* – WriteAddr : EEPROMs internal address to write to.
* Output : None
* Return : None
pBuffer:指向要写入数据数组的指针
WriteAddr:24c02中要写入数据的首地址
*******************************************************************************/
void I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr)//写一个字节到EEPROM
{
/* Send STRAT condition */
I2C_GenerateSTART(I2C1, ENABLE);//发生 I2Cx传输 START条件

/* Test on EV5 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); //查看最近一次 I2C事情是否是输入的事情

/* Send EEPROM address for write */
I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);//向指定的从 I2C设备传送地址字,挑选发送方向
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//查看最近一次 I2C事情是否是输入的事情

/* Send the EEPROMs internal address to write to */
I2C_SendData(I2C1, WriteAddr);//经过外设 I2Cx发送地址
/* Test on EV8 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//查看最近一次 I2C事情是否是输入的事情

/* Send the byte to be written */
I2C_SendData(I2C1, *pBuffer); //经过外设 I2Cx发送数据

/* Test on EV8 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//查看最近一次 I2C事情是否是输入的事情
/* Send STOP condition */
I2C_GenerateSTOP(I2C1, ENABLE);//发生 I2Cx传输 STOP条件
}

/*******************************************************************************
* Function Name : I2C_EE_PageWrite
* Description : Writes more than one byte to the EEPROM with a single WRITE
* cycle. The number of byte cant exceed the EEPROM page size.
* Input : – pBuffer : pointer to the buffer containing the data to be
* written to the EEPROM.
* – WriteAddr : EEPROMs internal address to write to.
* – NumByteToWrite : number of bytes to write to the EEPROM.
* Output : None
* Return : None
pBuffer:指向要写入数据数组的指针
WriteAddr:24c02中要写入数据的首地址
NumByteToWrite:写入的字节数
*******************************************************************************/
void I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)//写少于一页的数据
{
/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);//发生 I2Cx传输 START条件
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); //查看最近一次 I2C事情是否是输入的事情
/* Send EEPROM address for write */
I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);//向指定的从 I2C设备传送地址字,挑选发送方向

/* Test on EV6 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); //查看最近一次 I2C事情是否是输入的事情

/* Send the EEPROMs internal address to write to */
I2C_SendData(I2C1, WriteAddr); //经过外设 I2Cx发送地址

/* Test on EV8 and clear it */
while(! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //查看最近一次 I2C事情是否是输入的事情

/* While there is data to be written */
while(NumByteToWrite–)
{
/* Send the current byte */
I2C_SendData(I2C1, *pBuffer); //经过外设 I2Cx发送数据

/* Point to the next byte to be written */
pBuffer++;
/* Test on EV8 and clear it */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//查看最近一次 I2C事情是否是输入的事情
}

/* Send STOP condition */
I2C_GenerateSTOP(I2C1, ENABLE);//发生 I2Cx传输 STOP条件
}

/*******************************************************************************
* Function Name : I2C_EE_BufferRead
* Description : Reads a block of data from the EEPROM.
* Input : – pBuffer : pointer to the buffer that receives the data read
* from the EEPROM.
* – ReadAddr : EEPROMs internal address to read from.
* – NumByteToRead : number of bytes to read from the EEPROM.
* Output : None
* Return : None
pBuffer:指向要保存读出数据的数组的指针
ReadAddr:24c02中要读出数据的首地址
NumByteToRead:读出的字节数
*******************************************************************************/
void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)//将EEPROM的数据读入缓冲器
{
I2C_EE_WaitEepromStandbyState();//EEPROM设为待命状况
/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);//发生 I2Cx传输 START条件
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//查看最近一次 I2C事情是否是输入的事情
/* In the case of a single data transfer disable ACK before reading the data */
if(NumByteToRead==1)
{
I2C_AcknowledgeConfig(I2C1, DISABLE);//使能或许失能指定 I2C的应对功用
}
/* Send EEPROM address for write */
I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);//向指定的从 I2C设备传送地址字,挑选发送方向

/* Test on EV6 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//查看最近一次 I2C事情是否是输入的事情
/* Clear EV6 by setting again the PE bit */
I2C_Cmd(I2C1, ENABLE);//使能或许失能 I2C外设

/* Send the EEPROMs internal address to write to */
I2C_SendData(I2C1, ReadAddr); //经过外设 I2Cx发送地址

/* Test on EV8 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//查看最近一次 I2C事情是否是输入的事情
/* Send STRAT condition a second time */
I2C_GenerateSTART(I2C1, ENABLE);//发生 I2Cx传输 START条件
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//查看最近一次 I2C事情是否是输入的事情
/* Send EEPROM address for read */
I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Receiver);//向指定的从 I2C设备传送地址字,挑选接纳方向
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));//查看最近一次 I2C事情是否是输入的事情
/* While there is data to be read */
while(NumByteToRead)
{
/* Test on EV7 and clear it */
if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)) //查看最近一次 I2C事情是否是输入的事情
{
if(NumByteToRead == 2)
{
/* Disable Acknowledgement */
I2C_AcknowledgeConfig(I2C1, DISABLE);//使能或许失能指定 I2C的应对功用
}

if(NumByteToRead == 1)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2C1, ENABLE);//发生 I2Cx传输 STOP条件
}

/* Read a byte from the EEPROM */
*pBuffer = I2C_ReceiveData(I2C1);//回来经过 I2Cx最近接纳的数据

/* Point to the next location where the byte read will be saved */
pBuffer++;

/* Decrement the read bytes counter */
NumByteToRead–;
}
}

/* Enable Acknowledgement to be ready for another reception */
I2C_AcknowledgeConfig(I2C1, ENABLE);//使能或许失能指定 I2C的应对功用
}

/*******************************************************************************
* Function Name : I2C_EE_WaitEepromStandbyState
* Description : Wait for EEPROM Standby state
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void I2C_EE_WaitEepromStandbyState(void) //EEPROM设为待命状况
{
vu16 SR1_Tmp = 0;

do
{
/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);//发生 I2Cx传输 START条件
/* Read I2C1 SR1 register */
SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1);//读取指定的 I2C寄存器 I2C_SR1 并回来其值
/* Send EEPROM address for write */
I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);//向指定的从 I2C设备传送地址字 ,挑选发送方向
}while(!(I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0x0002));//地址发送完毕
/* Clear AF flag */
I2C_ClearFlag(I2C1, I2C_FLAG_AF);//铲除 I2Cx的应对过错标志位

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/news/guandian/268241.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部