STM32_IIC 24C02

STM32_IIC 24C02

第一步引脚配置 ,IIC配置

#include "24C02.h"
#include "stm32f10x.h" 
#define I2C_Speed              800000
#define I2C1_SLAVE_ADDRESS7    0xA0
#define I2C_PageSize           8
#define EEPROM_ADDRESS 0xA0
void I2C_Configuration(void)
{
    I2C_InitTypeDef  I2C_InitStructure;
    GPIO_InitTypeDef  GPIO_InitStructure; 

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);//I2C时钟使能
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_AFIO, ENABLE);//GPIO时钟使能
    // PB6,7 SCL and SDA */
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;//复用开漏
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    I2C_DeInit(I2C1); //初始化IIC
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; //设置为IIC模式
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; //I2C工作于快速模式
    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;//时钟设置为40K
    I2C_Cmd(I2C1, ENABLE); //使能I2C1
    I2C_Init(I2C1, &I2C_InitStructure);//以上参数初始化结构体
}

这里写图片描述
第二部 IIC的通讯
/************************************************
** 函数名: I2C_EE_ByteWrite
** 功能描述: 一个字节写入EEPROM
** 输入参数:
pBuffer 要写入数据数组的指针
WriteAddr 24C02 中要写入数据的首地址
*************************************************/
void I2C_EE_ByteWrite(uint8_t* pBuffer,uint8_t WriteAddr)
{
/产生I2Cx传输 START 条件/
I2C_GenerateSTART(I2C1, ENABLE);
//设置主机模式
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
/I2C设备 发送方向/
I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);
//等待选着过程完成
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
/* 发送数据到EEPROM内部地址
I2C_SendData(I2C1, WriteAddr);
//等待字节完成
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* //通过外设 发送地址·*/
I2C_SendData(I2C1, *pBuffer);
//等待字节发送完成
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

/产生I2Cx STOP条件/
I2C_GenerateSTOP(I2C1, ENABLE);
}
IIC中断说明
这里写图片描述
I2C所有函数说明
这里写图片描述
这里写图片描述

I2C_CheckEvent 事件所有值如下
这里写图片描述

/**********************************************************
** 函数名: II2C_EE_BufferRead
** 功能描述:将EEPROM的数据读入指针缓冲组中
** 输入参数: 
            pBuffer 指向要读出数据的数组指针
            ReadAddr:24c02 要读出数据的首地址
            NumByteToRead:读出的字节数
** 输出参数:无
***********************************************************/
void I2C_EE_BufferRead(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead)
{  

   I2C_EE_WaitEepromStandbyState();//等待EEPROM等待命令
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
  /*产生起始条件 */
  I2C_GenerateSTART(I2C1, ENABLE);
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
  //向指定的从I2C设备传送地址字 选择发送方向
  I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  I2C_Cmd(I2C1, ENABLE);
  //EEPROM数据起始地址
  I2C_SendData(I2C1, ReadAddr);  
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  /*再次发送起始条件*/  
  I2C_GenerateSTART(I2C1, ENABLE);
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

  /*向指定I2c设备传送地址字 选择接受方向*/
  I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Receiver);
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

  /*直到读取完成*/
  while(NumByteToRead)  
  {
    if(NumByteToRead == 1)
    {
      /*失能 I2C应答功能*/
      I2C_AcknowledgeConfig(I2C1, DISABLE);

      /*产生停止条件*/
      I2C_GenerateSTOP(I2C1, ENABLE);
    }
    //检查是否接受到数据
    if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))  
    {      
      /*读取通过I2CX 最近接收的数据 */
      *pBuffer = I2C_ReceiveData(I2C1);
      pBuffer++; 

      NumByteToRead--;        
    }   
  }
    //使能指定 I2C的应答功能
    I2C_AcknowledgeConfig(I2C1, ENABLE);
}

I2C在读取完 最后一个字节 发送NACk 释放总线
这里写图片描述

/**********************************************************
** 函数名:I2C_EE_WaitEepromStandbyState
** 功能描述:等待EEPROM为待命状态
** 输入参数:无
** 输出参数:无
***********************************************************/
void I2C_EE_WaitEepromStandbyState(void)      
{
  __IO uint16_t SR1_Tmp = 0;

  do
  {
    /*产生起始条件*/
    I2C_GenerateSTART(I2C1, ENABLE);
    /*读取指定I2C寄存器 I2C_SR1 并返回值*/
    SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1);
    /*向指定的从I2C设备传送地址字,选择发送方向*/
    I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);
  }while(!(I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0x0002));//直到地址发送结束

  //清除I2X应答错误标志位
  I2C_ClearFlag(I2C1, I2C_FLAG_AF);

  /*产生停止条件*/    
  I2C_GenerateSTOP(I2C1, ENABLE);  
}

I2C_SR1寄存器的第二位
这里写图片描述

I2C_Direction
这里写图片描述

/**********************************************************
** 函数名: I2C_EE_BufferWrite
** 功能描述: 可跨页在任意地址开始写数据
** 输入参数: 
            pBuffer: 指向写入数据的指针
            WriteAddr:24C02要写入数据的首地址
            NumByteToWrite:写入的字节数
** 输出参数:无
***********************************************************/
void I2C_EE_BufferWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite)
{
  uint8_t 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(Addr == 0) 
  {
    /*如果数据小于一页*/
    if(NumOfPage == 0) 
    {
      I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);//写少于一页的数据
      I2C_EE_WaitEepromStandbyState(); //德昂带EEPROM待命的状态
    }
    /*如果数据大于一页 */
    else  
    {
      while(NumOfPage--)//要写入的页数
      {
        I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize); //写一页的数据
        I2C_EE_WaitEepromStandbyState(); //等待EEPROM
        WriteAddr +=  I2C_PageSize; //地址加8
        pBuffer += I2C_PageSize;//数据加8
      }

      if(NumOfSingle!=0)  //剩余数据小于一页
      {
        I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);//写小于一页的数据
        I2C_EE_WaitEepromStandbyState(); //
      }
    }
  }
  /*如果不是页 开始的 */
  else 
  {
    /* 如果小于一页 */
    if(NumOfPage== 0) 
    {
      I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle); //写小于一页的数据
      I2C_EE_WaitEepromStandbyState();
    }
    /* 如果大于等于一页*/
    else
    {
      NumByteToWrite -= count;
      NumOfPage =  NumByteToWrite / I2C_PageSize;//重新计算写入页数
      NumOfSingle = NumByteToWrite % I2C_PageSize;//计算不足一页的个数   

      if(count != 0)
      {  
        I2C_EE_PageWrite(pBuffer, WriteAddr, count); //将开始的空间写满
        I2C_EE_WaitEepromStandbyState();
        WriteAddr += count;
        pBuffer += count;
      } 

      while(NumOfPage--) //要写的页数
      {
        I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
        I2C_EE_WaitEepromStandbyState();
        WriteAddr +=  I2C_PageSize;
        pBuffer += I2C_PageSize;  
      }
      if(NumOfSingle != 0)//剩余数据小于一页
      {
        I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);//写小于一页的数据
        I2C_EE_WaitEepromStandbyState(); //
      }
    }
  }  
}

/**********************************************************
** 函数名: I2C_EE_PageWrite
** 功能描述: 写小于一页的数据EEPROM
** 输入参数: 
            pBuffer 指向要写入数据数组的指针
            WriteAddr: 24C02要写入数据的首地址
            NumByteToWrite:要写入字节数
** 输入参数: 无
***********************************************************/
void I2C_EE_PageWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint8_t NumByteToWrite)
{
  /*等待总线空闲*/
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
  /*产生I2X START条件*/
  I2C_GenerateSTART(I2C1, ENABLE); 
  //设置主机模式
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));  
  /*向指定I2C设备发送地址 选择发送方向*/
  I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);
  //等待完成
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));  

  /*通过 外设I2C 发送地址 */    
  I2C_SendData(I2C1, WriteAddr);  
  //等待完成
  while(! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  /*知道写完数据*/
  while(NumByteToWrite--)  
  {
    /* 发送当前字节数据*/
    I2C_SendData(I2C1, *pBuffer); 
    /* 指针指向下一个要写的数据 */
    pBuffer++; 
    //等待字节写完
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  }

  /* 停止条件*/
  I2C_GenerateSTOP(I2C1, ENABLE);
}

main 主函数

int main(void)
{
    u8 my_buf[20];
    SystemInit(); //系统初始化 
    Usart_Configuration();//窗口初始化
    I2C_Configuration();//I2C初始化 
    delay_ms(10);
    //在地址10 写入指定长度数据
    I2C_EE_BufferWrite("系统初始化时钟配置",10,18);   
    I2C_EE_BufferRead(my_buf,10,18);    //读取地址10处的数据
    printf(my_buf);//用串口打印读取到的数据
    while(1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值