你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

查看: 5357|回复: 0

【MCU实战经验】+STM32F4硬件IIC实现对AT24C02的操作

[复制链接]

36

主题

89

回帖

2

蝴蝶豆

金牌会员

最后登录
2020-12-9
发表于 2014-4-1 10:13:54 | 显示全部楼层 |阅读模式
本程序利用STM32F4的硬件IIC实现对AT24C02的任何操作!!
Bsp.c主要对板载外设进行初始化!
/**
  ******************************************************************************
  * @file    bsp.c
  * @author  wangfei
  * @date    13-April-2012
  * @e-mail  wfmjj@hotmail.com
  * @brief   Initialize peripherals.
  *****************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "bsp.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
  * @brief   This function handles NMI exception.
  * @param  None
  * @retval None
  */
void Bsp_Init(void)
{
Bsp_GPIO_Config();
Bsp_IIC_Config();
Bsp_USART3_Config();

}
/**
  * @brief   This function config gpio.
  * @param  None
  * @retval None
  */
void Bsp_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;  //定义结构体

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);   //打开外设GPIOE的时钟--LED
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);     //turn on gpioc clock
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);   //打开GPIOB口的时钟I2C_CLK--PB6

//LED端口配置
GPIO_InitStructure.GPIO_Pin=(GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);  //led口配置
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOE, &GPIO_InitStructure);
//USART3端口配置
GPIO_PinAFConfig(GPIOC,GPIO_PinSource10,GPIO_AF_USART3);  //Connect USART3 pins to AF7
  GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,GPIO_AF_USART3);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10 | GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
//IIC端口设置 IIC_CLK和IIC_SDA引脚均要设置为复用开漏不带上拉输出
GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_I2C1);  //开启PB6的复用功能连接至I2C1
GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_I2C1);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6 | GPIO_Pin_7;   //选择PB6和PB7引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;           //开启PB6和PB7的复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;    //PB6和PB7设置为开漏输出
GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL;   //PB6和PB7口不带上拉电阻
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/**
  * @brief   This function config iic.
  * @param  None
  * @retval None
  */
void Bsp_IIC_Config(void)
{
  I2C_InitTypeDef I2C_InitStructure;   

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);   //打开IIC外设时钟
  
I2C_DeInit(I2C1); //将外设IIC的各个寄存器恢复到复位以后的值

I2C_InitStructure.I2C_ClockSpeed=100000;  //标准模式 时钟频率为100KHZ
I2C_InitStructure.I2C_Mode=I2C_Mode_I2C;   //选中I2C模式
I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1=0X00;      //当I2C出于从模式时,自身的地址
I2C_InitStructure.I2C_Ack=I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &I2C_InitStructure);

I2C_AcknowledgeConfig(I2C1,ENABLE);   //在接收到一个字节后返回一个应答ACK
I2C_Cmd(I2C1,ENABLE);  //开启外设IIC模块
}
/**
  * @brief   This function config usart3.
  * @param  None
  * @retval None
  */
void Bsp_USART3_Config(void)
{
USART_InitTypeDef USART_InitStructure;
  
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //turn on usart3 clock
  
  USART_InitStructure.USART_BaudRate =115200 ;         //波特率设置
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_Init(USART3, &USART_InitStructure);
  
  //USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
  USART_Cmd(USART3,ENABLE);
  USART_ClearFlag(USART3, USART_FLAG_TC);   //清除发送完成标志位
}
AT24C02.C文件主要对AT24C02的操作
/**
  ******************************************************************************
  * @file    at24c02.c
  * @author  wangfei
  * @date    13-April-2012
  * @e-mail  wfmjj@hotmail.com
  * @brief  write or read eeprom
  *****************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "at24c02.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
  * @brief   This function write one byte to at24c02.
  * @param  None
  * @retval None
  */
void IIC_Write_AT24C02_OneByte(uint8_t addr,uint8_t data)
{
uint16_t flag;
//判断BUSY是否为1,BUSY=1总线处于忙状态
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));  //如果BUSY=1则等待一直等到BUSY=0

//主机产生起始条件
I2C_GenerateSTART(I2C1,ENABLE);  

//判断SB是否为1,SB=1起始条件已经发送 即判断EV5
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)==ERROR);  //当产生了起始条件,设备就进入了主模式

//发送eepROM的地址0XA0
I2C_Send7bitAddress(I2C1,0XA0,I2C_Direction_Transmitter); //软件读取SR1寄存器后,写数据寄存器的操作将清除SB位
//判断ADDR是否为1,ADDR=1地址发送结束 即判断EV6
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)==ERROR);
  flag=I2C1->SR2; //软件读取SR1寄存器后,对SR2寄存器的读操作将清除ADDR位
//发送AT24C02的内部地址:即数据要写入的地址
I2C_SendData(I2C1,addr);

//判断TXE是否为1,TXE=1移位寄存器不为空,数据寄存器为空 即判断EV8
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING)==ERROR);

//发送数据到要写入的地址
I2C_SendData(I2C1,data);    //对数据寄存器的写操作将清除TXE位

//判断TXE和BTF是否为1,TXE=1,BTF=1请求设置停止位 即判断EV8_2
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)==ERROR);

//关闭通讯,产生停止条件
I2C_GenerateSTOP(I2C1,ENABLE); //产生停止条件时,硬件自动清除TXE和BTF位
}
/**
  * @brief   This function waite for eeprom standby state.
  * @param   none
* @retval  None
  */
/*AT24C02在接收完数据后,启动内部周期写入数据的时间内不会对主机的请求做出应答的特性,因此此
  函数循环发送起始信号,若检测到AT24C02的应答,则说明AT24C02已完成上一步的数据写入,进入稳定状态
  可以进行下一次的操作,因此这个函数在数据写入完成后必须调用此函数,判断AT24C02是否进入稳定状态*/
void IIC_Waite_AT24C02_Standby(void)
{
  uint16_t SR1_Flag;
I2C1->SR1&=0X0000;  //清除I2C1_SR1寄存器
do
{
  I2C_GenerateSTART(I2C1,ENABLE);  //产生起始条件
  
  SR1_Flag=I2C1->SR1;  //软件读取SR1寄存器后,写数据寄存器的操作将清除SB位
  
  I2C_Send7bitAddress(I2C1,0XA0,I2C_Direction_Transmitter); //发送7位AT24C02的地址
}while((I2C1->SR1&0X0002)==0X00);  //当ADDR=1时,跳出此循环表明AT24C02写入数据已完成

  I2C_ClearFlag(I2C1,I2C_FLAG_AF);  //清除应答失败位

  I2C_GenerateSTOP(I2C1,ENABLE);   //发送停止信号
}
/*
* 函数名:IIC_AT24C02_PageWrite
* 描述  :在EEPROM的一个写循环中可以写多个字节,但一次写入的字节数
*         不能超过EEPROM页的大小。AT24C02每页有8个字节。
* 输入  :-pBuffer 缓冲区指针
*         -WriteAddr 接收数据的EEPROM的地址
*         -NumByte 要写入EEPROM的字节数
* 输出  :无
* 返回  :无
* 调用  :外部调用
*/
void IIC_AT24C02_PageWrite(uint8_t *pBuffer,uint8_t WriteAddr,uint8_t NumByte)
{
uint16_t state;
//判断BUSY是否为1,BUSY=1总线处于忙状态
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));  //如果BUSY=1则等待一直等到BUSY=0

//主机产生起始条件
I2C_GenerateSTART(I2C1,ENABLE);  

//判断SB是否为1,SB=1起始条件已经发送 即判断EV5
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)==ERROR);  //当产生了起始条件,设备就进入了主模式

//发送eepROM的地址0XA0
I2C_Send7bitAddress(I2C1,0XA0,I2C_Direction_Transmitter); //软件读取SR1寄存器后,写数据寄存器的操作将清除SB位
//判断ADDR是否为1,ADDR=1地址发送结束 即判断EV6
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)==ERROR);
  state=I2C1->SR2; //软件读取SR1寄存器后,对SR2寄存器的读操作将清除ADDR位

//发送AT24C02的内部地址:即数据要写入的地址
I2C_SendData(I2C1,WriteAddr);

//判断TXE是否为1,TXE=1移位寄存器不为空,数据寄存器为空 即判断EV8
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING)==ERROR);

