📄 i2c.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 + -