单片机驱动—IIC驱动

这篇博客介绍了如何使用STM32通过IIC模拟读写EEPROM的过程,包括IIC的初始化、起始和停止信号、发送数据以及读取数据的实现。此外,还提供了针对BL24CM1A型号EEPROM的读写函数,如`BL24CM1A_Write_Data`和`BL24CM1A_Read_Data`,以及软复位和解锁、锁定功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

.h文件

#ifndef __BSP_IIC_H__
#define __BSP_IIC_H__

#include "stm32f4xx.h"
//#include "i2c_soft.h"

typedef enum
{
  ADDR_WIDE_8  = 0,      //地址为8位宽度
  ADDR_WIDE_16  = 1,     //地址为16位宽度
} IIC_Addr_Type;

typedef struct IIC_Type
{
  //属性
  uint32_t         RCC_SCL_APB2Periph;
  uint32_t         RCC_SDA_APB2Periph;
  GPIO_TypeDef*    GPIOx_SCL;
  GPIO_TypeDef*    GPIOx_SDA;
  uint16_t         SCL_Pin_x;
  uint16_t         SDA_Pin_x;
  //操作
  uint8_t (*IIC_Init)(const struct IIC_Type*);                     //IIC_Init
  uint8_t (*IIC_Start)(const struct IIC_Type*);                    //IIC_Start
  uint8_t (*IIC_Stop)(const struct IIC_Type*);                     //IIC_Stop
  uint8_t (*IIC_Wait_Ack)(const struct IIC_Type*);              //IIC_Wait_ack,返回wait失败或是成功
  uint8_t (*IIC_Ack)(const struct IIC_Type*);                      //IIC_Ack,IIC发送ACK信号
  uint8_t (*IIC_NAck)(const struct IIC_Type*);                     //IIC_NAck,IIC发送NACK信号
  uint8_t (*IIC_Send_Byte)(const struct IIC_Type*,uint8_t);        //IIC_Send_Byte,入口参数为要发送的字节
  uint8_t (*IIC_Read_Byte)(const struct IIC_Type*);     //IIC_Send_Byte
  uint8_t (*delay_us)(uint32_t);                                   //us延时
}IIC_TypeDef;


// #ifndef ADDR_WIDE_8
// #define ADDR_WIDE_8    0
// #endif
// #ifndef ADDR_WIDE_16
// #define ADDR_WIDE_16   1
// #endif

typedef struct EEPROM_Type 
{
  IIC_TypeDef      IIC;
  //属性
  uint32_t         RCC_Lock_APB2Periph; //LOCK引脚时钟
  GPIO_TypeDef*    GPIOx_Lock;
  uint16_t         Lock_Pin_x;

  uint8_t          addr_wide;    //ADDR_WIDE_8 - 8地址宽度;ADDR_WIDE_16 -- 16地址宽度
  uint8_t          device_addr;  //设备地址
  uint16_t         page_size;   //页大小
  uint32_t         max_size;    //最大字节
  uint8_t          (*EEProm_Init)(const struct EEPROM_Type*); //初始化IIC  
  uint8_t          (*EEProm_Soft_Reset)(const struct EEPROM_Type*); //EEPROM软件复位
  uint8_t          (*EEProm_Unlock)(const struct EEPROM_Type*);     //EEPROM解锁
  uint8_t          (*EEProm_Lock)(const struct EEPROM_Type*);     //EEPROM上锁
  uint8_t          (*EEProm_NRead)(const struct EEPROM_Type*, uint32_t, uint8_t*, uint16_t); //EEPROM读取N个字节
  uint8_t          (*EEProm_NWrite)(const struct EEPROM_Type*, uint32_t, uint8_t*, uint16_t); //EEPROM写入N个字节

}EEPROM_Type_t;



void BL24CM1A_Init(void);


uint8_t BL24CM1A_Write_Data(uint32_t WriteAddress, uint8_t* pBuffer, uint16_t length);
uint8_t BL24CM1A_Read_Data(uint32_t readaddress, uint8_t* pBuffer, uint16_t length);


#endif /* __BSP_IIC_*/

.c


#include "bsp_iic.h"
#include "sys_timer.h"
#include "global_includes.h"

#ifndef true
#define true     1
#endif

#ifndef false
#define false    0
#endif
#define IIC_DELAY_us    5
//设置SCL电平
static void IIC_SCL(const struct IIC_Type* IIC_Type_t,int n)
{
  if(n == 1)
  {
    GPIO_SetBits(IIC_Type_t->GPIOx_SCL, IIC_Type_t->SCL_Pin_x);
  }
  else
  {
    GPIO_ResetBits(IIC_Type_t->GPIOx_SCL, IIC_Type_t->SCL_Pin_x);
  }
}

//设置SDA电平
static void IIC_SDA(const struct IIC_Type* IIC_Type_t,int n)
{
  if(n == 1)
  {
    GPIO_SetBits(IIC_Type_t->GPIOx_SDA, IIC_Type_t->SDA_Pin_x);
  }
  else
  {
    GPIO_ResetBits(IIC_Type_t->GPIOx_SDA, IIC_Type_t->SDA_Pin_x);
  }
}
//读取SDA电平
static uint8_t READ_SDA(const struct IIC_Type* IIC_Type_t)
{
  return GPIO_ReadInputDataBit(IIC_Type_t->GPIOx_SDA,IIC_Type_t->SDA_Pin_x);  //读取SDA电平
}


//初始化
static uint8_t IIC_Init_t(const struct IIC_Type* IIC_Type_t)
{
  RCC_AHB1PeriphClockCmd(IIC_Type_t->RCC_SCL_APB2Periph, ENABLE);
  RCC_AHB1PeriphClockCmd(IIC_Type_t->RCC_SDA_APB2Periph, ENABLE);
  GPIO_InitTypeDef  GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  
  GPIO_InitStructure.GPIO_Pin =  IIC_Type_t->SDA_Pin_x;
  GPIO_Init(IIC_Type_t->GPIOx_SDA, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin =  IIC_Type_t->SCL_Pin_x;
  GPIO_Init(IIC_Type_t->GPIOx_SCL, &GPIO_InitStructure);

  IIC_SCL(IIC_Type_t, 1);
  IIC_SDA(IIC_Type_t, 1);
  return true;

}


//起始信号
static uint8_t IIC_Start_t(const struct IIC_Type* IIC_Type_t)
{
  IIC_SDA(IIC_Type_t, 1);
  IIC_SCL(IIC_Type_t, 1);
  IIC_Type_t->delay_us(IIC_DELAY_us);
  if(!READ_SDA(IIC_Type_t))
  {
    return false;  //SDA线为低电平则总线忙,退出
  }
  IIC_SDA(IIC_Type_t, 0);
  IIC_Type_t->delay_us(IIC_DELAY_us);
  if(READ_SDA(IIC_Type_t))
  {
    return false;  //SDA线为高电平则总线出错,退出
  }
  IIC_SCL(IIC_Type_t, 0);
  IIC_Type_t->delay_us(IIC_DELAY_us);
  return true;
}

//停止信号
static uint8_t IIC_Stop_t(const struct IIC_Type* IIC_Type_t)
{
  IIC_SCL(IIC_Type_t, 0);
  IIC_Type_t->delay_us(IIC_DELAY_us);
  IIC_SDA(IIC_Type_t, 0);
  IIC_Type_t->delay_us(IIC_DELAY_us);
  IIC_SCL(IIC_Type_t, 1);
  IIC_Type_t->delay_us(IIC_DELAY_us);
  IIC_SDA(IIC_Type_t, 1);
  IIC_Type_t->delay_us(IIC_DELAY_us);
}

static uint8_t IIC_Wait_Ack_t(const struct IIC_Type* IIC_Type_t)
{
  uint8_t i;

  IIC_SCL(IIC_Type_t, 0);
  IIC_Type_t->delay_us(IIC_DELAY_us);
  IIC_SDA(IIC_Type_t, 1);
  IIC_Type_t->delay_us(IIC_DELAY_us);
  IIC_SCL(IIC_Type_t, 1);
  IIC_Type_t->delay_us(IIC_DELAY_us);
  for(i = 0; i < 30; i++)
  {
    if(READ_SDA(IIC_Type_t))
    {
      IIC_Type_t->delay_us(IIC_DELAY_us);
    }
    else
    {
      break;
    }
  }
  IIC_SCL(IIC_Type_t, 0);
  if(i  >=  30)
  {
    IIC_Type_t->IIC_Stop(IIC_Type_t);
    return false;
  }
  return true;
}

/**************************************************************************
*功能   :IICack
*函数名 : I2C_Ack
*输入   :iic(iic序号)
*返回   :无
**************************************************************************/
static uint8_t IIC_Ack_t(const struct IIC_Type* IIC_Type_t)
{
  IIC_SCL(IIC_Type_t, 0);
  IIC_Type_t->delay_us(IIC_DELAY_us);
  IIC_SDA(IIC_Type_t, 0);
  IIC_Type_t->delay_us(IIC_DELAY_us);
  IIC_SCL(IIC_Type_t, 1);
  IIC_Type_t->delay_us(IIC_DELAY_us);
  IIC_SCL(IIC_Type_t, 0);
  IIC_Type_t->delay_us(IIC_DELAY_us);
}

/**************************************************************************
*功能   :IICnoack
*函数名 : I2C_NoAck
*输入   :iic(iic序号)
*返回   :无
**************************************************************************/
static uint8_t IIC_NAck_t(const struct IIC_Type* IIC_Type_t)
{
  IIC_SCL(IIC_Type_t, 0);
  IIC_Type_t->delay_us(IIC_DELAY_us);
  IIC_SDA(IIC_Type_t, 1);
  IIC_Type_t->delay_us(IIC_DELAY_us);
  IIC_SCL(IIC_Type_t, 1);
  IIC_Type_t->delay_us(IIC_DELAY_us);
  IIC_SCL(IIC_Type_t, 0);
  IIC_Type_t->delay_us(IIC_DELAY_us);
}

static uint8_t IIC_Send_Byte_t(const struct IIC_Type* IIC_Type_t, uint8_t SendByte)
{
  uint8_t i = 8;
  while(i--)
  {
    IIC_SCL(IIC_Type_t, 0);
    IIC_Type_t->delay_us(IIC_DELAY_us);
    if(SendByte & 0x80)
    {
      IIC_SDA(IIC_Type_t, 1);
    }
    else
    {
      IIC_SDA(IIC_Type_t, 0);
    }
    SendByte <<= 1;
    IIC_Type_t->delay_us(IIC_DELAY_us);
    IIC_SCL(IIC_Type_t, 1);
    IIC_Type_t->delay_us(IIC_DELAY_us);
  }
  IIC_SCL(IIC_Type_t, 0);
}

static uint8_t IIC_Read_Byte_t(const struct IIC_Type* IIC_Type_t)
{
  uint8_t i = 8;
  uint8_t ReceiveByte = 0;
  IIC_SDA(IIC_Type_t, 1);
  while(i--)
  {
    ReceiveByte <<= 1;
    IIC_SCL(IIC_Type_t, 0);
    IIC_Type_t->delay_us(IIC_DELAY_us);
    IIC_SCL(IIC_Type_t, 1);
    IIC_Type_t->delay_us(IIC_DELAY_us);
    if(READ_SDA(IIC_Type_t))
    {
      ReceiveByte |= 0x01;
    }
  }
  IIC_SCL(IIC_Type_t, 0);
  return ReceiveByte;
}

static uint8_t EEProm_Unlock_t(const struct EEPROM_Type* EEPROM_Type_t)
{
  GPIO_ResetBits(EEPROM_Type_t->GPIOx_Lock, EEPROM_Type_t->Lock_Pin_x);
}

static uint8_t EEProm_Lock_t(const struct EEPROM_Type* EEPROM_Type_t)
{
  GPIO_SetBits(EEPROM_Type_t->GPIOx_Lock, EEPROM_Type_t->Lock_Pin_x);
}

uint8_t EEProm_Init_t(const struct EEPROM_Type* EEPROM_Type_t)
{
  RCC_AHB1PeriphClockCmd(EEPROM_Type_t->RCC_Lock_APB2Periph, ENABLE);
  GPIO_InitTypeDef  GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  
  GPIO_InitStructure.GPIO_Pin =  EEPROM_Type_t->Lock_Pin_x;
  GPIO_Init(EEPROM_Type_t->GPIOx_Lock, &GPIO_InitStructure);
  EEPROM_Type_t->IIC.IIC_Init(&EEPROM_Type_t->IIC);

  return true;
}

uint8_t EEProm_Soft_Reset_t(const struct EEPROM_Type* EEPROM_Type_t)
{

  IIC_SDA(&EEPROM_Type_t->IIC, 1);
  IIC_SCL(&EEPROM_Type_t->IIC, 1);
  EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);
  IIC_SDA(&EEPROM_Type_t->IIC, 0);
  EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);
  IIC_SCL(&EEPROM_Type_t->IIC, 0);
  for(uint8_t i = 0; i < 9; i++)
  {
    IIC_SCL(&EEPROM_Type_t->IIC, 1);
    EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);
    IIC_SDA(&EEPROM_Type_t->IIC, 1);
    EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);
    IIC_SCL(&EEPROM_Type_t->IIC, 0);
    EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);
  }
  IIC_SDA(&EEPROM_Type_t->IIC, 1);
  IIC_SCL(&EEPROM_Type_t->IIC, 1);
  EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);
  IIC_SDA(&EEPROM_Type_t->IIC, 0);
  EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);
  IIC_SCL(&EEPROM_Type_t->IIC, 0);
  EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);
  IIC_SDA(&EEPROM_Type_t->IIC, 0);
  EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);
  IIC_SCL(&EEPROM_Type_t->IIC, 1);
  EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);
  IIC_SDA(&EEPROM_Type_t->IIC, 1);
  EEPROM_Type_t->IIC.delay_us(IIC_DELAY_us);
}