for(;NumByte>0;NumByte--)
{
  //发送数据到要写入的地址
   I2C_SendData(I2C1,*pBuffer);    //对数据寄存器的写操作将清除TXE位
  
  //缓冲区指针加1指向下一个要写入的数据
  pBuffer++;
  
  //判断TXE和BTF是否为1,TXE=1,BTF=1请求设置停止位 即判断EV8_2
   while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)==ERROR);
}

//关闭通讯,产生停止条件
I2C_GenerateSTOP(I2C1,ENABLE); //产生停止条件时,硬件自动清除TXE和BTF位
}
/**
  * @brief   This function read one byte from slect address.
  * @param   none
* @retval  None
  */
/*选择性读取允许主器件对AT24C02寄存器的任意字节读操作,具体步骤如下:
1--主器件发送起始信号,从器件地址,和他想读取的字节数据的地址执行一个伪写操作
2--AT24C02应答之后,主器件从新发送起始信号和从器件地址,此时R/W位置1。
3--AT24C02响应并发送应答信号,然后输出一个所要求的8位字节数据。
4--主器件不发送应答信号,但产生一个停止信号。*/
uint8_t IIC_Read_AT24C02_OneByte(uint8_t address)
{
  uint16_t temp,flag;
//判断BUSY是否为1,BUSY=1总线处于忙状态
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));  //如果BUSY=1则等待一直等到BUSY=0

//主机产生起始条件
I2C_GenerateSTART(I2C1,ENABLE);  

//判断SB是否为1,SB=1起始条件已经发送 即判断EV5
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)==ERROR);  //当产生了起始条件,设备就进入了主模式

//发送eepROM的地址0XA0
I2C_Send7bitAddress(I2C1,0XA0,I2C_Direction_Transmitter); //软件读取SR1寄存器后,写数据寄存器的操作将清除SB位
//判断ADDR是否为1,ADDR=1地址发送结束 即判断EV6
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)==ERROR);
  flag=I2C1->SR2; //软件读取SR1寄存器后,对SR2寄存器的读操作将清除ADDR位
//发送想要读取字节的地址
I2C_SendData(I2C1,address);
//判断TXE是否为1,TXE=1移位寄存器不为空,数据寄存器为空 即判断EV8
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING)==ERROR);

//主机重新发送起始信号
I2C_GenerateSTART(I2C1,ENABLE);  

//判断SB是否为1,SB=1起始条件已经发送 即判断EV5
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)==ERROR);  //当产生了起始条件,设备就进入了主模式
//主机重新发送AT24C02的地址,这是R/W位置1
  I2C_Send7bitAddress(I2C1,0XA0,I2C_Direction_Receiver);

//判断ADDR是否为1,ADDR=1地址发送结束 即判断EV6
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)==ERROR);
  flag=I2C1->SR2; //软件读取SR1寄存器后,对SR2寄存器的读操作将清除ADDR位
I2C_AcknowledgeConfig(I2C1,DISABLE);
I2C_GenerateSTOP(I2C1,ENABLE);
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)==ERROR);

temp=I2C_ReceiveData(I2C1);

I2C_AcknowledgeConfig(I2C1, ENABLE); //打开应答信号使其回到初始状态
return temp;
}
/*
* 函数名:IIC_AT24C02_PageRead
* 描述  :从EEPROM里面读取一块数据。
* 输入  :-pBuffer 存放从EEPROM读取的数据的缓冲区指针。
*         -ReadAddr 接收数据的EEPROM的地址。
*         -NumByte 要从EEPROM读取的字节数。
* 输出  :无
* 返回  :无
* 调用  :外部调用
*/
void IIC_AT24C02_PageRead(uint8_t *pBuffer,uint8_t ReadAddr,uint8_t NumByte)
{
uint16_t  flag1,flag2;

//判断BUSY是否为1,BUSY=1总线处于忙状态
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));  //如果BUSY=1则等待一直等到BUSY=0

//主机产生起始条件
I2C_GenerateSTART(I2C1,ENABLE);  

//判断SB是否为1,SB=1起始条件已经发送 即判断EV5
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)==ERROR);  //当产生了起始条件,设备就进入了主模式
//发送eepROM的地址0XA0
I2C_Send7bitAddress(I2C1,0XA0,I2C_Direction_Transmitter); //软件读取SR1寄存器后,写数据寄存器的操作将清除SB位
//判断ADDR是否为1,ADDR=1地址发送结束 即判断EV6
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)==ERROR);
  flag1=I2C1->SR2; //软件读取SR1寄存器后,对SR2寄存器的读操作将清除ADDR位

