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

📄 i2c.c

📁 周立功开发板SmartArm2200 I2C中断方式读写板上EEPROM CAT1025,在MDK Keil环境下完成。实现了完整的串口输入输出
💻 C
字号:
/*****************************************************************************************
* 模块名称: I2C通讯模块
* 模块描述: SmartArm2200 I2C操作。CAT1025 EEPROM,实现1到8字节数据的读写操作
* 创建人  : hlb
* 创建日期: 2008-5-4
******************************************************************************************
* 修改人  :
* 修改日期:
*****************************************************************************************/
#include <LPC22xx.h>
#include "Public.h"
#include "I2C.h"

__irq void I2C_isr (void);
/*****************************************************************************************
* 常亮定义 
*****************************************************************************************/
#define I2C_SLAVE_ADDRESS 0xA0
#define I2C_NONE 0
#define I2C_READ 1
#define I2C_WRITE 2

#define I2C_AA (1 << 2)
#define I2C_SI (1 << 3)
#define I2C_STO (1 << 4)
#define I2C_STA (1 << 5)
#define I2C_I2EN (1 << 6)
/*****************************************************************************************
* 定义用于和I2C中断传递信息的全局变量 
*****************************************************************************************/
static volatile U8 I2CAddress;  //I2C器件从地址
static volatile U8 I2CRamAddress; //I2C器件内部子地址
static volatile U8 I2CNum; //I2C要发送活着读取的字节数
static volatile U8 *I2CBuf; //数据缓冲区指针
static volatile U8 ReadBuf[8]; //读缓冲区
static volatile U8 WriteBuf[8]; //写缓冲区
static volatile U8 I2CEnd; //I2C总线结束标志:结束总线是置1
static volatile U8 I2CAddEn; //子地址控制。
               //0--子地址已经处理或者不需要子地址
               //1--读操作
               //2--写操作