uint8_t EEProm_Soft_Read(const struct EEPROM_Type* EEPROM_Type_t, uint32_t ReadAddress, uint8_t* pBuffer, uint16_t length)
{
  uint8_t block  = 0;
  uint8_t addr_h = 0;
  uint8_t addr_l = 0;
  EEPROM_Type_t->EEProm_Soft_Reset(EEPROM_Type_t);
  if(!EEPROM_Type_t->IIC.IIC_Start(&EEPROM_Type_t->IIC))
  {
    return false;
  }
  if(EEPROM_Type_t->addr_wide == ADDR_WIDE_16)
  {
    block = ((ReadAddress >> 16) << 1);
  }
  else
  {
    block = ((ReadAddress >> 8) << 1);
  }
  addr_h = (ReadAddress >> 8);
  addr_l = ReadAddress;
  EEPROM_Type_t->IIC.IIC_Send_Byte(&EEPROM_Type_t->IIC, EEPROM_Type_t->device_addr & 0xfe | block); //设置高起始地址+器件地址
  if(!EEPROM_Type_t->IIC.IIC_Wait_Ack(&EEPROM_Type_t->IIC))
  {
    EEPROM_Type_t->IIC.IIC_Stop(&EEPROM_Type_t->IIC);
    return false;
  }
  if(EEPROM_Type_t->addr_wide == ADDR_WIDE_16)
  {
    EEPROM_Type_t->IIC.IIC_Send_Byte(&EEPROM_Type_t->IIC, addr_h);   //设置低起始地址
    EEPROM_Type_t->IIC.IIC_Wait_Ack(&EEPROM_Type_t->IIC);
  }
  EEPROM_Type_t->IIC.IIC_Send_Byte(&EEPROM_Type_t->IIC, addr_l);   //设置低起始地址
  if(!EEPROM_Type_t->IIC.IIC_Wait_Ack(&EEPROM_Type_t->IIC))
  {
    EEPROM_Type_t->IIC.IIC_Stop(&EEPROM_Type_t->IIC);
    return false;
  }
  
  EEPROM_Type_t->EEProm_Soft_Reset(EEPROM_Type_t);
  EEPROM_Type_t->IIC.IIC_Start(&EEPROM_Type_t->IIC);
  EEPROM_Type_t->IIC.IIC_Send_Byte(&EEPROM_Type_t->IIC, EEPROM_Type_t->device_addr | 0x01 | block); //设置高起始地址+器件地址
  if(!EEPROM_Type_t->IIC.IIC_Wait_Ack(&EEPROM_Type_t->IIC))
  {
    EEPROM_Type_t->IIC.IIC_Stop(&EEPROM_Type_t->IIC);
    return false;
  }

  while(length)
  {
    *pBuffer = EEPROM_Type_t->IIC.IIC_Read_Byte(&EEPROM_Type_t->IIC);
    if(length == 1)
    {
      EEPROM_Type_t->IIC.IIC_NAck(&EEPROM_Type_t->IIC);
    }
    else
    {
      EEPROM_Type_t->IIC.IIC_Ack(&EEPROM_Type_t->IIC);
    }
    pBuffer++;
    length--;
  }
  EEPROM_Type_t->IIC.IIC_Stop(&EEPROM_Type_t->IIC);
  return true;
}

uint8_t EEProm_Soft_Write(const struct EEPROM_Type* EEPROM_Type_t, uint32_t WriteAddress, uint8_t* pBuffer, uint16_t length)
{
  uint16_t i;
  uint8_t block  = 0;
  uint8_t addr_h = 0;
  uint8_t addr_l = 0;
  EEPROM_Type_t->EEProm_Soft_Reset(EEPROM_Type_t);
  if(!EEPROM_Type_t->IIC.IIC_Start(&EEPROM_Type_t->IIC))
  {
    return false;
  }
  if(EEPROM_Type_t->addr_wide == ADDR_WIDE_16)
  {
    block = ((WriteAddress >> 16) << 1);
  }
  else
  {
    block = ((WriteAddress >> 8) << 1);
  }
  addr_h = (WriteAddress >> 8);
  addr_l = WriteAddress;
  EEPROM_Type_t->IIC.IIC_Send_Byte(&EEPROM_Type_t->IIC, EEPROM_Type_t->device_addr & 0xfe | block); //设置高起始地址+器件地址
  if(!EEPROM_Type_t->IIC.IIC_Wait_Ack(&EEPROM_Type_t->IIC))
  {
    EEPROM_Type_t->IIC.IIC_Stop(&EEPROM_Type_t->IIC);
    return false;
  }
  if(EEPROM_Type_t->addr_wide == ADDR_WIDE_16)
  {
    EEPROM_Type_t->IIC.IIC_Send_Byte(&EEPROM_Type_t->IIC, addr_h);   //设置低起始地址
    EEPROM_Type_t->IIC.IIC_Wait_Ack(&EEPROM_Type_t->IIC);
  }
  EEPROM_Type_t->IIC.IIC_Send_Byte(&EEPROM_Type_t->IIC, addr_l);   //设置低起始地址
  if(!EEPROM_Type_t->IIC.IIC_Wait_Ack(&EEPROM_Type_t->IIC))
  {
    EEPROM_Type_t->IIC.IIC_Stop(&EEPROM_Type_t->IIC);
    return false;
  }

  for(i = 0; i < length; i++)
  {
    EEPROM_Type_t->IIC.IIC_Send_Byte(&EEPROM_Type_t->IIC, *pBuffer);
    if(!EEPROM_Type_t->IIC.IIC_Wait_Ack(&EEPROM_Type_t->IIC))
    {
      EEPROM_Type_t->IIC.IIC_Stop(&EEPROM_Type_t->IIC);
      return false;
    }
    pBuffer++;
  }
  EEPROM_Type_t->IIC.IIC_Stop(&EEPROM_Type_t->IIC);
  //注意:因为这里要等待EEPROM写完,可以采用查询或延时方式(10ms)
  EEPROM_Type_t->IIC.delay_us(10000);
  return true;
}


uint8_t EEProm_Soft_Write_Data(const struct EEPROM_Type* EEPROM_Type_t, uint32_t WriteAddress, uint8_t* pBuffer, uint16_t length)
{
  uint8_t ret = false;
  if(((WriteAddress + length) > EEPROM_Type_t->max_size || length == 0))
  {
    return false;
  }
  uint32_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;
  Addr  = WriteAddress % EEPROM_Type_t->page_size;      //写入地址是开始页的第几位
  count = EEPROM_Type_t->page_size - Addr;     //在开始页要写入的个数

  EEPROM_Type_t->EEProm_Unlock(EEPROM_Type_t);

  if(count >= length)                                                 // 该页剩余的空间可以容下需要写入的数据量
  {
    if(EEProm_Soft_Write(EEPROM_Type_t, WriteAddress, pBuffer, length)  ==  false) //写一页的数据
    {
      goto ret_return;
    }
    ret = true;
  }
  else
  {
    NumOfPage = (length - count) / EEPROM_Type_t->page_size;
    NumOfSingle = (length - count) % EEPROM_Type_t->page_size;
    if(EEProm_Soft_Write(EEPROM_Type_t, WriteAddress, pBuffer, count) ==  false)
    {
      goto ret_return;
    }
    WriteAddress += count;
    pBuffer += count;
    while(NumOfPage--)                                                      // 写页
    {
      if(EEProm_Soft_Write(EEPROM_Type_t, WriteAddress, pBuffer, EEPROM_Type_t->page_size)  ==  false)
      {
        goto ret_return;
      }
      WriteAddress +=  EEPROM_Type_t->page_size;
      pBuffer += EEPROM_Type_t->page_size;
    }
    if(NumOfSingle != 0)                                                    // 剩下的不足一页
    {
      if(EEProm_Soft_Write(EEPROM_Type_t, WriteAddress, pBuffer, NumOfSingle)  ==  false)
      {
        goto ret_return;
      }
    }
    ret = true;
  }
  ret_return:
  EEPROM_Type_t->EEProm_Lock(EEPROM_Type_t);
  return ret;
}

uint8_t EEProm_NWrite_t(const struct EEPROM_Type* EEPROM_Type_t, uint32_t WriteAddress, uint8_t* pBuffer, uint16_t length)
{
  uint8_t i;
  for(i = 0; i < 3; i++)
  {
    if(EEProm_Soft_Write_Data(EEPROM_Type_t, WriteAddress, pBuffer, length) ==  true)
    {
      return true;
    }
  }
  return false;
}

/****************************************************************************************
*函数名称: IIC_Soft_Read_Data
*
*函数说明: 模拟iic读数据函数
****************************************************************************************/
uint8_t EEProm_NRead_t(const struct EEPROM_Type* EEPROM_Type_t, uint32_t readaddress, uint8_t* pBuffer, uint16_t length)
{
  uint8_t ret = false;
  if(((readaddress + length) > EEPROM_Type_t->max_size || length == 0))
  {
    return false;
  }
  EEPROM_Type_t->EEProm_Unlock(EEPROM_Type_t);
  ret   = EEProm_Soft_Read(EEPROM_Type_t, readaddress, pBuffer, length);
  EEPROM_Type_t->EEProm_Lock(EEPROM_Type_t);
  return ret;
}

uint8_t delay_us_t(uint32_t us)
{
  sys_timer_usDelay(us);
}

EEPROM_Type_t BL24CM1A = 
{
  .IIC = {
    .RCC_SCL_APB2Periph = RCC_AHB1Periph_GPIOB,
    .RCC_SDA_APB2Periph = RCC_AHB1Periph_GPIOB,
    .GPIOx_SCL = GPIOB,
    .GPIOx_SDA = GPIOB,
    .SCL_Pin_x = GPIO_Pin_4,
    .SDA_Pin_x = GPIO_Pin_5,
    .IIC_Init = IIC_Init_t,
    .IIC_Start = IIC_Start_t,
    .IIC_Stop = IIC_Stop_t,
    .IIC_Wait_Ack = IIC_Wait_Ack_t,
    .IIC_Ack = IIC_Ack_t,
    .IIC_NAck = IIC_NAck_t,
    .IIC_Send_Byte = IIC_Send_Byte_t,
    .IIC_Read_Byte = IIC_Read_Byte_t,
    .delay_us = delay_us_t,
  },
  .RCC_Lock_APB2Periph = RCC_AHB1Periph_GPIOB,
  .GPIOx_Lock = GPIOB,
  .Lock_Pin_x = GPIO_Pin_3,
  .addr_wide = ADDR_WIDE_16,
  .device_addr = 0xA0,
  .page_size = 128,
  .max_size = 131072,
  .EEProm_Init = EEProm_Init_t,
  .EEProm_Soft_Reset = EEProm_Soft_Reset_t,
  .EEProm_Unlock = EEProm_Unlock_t,
  .EEProm_Lock = EEProm_Lock_t,
  .EEProm_NRead = EEProm_NRead_t,
  .EEProm_NWrite = EEProm_NWrite_t,
};

void BL24CM1A_Init(void)
{
  BL24CM1A.EEProm_Init(&BL24CM1A);
}

uint8_t BL24CM1A_Write_Data(uint32_t WriteAddress, uint8_t* pBuffer, uint16_t length)
{
  BL24CM1A.EEProm_NWrite(&BL24CM1A, WriteAddress, pBuffer, length);
}

uint8_t BL24CM1A_Read_Data(uint32_t readaddress, uint8_t* pBuffer, uint16_t length)
{
  BL24CM1A.EEProm_NRead(&BL24CM1A, readaddress, pBuffer, length);
}










评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大文梅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值