//发送想要读取字节的地址
I2C_SendData(I2C1,ReadAddr);
//判断TXE是否为1,TXE=1移位寄存器不为空,数据寄存器为空 即判断EV8
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING)==ERROR);

//主机重新发送起始信号
I2C_GenerateSTART(I2C1,ENABLE);  

//判断SB是否为1,SB=1起始条件已经发送 即判断EV5
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)==ERROR);  //当产生了起始条件,设备就进入了主模式
//主机重新发送AT24C02的地址,这是R/W位置1
  I2C_Send7bitAddress(I2C1,0XA0,I2C_Direction_Receiver);
//判断ADDR是否为1,ADDR=1地址发送结束 即判断EV6
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)==ERROR);
  flag2=I2C1->SR2; //软件读取SR1寄存器后,对SR2寄存器的读操作将清除ADDR位

//接收AT24C02发送的数据
  while(NumByte)
{
  if(NumByte==1)   //等于1时数据已经发送完成
  {
   //主机不再发送响应信号
   I2C_AcknowledgeConfig(I2C1,DISABLE);
  //主机产生停止信号
      I2C_GenerateSTOP(I2C1,ENABLE);
  }
  //检查RXNE是否为1,即判断EV7
  if(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)==SUCCESS)
  {
   /* Read a byte from the EEPROM */
    *pBuffer = I2C_ReceiveData(I2C1);  //软件读取数据寄存器的值,讲清除RXNE位
   
   /* Point to the next location where the byte read will be saved */
       pBuffer++;
   
    /* Decrement the read bytes counter */
       NumByte--;   
  }
}
I2C_AcknowledgeConfig(I2C1, ENABLE); //打开应答信号使其回到初始状态
}
/*
* 函数名:IIC_AT24C02_BufferWrite
* 描述  :将缓冲区中的数据写到I2C EEPROM中
* 输入  :-pBuffer 缓冲区指针
*         -WriteAddr 接收数据的EEPROM的地址
*         -NumByteToWrite 要写入EEPROM的字节数
* 输出  :无
* 返回  :无
*/
void IIC_AT24C02_BufferWrite(uint8_t *pBuffer,uint8_t WriteAddr,uint8_t NumByteToWrite )
{
uint8_t NumofPage=0;    //要写入的数据块按页操作所需的次数(AT24C02页写,可一次写入8个字节数据)
uint8_t NumofSignal=0;  //要写入的数据块按页写操作完成后剩余的字节数
uint8_t addr=0;         //要写入数据块的首地址是否为8的倍数
uint8_t count=0;        //

addr=WriteAddr%I2C_PageSize; //判断要写入的数据块首地址是否为8的倍数,addr=0则为8的整数倍
//如果要写入的数据的起始地址不是8的倍数,则addr不为0.算出与8的差值。
//写入数据的起始地址+这个差值=下一个为8的倍数的地址
  
count=8-addr;

NumofPage=NumByteToWrite/I2C_PageSize; //计算写入的数据块按页写需要进行页操作的次数
NumofSignal=NumByteToWrite%I2C_PageSize; //页操作剩余的字节数

/* 如果要写入数据块的首地址为8的倍数,即addr=0只需操作几次页写函数即可 */
if(addr==0)   //首先判断起始地址是否为8的整数倍,在判断要写的数据长度是否大于8个字节
{
  //如果写入的数据块长度小于8个字节
  if(NumofPage==0)
  {
   IIC_AT24C02_PageWrite(pBuffer,WriteAddr,NumofSignal);
   IIC_Waite_AT24C02_Standby();
  }
  else    //要写入的数据块长度大于8个字节,即按页操作
  {
   while(NumofPage--)
   {
    IIC_AT24C02_PageWrite(pBuffer,WriteAddr,8);  //进行页操作一次可以连续写入8个字节数据
    IIC_Waite_AT24C02_Standby();
    WriteAddr+=8;       //写入数据的地址加8
    pBuffer+=8;         //将要写入的数据的指针加8
   }
   if(NumofSignal!=0)  //按页操作完成之后的数据不够8个字节的
   {
    IIC_AT24C02_PageWrite(pBuffer,WriteAddr,NumofSignal);  //将剩余的字节数写入到对应的地址中
    IIC_Waite_AT24C02_Standby();
   }
  }
}
else   //如果写入数据的起始地址不为8的倍数,即addr!=0.
{
  //如果写入的数据块长度小于8个字节
  if(NumofPage==0)
  {
   IIC_AT24C02_PageWrite(pBuffer,WriteAddr,NumofSignal);
   IIC_Waite_AT24C02_Standby();
  }
  else    //要写入的数据块长度大于8个字节,即按页操作
  {
   //首先要先写入count个数据,即算出写完counter个字节数据后NumByteToWrite的新值
   
   NumByteToWrite-=count;
   NumofPage=NumByteToWrite/I2C_PageSize; //计算写入的数据块按页写需要进行页操作的次数
     NumofSignal=NumByteToWrite%I2C_PageSize; //页操作剩余的字节数
   
   if(count!=0)
   {
    IIC_AT24C02_PageWrite(pBuffer,WriteAddr,count);
     IIC_Waite_AT24C02_Standby();
    WriteAddr+=count;
    pBuffer+=count;
   }
   while(NumofPage--)
   {
    IIC_AT24C02_PageWrite(pBuffer,WriteAddr,8);  //进行页操作一次可以连续写入8个字节数据
    IIC_Waite_AT24C02_Standby();
    WriteAddr+=8;       //写入数据的地址加8
    pBuffer+=8;         //将要写入的数据的指针加8
   }
   if(NumofSignal!=0)  //按页操作完成之后的数据不够8个字节的
   {
    IIC_AT24C02_PageWrite(pBuffer,WriteAddr,NumofSignal);  //将剩余的字节数写入到对应的地址中
    IIC_Waite_AT24C02_Standby();
   }
  }
}
}
 

app.c主要对at24c02的读与写
/**
  ******************************************************************************
  * @file    app.c
  * @author  wangfei
  * @date    13-April-2012
  * @e-mail  wfmjj@hotmail.com
  * @brief   Initialize peripherals.
  *****************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "app.h"
#include "bsp.h"
#include "at24c02.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint8_t PageWrite[8]={1,2,3,4,5,6,7,8};
uint8_t PageRead[8];
uint8_t SequenceWrite[15]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
uint8_t SequenceRead[15];
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
  * @brief   This function handles NMI exception.
  * @param  None
  * @retval None
  */
int main(void)
{
  uint8_t I2C_Data,i,m;
  uint8_t *p,*q,*r,*s;
  uint8_t ReadSum=0,WriteSum=0;
  p=PageWrite;
  q=PageRead;
  r=SequenceWrite;
  s=SequenceRead;
   GPIO_ResetBits(GPIOE,(GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3));  //可以通过观察LED的状态判断写入和读取的数值相等不
  Bsp_Init();
//单字节的读与写
  IIC_Write_AT24C02_OneByte(200,0x78);
  IIC_Waite_AT24C02_Standby();
  I2C_Data=IIC_Read_AT24C02_OneByte(200);
  if(I2C_Data==0x78)
  {
   GPIO_SetBits(GPIOE,(GPIO_Pin_0));
  }
//页写和连续读取
  IIC_AT24C02_PageWrite(p,2,8);
  IIC_Waite_AT24C02_Standby();
  IIC_AT24C02_PageRead(q,2,8);
  if(PageRead[1]==2)
  {
   GPIO_SetBits(GPIOE,(GPIO_Pin_1));
  }
//连续写与读
  IIC_AT24C02_BufferWrite(r,15,15);
  IIC_Waite_AT24C02_Standby();
  IIC_AT24C02_PageRead(s,15,15);
  WriteSum=SequenceWrite_Checksum();
  ReadSum=SequenceRead_Checksum();
  if(WriteSum==ReadSum)
  {
    GPIO_SetBits(GPIOE,(GPIO_Pin_2));
  }
while(1)
{
   USART_SendData(USART3,I2C_Data);
     while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
     Delay(10000000);
   for(i=0;i
%E6%9C%AA%E5%91%BD%E5%90%8D1.JPG
回复

使用道具 举报

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版