/*****************************************************************************************
* 函数名称: void I2C_Init(U32 FI2C) 
* 函数描述: I2C初始化,允许中断,分配中断优先级为1
* 参数描述:FI2C 初始化I2C总线频率,最大值为400K
*****************************************************************************************/
void I2C_Init(U32 FI2C)
{
  U32 tmFI2C;
  tmFI2C = FI2C;
  if (tmFI2C > 400000) tmFI2C = 400000;
  PINSEL0 = (PINSEL0 & 0xFFFFFF0F) | 0x50;  //引脚功能选择
  /* 设置时钟 */
  I2SCLH = (GD.Fpclk / tmFI2C + 1) / 2;
  I2SCLL = (GD.Fpclk / tmFI2C) / 2;
  /* 设为主模式 */
  I2CONCLR = 0x2C;
  I2CONSET = 0x40;
  
  I2CAddress = I2C_SLAVE_ADDRESS;
  
  VICIntSelect = VICIntSelect & (~(1 << 9));  //设置I2C中断为普通中断
  VICIntEnable = VICIntEnable | (1 << 9); //允许I2C中断
  VICVectAddr0 = (U32)I2C_isr;
  VICVectCntl0 = 0x20 | 0x9;
    
}
/*****************************************************************************************
* 函数名称: void I2C_WriteByte(U32 Address, U8 Data) 
* 函数描述: 写一个字节
*****************************************************************************************/
bool I2C_WriteBytes(U8 SlaveAddress, U8 RamAddress, U8 *P, U8 Len)
{
  int i;
  I2CAddress = SlaveAddress & 0xFE;
  I2CRamAddress = RamAddress;
  I2CNum = Len;
  if (I2CNum < 1) I2CNum = 1;
  if (I2CNum > 8) I2CNum = 8;

  for (i = 0; i < I2CNum; i++)
  {
    WriteBuf[i] = *(P+i);
  }
  I2CBuf = WriteBuf;
  
  I2CEnd = 0;   //置位标志
  I2CAddEn = 2; //写操作

  I2CONCLR = 0x2C; //清除STA, SI, AA
  I2CONSET = 0x60; //使能并发送起始标志

  while(I2CEnd == 0);	//等待写入完成
  
  if (I2CEnd == 1)
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}
/*****************************************************************************************
* 函数名称: U8 I2C_ReadByte(U32 Address) 
* 函数描述: 读一个字节
*****************************************************************************************/
bool I2C_ReadBytes(U8 SlaveAddress, U8 RamAddress, U8 *P, U8 Len)
{
  int i, tmI2CNum;

  I2CAddress = SlaveAddress & 0xFE;
  I2CRamAddress = RamAddress;
  I2CNum = Len;
  if (I2CNum < 1) I2CNum = 1;
  if (I2CNum > 8) I2CNum = 8;
  tmI2CNum = I2CNum;
  I2CBuf = ReadBuf;
  I2CEnd = 0;  
  I2CAddEn = I2C_READ; //读操作

  I2CONCLR = I2C_STA | I2C_SI | I2C_AA; //清除STA, SI, AA
  I2CONSET = I2C_I2EN | I2C_STA; //使能并发送起始标志

  while(I2CEnd == 0); //等待读操作完成
  if (I2CEnd == 1)
  {
    for (i = 0; i < tmI2CNum; i++)
    {
      *(P+i) = ReadBuf[i];
    }
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}
/*****************************************************************************************
* 函数名称: void I2C_WriteU8(U32 Address, U8 Data) 
* 函数描述: 写U8
*****************************************************************************************/
void I2C_WriteU8(U32 Address, U8 Data)
{
  static U8 D;
  D = Data;
  I2C_WriteBytes(I2CAddress, Address, &D, sizeof(D));
}
/*****************************************************************************************
* 函数名称: U8 I2C_ReadU8(U32 Address) 
* 函数描述: 读U8
*****************************************************************************************/
U8 I2C_ReadU8(U32 Address)
{
  static U8 D;
  if (I2C_ReadBytes(I2CAddress, Address, &D, sizeof(D)))
    return D;
  else return 0; 
}
/*****************************************************************************************
* 函数名称: void I2C_WriteS8(U32 Address, S8 Data) 
* 函数描述: 写S8
*****************************************************************************************/
void I2C_WriteS8(U32 Address, S8 Data)
{
  static S8 D;
  D = Data;
  I2C_WriteBytes(I2CAddress, Address, (U8 *)&D, sizeof(D));
}
/*****************************************************************************************
* 函数名称: S8 I2C_ReadS8(U32 Address) 
* 函数描述: 读S8
*****************************************************************************************/
S8 I2C_ReadS8(U32 Address)
{
  static S8 D;
  if (I2C_ReadBytes(I2CAddress, Address, (U8 *)&D, sizeof(D)))
    return D;
  else return 0;
}
/*****************************************************************************************
* 函数名称: void I2C_WriteU16(U32 Address, U16 Data) 
* 函数描述: 写U16
*****************************************************************************************/
void I2C_WriteU16(U32 Address, U16 Data)
{
  static U16 D;
  D = Data;
  I2C_WriteBytes(I2CAddress, Address, (U8 *)&D, sizeof(D));
}
/*****************************************************************************************
* 函数名称: U16 I2C_ReadU16(U32 Address) 
* 函数描述: 读U16
*****************************************************************************************/
U16 I2C_ReadU16(U32 Address)
{
  static U16 D;
  if (I2C_ReadBytes(I2CAddress, Address, (U8 *)&D, sizeof(D)))
    return D;
  else return 0;  
}
/*****************************************************************************************
* 函数名称: void I2C_WriteS16(U32 Address, S16 Data) 
* 函数描述: 写S16
*****************************************************************************************/
void I2C_WriteS16(U32 Address, S16 Data)
{
  static S16 D;
  D = Data;
  I2C_WriteBytes(I2CAddress, Address, (U8 *)&D, sizeof(D));    
}
/*****************************************************************************************
* 函数名称: S16 I2C_ReadS16(U32 Address) 
* 函数描述: 读S16
*****************************************************************************************/
S16 I2C_ReadS16(U32 Address)
{
  static S16 D;
  if (I2C_ReadBytes(I2CAddress, Address, (U8 *)&D, sizeof(D)))
    return D;
  else return 0; 
}
/*****************************************************************************************
* 函数名称: void I2C_WriteU32(U32 Address, U32 Data) 
* 函数描述: 写U32
*****************************************************************************************/
void I2C_WriteU32(U32 Address, U32 Data)
{
  static U32 D;
  D = Data;
  I2C_WriteBytes(I2CAddress, Address, (U8 *)&D, sizeof(D));
}
/*****************************************************************************************
* 函数名称: U32 I2C_ReadU32(U32 Address) 
* 函数描述: 读U32
*****************************************************************************************/
U32 I2C_ReadU32(U32 Address)
{
  static U32 D;
  if (I2C_ReadBytes(I2CAddress, Address, (U8 *)&D, sizeof(D)))
    return D;
  else return 0;
}
/*****************************************************************************************
* 函数名称: void I2C_WriteS32(U32 Address, S32 Data) 
* 函数描述: 写S32
*****************************************************************************************/
void I2C_WriteS32(U32 Address, S32 Data)
{
  static S32 D;
  D = Data;
  I2C_WriteBytes(I2CAddress, Address, (U8 *)&D, sizeof(D));  
}
/*****************************************************************************************
* 函数名称: S32 I2C_ReadS32(U32 Address) 
* 函数描述: 读S32
*****************************************************************************************/
S32 I2C_ReadS32(U32 Address)
{
  static S32 D;
  if (I2C_ReadBytes(I2CAddress, Address, (U8 *)&D, sizeof(D)))
    return D;
  else return 0;
}
/*****************************************************************************************
* 函数名称: void I2C_WriteFloat(U32 Address, Float Data) 
* 函数描述: 写float
*****************************************************************************************/
void I2C_WriteFloat(U32 Address, float Data)
{
  UnionFloat UF;
  UF.F = Data;
  I2C_WriteU32(Address, UF.D); 
}
/*****************************************************************************************
* 函数名称: float I2C_ReadFloat(U32 Address) 
* 函数描述: 读float
*****************************************************************************************/
float I2C_ReadFloat(U32 Address)
{
  UnionFloat UF;
  UF.D = I2C_ReadU32(Address);
  return (UF.F);
}
/*****************************************************************************************
* 函数名称: void I2C_isr (void) 
* 函数描述: I2C中断处理程序
*****************************************************************************************/
__irq void I2C_isr (void)
{
  U8 sta;
  
  sta = I2STAT;
  switch(sta)
  {
    case 0x08:
	     I2DAT = I2CAddress;
		 I2CONCLR = I2C_STO | I2C_SI; //清起始标志,中断标志
		 break;
	case 0x10:
	     I2DAT = I2CAddress;
	     I2CONCLR = I2C_STO | I2C_SI;
	     break;
	case 0x18:
	     if (I2CAddEn == I2C_READ)
         {
		   I2DAT = I2CRamAddress;
           I2CONCLR = I2C_STA | I2C_STO | I2C_SI;
		 }
		 else if(I2CAddEn == I2C_WRITE)
         {
		   I2DAT = I2CRamAddress;
		   I2CONCLR = I2C_STA | I2C_STO | I2C_SI;
		 }
		 break; 
	case 0x28:
		 if (I2CAddEn == I2C_READ)
         {
		   I2CAddress = I2CAddress | 0x1;  //改写从地址为读
           I2CONCLR = I2C_STO | I2C_SI;    //
           I2CONSET = I2C_STA;             //发送重复起始条件
		 }
         else
         {       
           if (I2CNum >= 1) //将发送数据字节,接收ACK位
           {
             I2DAT = *I2CBuf++;
             I2CONCLR = I2C_STA | I2C_STO | I2C_SI;
             I2CNum--;
           }
           else
           {
             I2CONCLR = I2C_STA | I2C_SI;
             I2CONSET = I2C_STO;
             I2CEnd = 1;
           }
         }
		 break; 	
	 case 0x20:
	 case 0x30:
	 case 0x38:
	      I2CONCLR = 0x28;
	      I2CEnd = 0xFF;
          break;
	 case 0x40:
	      if(I2CNum == 1) //准备接收数据,返回非ACK位
          {
		    I2CONCLR = I2C_STA | I2C_STO | I2C_SI | I2C_AA;
		  }
          else //准备接收数据,返回ACk位
          {
		    I2CONCLR = I2C_STA | I2C_STO | I2C_SI;
            I2CONSET = I2C_AA;
		  } 
		  break;	
	 case 0x50:
	      *I2CBuf++ = I2DAT;
		  I2CNum--;
		  if(I2CNum == 1)
          {
		    I2CONCLR = I2C_STA | I2C_STO | I2C_SI | I2C_AA;
		  }
          else
          {
		    I2CONCLR = I2C_STA | I2C_STO | I2C_SI;
            I2CONSET = I2C_AA;
		  }
		  break;
	 case 0x58:
	      *I2CBuf++ = I2DAT;
	      I2CONSET = I2C_STO;
          I2CONCLR = I2C_STA | I2C_SI;
	      I2CEnd = 1; 
	      break;
     case 0x48:
	      I2CONCLR = 0x28;
	      I2CEnd = 0xFF; 
	      break;
	 default:
		  break;
    }
	
	VICVectAddr = 0x00;
}

⌨️ 快捷键说明

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