⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 storage.c

📁 通用IIC通讯程序,可以实现多个字节的读写
💻 C
字号:
//**************************************************************************
//  COPYRIGNT 2008.10.17
//  ALL RIGHT REAERVE
//  DESCRIPTION: upd78f0513 POWER METER
//  FILE: STORAGE.C
//  AUTHOR:  WYP
//  VERSION: 1.0
//**************************************************************************

#include "includes.h"

#define SlaveAddr	0xA0
#define p_size 		16
#define p_size_hex	15

void I2cStart(void)
{
  IIC_SDA_OUT;
  IIC_SDA = 1;
  DelayUs(2);
  IIC_SCL_OUT;
  IIC_SCL = 1;
  DelayUs(2);
  IIC_SDA = 0;
  DelayUs(4);
  IIC_SCL = 0;
  DelayUs(4);
}

void I2cStop(void)
{
  uint8_t t = 10;
  IIC_SDA_OUT;
  IIC_SDA = 0;
  DelayUs(4);
  IIC_SCL = 1;
  DelayUs(4);
  IIC_SDA = 1;
  while(--t != 0);
}

uint8_t I2cGetAck(void)
{
  uint8_t ACK;
  IIC_SDA_IN;
  IIC_SCL = 1;
  DelayUs(4);
  if(IIC_SDA)
  {
    ACK = 1;
  }
  else
  {
    ACK = 0;
  }
  IIC_SCL = 0;
  DelayUs(4);
  return(ACK);
}

void I2cPutAck(void)
{
  IIC_SDA_OUT;
  IIC_SDA = 1;
  IIC_SCL = 1;
  DelayUs(4);
  IIC_SCL = 0;
  DelayUs(4);
}

void I2cPutNoAck(void)
{
  IIC_SDA_OUT;
  IIC_SDA = 0;
  IIC_SCL = 1;
  DelayUs(4);
  IIC_SCL = 0;
  DelayUs(4);
}

void SendOneByte(uint8_t dat)
{
  uint8_t i;
  IIC_SDA_OUT;
  for(i=0;i<8;i++)
  {
    if(dat & 0x80)
    {
      IIC_SDA = 1;
    }
    else
    {
      IIC_SDA = 0;
    }
    dat <<= 1;
    IIC_SCL = 1;
    DelayUs(4);
    IIC_SCL = 0;
    DelayUs(4);
  }
}

uint8_t RecvOneByte(void)
{
  uint8_t i;
  uint8_t dat = 0;
  IIC_SDA_IN;
  for(i=0;i<8;i++)
  {
    IIC_SCL = 1;
    DelayUs(4);
    dat <<= 1;
    if(IIC_SDA)
    {
      dat++;
    }
    IIC_SCL = 0;
    DelayUs(4);
  }
  return(dat);
}

bool I2cOneByteWrite(uint16_t SubAddr,uint8_t dat)
{
  I2cStart();
  SendOneByte ((SlaveAddr | (((uint8_t)(SubAddr>>8))<<1)));
  if(I2cGetAck())
  {
    I2cStop();
    return 1;
  }
  SendOneByte((uint8_t)SubAddr);
  if(I2cGetAck ())
  {
    I2cStop();
    return 1;
  }
  SendOneByte(dat);
  if(I2cGetAck())
  {
    I2cStop();
    return 1;
  }
  I2cStop();
  DelayMs(10);
  return 0;
}

bool I2cSequenceWrite(uint16_t SubAddr,uint8_t Size,uint8_t *dat)
{
  uint8_t i,PageCnt,SizeCnt;
  
  ClrWtd();
  DI();
  IICWPENOUT0;
  if(Size == 0)
    return 1;
  PageCnt = (Size+(0x000F&(uint8_t)(SubAddr))-1)/p_size + 1;
  ClrWtd();
  do
  {
    I2cStart();
    SendOneByte ((SlaveAddr | (((uint8_t)(SubAddr>>8))<<1)));
    if(I2cGetAck ())
    {
      I2cStop();
      return 1;
    }
    SendOneByte((uint8_t)SubAddr);
    if(I2cGetAck())
    {
      I2cStop();
      return 1;
    }
    
    if (SubAddr&p_size_hex)
    {	
      if((Size+((uint8_t)(SubAddr)&p_size_hex))>p_size)
        SizeCnt = p_size-((uint8_t)(SubAddr)&p_size_hex);                     
      else 
        SizeCnt = Size;
      SubAddr=(SubAddr/16)<<4;
    }
    else
    {
      if (Size<p_size)
        SizeCnt = Size;
      else
        SizeCnt = p_size;
    }
    Size -= SizeCnt;
    for(i=0;i<SizeCnt;i++)
    {
      SendOneByte(*dat++);
      if(I2cGetAck())
      {
        I2cStop();
        return 1;
      }
    }
    I2cStop();
    DelayMs(10);
    
    SubAddr >>= 4;
    SubAddr++;
    SubAddr <<= 4;
    PageCnt--;
  }while(PageCnt>0);
  IICWPENOUT1;
  EI();
  return 0;
}

bool I2cSequenceRead(uint16_t SubAddr,uint8_t Size,uint8_t *dat)
{
  ClrWtd();
  if(Size == 0)
    return 1;
  I2cStart();
  SendOneByte ((SlaveAddr | (((uint8_t)(SubAddr>>8))<<1)));
  if(I2cGetAck ())
  {
    I2cStop();
    return 1;
  }
  SendOneByte ((uint8_t)SubAddr);
  if(I2cGetAck ())
  {
    I2cStop();
    return 1;
  }
  
  I2cStart();
  SendOneByte ((SlaveAddr | (((uint8_t)(SubAddr>>8))<<1)) | 0x01);
  if(I2cGetAck ())
  {
    I2cStop();
    return 1;
  }
  
  for(;;)
  {
    *dat++ = RecvOneByte ();
    if(--Size == 0)
    {
      I2cPutAck ();
      break;
    }
    I2cPutNoAck ();
  }
  I2cStop();
  return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -