📄 i2cint.c
字号:
#define I2CMODEL
#include "config.h"
#include "I2CINT.h"
/* 定义用于和I2C中断传递信息的全局变量 */
volatile INT8U I2C_sla; /* I2C器件从地址 */
volatile INT32U I2C_suba; /* I2C器件内部子地址 */
volatile INT8U I2C_suba_num; /* I2C子地址字节数 */
volatile INT8U *I2C_buf; /* 数据缓冲区指针 */
volatile INT32U I2C_num; /* 要读取/写入的数据个数 */
volatile INT8U I2C_end; /* I2C总线结束标志:结束总线是置1 */
volatile INT8U I2C_suba_en; /* 子地址控制。
0--子地址已经处理或者不需要子地址
1--读取操作
2--写操作
*/
/*******************************************************************************************************
** 函数名称: void I2C_Init(INT32U fi2c)
** 功能描述: I2C初始化
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块:
** 作 者: 崔敬军
** 日 期: 2007年05月20日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void I2C_Init(INT32U fi2c)
{
if(fi2c>400000)
{
fi2c = 400000;
}
PINSEL0 = (PINSEL0&0xFFFFFF0F) | 0x50; // 设置I2C控制口有效
I2SCLH = (Fpclk/fi2c + 1) / 2; // 设置I2C时钟为fi2c
I2SCLL = (Fpclk/fi2c) / 2;
I2CONCLR = 0x2C;
I2CONSET = 0x40; // 使能主I2C
}
/*******************************************************************************************************
** 函数名称: void I2c_Exception(void)
** 功能描述: I2C中断,通过判断I2C状态字进行相应的操作
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块:
** 作 者: 崔敬军
** 日 期: 2007年05月20日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void I2c_Exception(void)
{
INT8U sta;
sta = I2STAT; // 读出I2C状态字
switch(sta)
{ case 0x08: // 己发送起始条件
if(1==I2C_suba_en) I2DAT = I2C_sla&0xFE; // 指定子地址读时,先写入地址
else I2DAT = I2C_sla; // 否则直接发送从机地址
I2CONCLR = 0x28; // SI=0
break;
case 0x10:
I2DAT = I2C_sla; // 重启动总线后,发送从地址
I2CONCLR = 0x28; // SI=0
break;
case 0x18: // 已发送SLA+W,并已接收应答
if(0==I2C_suba_en) // 无子地址,则直接发送数据
{ if(I2C_num>0)
{ I2DAT = *I2C_buf++;
I2CONCLR = 0x28;
I2C_num--;
}
else
{ I2CONSET = 0x10; // 无数据发送,结束总线
I2CONCLR = 0x28;
I2C_end = 1; // 设置总线操作结束标志
}
break;
}
if(1==I2C_suba_en) // 发送子地址
{ I2DAT = I2C_suba;
I2CONCLR = 0x28;
}
if(2==I2C_suba_en)
{ I2DAT = I2C_suba;
I2CONCLR = 0x28;
I2C_suba_en = 0; // 子地址己处理
}
break;
case 0x28: // 已发送I2C数据,并接收到应答
if(0==I2C_suba_en) // 无子地址,则直接发送数据
{ if(I2C_num>0)
{ I2DAT = *I2C_buf++;
I2CONCLR = 0x28;
I2C_num--;
}
else
{ I2CONSET = 0x10; // 无数据发送,结束总线
I2CONCLR = 0x28;
I2C_end = 1;
}
break;
}
if(1==I2C_suba_en) // 若是指定地址读,则重新启动总线
{ I2CONSET = 0x20;
I2CONCLR = 0x08;
I2C_suba_en = 0; // 子地址己处理
}
break;
case 0x20:
case 0x30:
case 0x38:
I2CONCLR = 0x28; // 总线进入不可寻址从模式
I2C_end = 0xFF; // 总线出错,设置标志
break;
case 0x40: // 己发送SLA+R,并已接收到应答
if(1==I2C_num) // 最后一字节,接收数据后发送非应答信号
{ I2CONCLR = 0x2C; // AA=0,接收到数据后产生非应答
}
else // 接收数据并发送应答信号
{ I2CONSET = 0x04; // AA=1,接收到数据后产生应答
I2CONCLR = 0x28;
}
break;
case 0x50:
*I2C_buf++ = I2DAT; // 读取数据
I2C_num--;
if(1==I2C_num)
{ I2CONCLR = 0x2C; // AA=0,接收到数据后产生非应答
}
else
{ I2CONSET = 0x04; // AA=1,接收到数据后产生应答
I2CONCLR = 0x28;
}
break;
case 0x58:
*I2C_buf++ = I2DAT; // 读取最后一字节数据
I2CONSET = 0x10; // 结束总线
I2CONCLR = 0x28;
I2C_end = 1;
break;
case 0x48:
I2CONCLR = 0x28; // 总线进入不可寻址从模式
I2C_end = 0xFF;
break;
default:
break;
}
VICVectAddr = 0x00; // 中断处理结束
}
/*******************************************************************************************************
** 函数名称: INT8S ISendByte(INT8U sla, INT8U dat)
** 功能描述: 向无子地址器件发送一字节数据(使用前要初始化好I2C引脚功能和I2C中断,并已使能I2C主模式)
** 输 入: sla--器件地址
dat--要发送的数据
** 输 出: 返回值为0时表示出错,为1时表示操作正确
** 全局变量: 无
** 调用模块:
** 作 者: 崔敬军
** 日 期: 2007年05月20日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
INT8S ISendByte(INT8U sla, INT8U dat)
{ /* 参数设置 */
INT8S ret;
I2C_sla = sla; // 写操作的器件地址
I2C_buf = &dat; // 待发送的数据
I2C_num = 1; // 发送1字节数据
I2C_suba_en = 0; // 无子地址
I2C_end = 0;
I2CONCLR = 0x2C;
I2CONSET = 0x60; // 设置为主机,并启动总线
while(0==I2C_end)
{
;//OSTimeDly(1);
}
if(1==I2C_end)
{
ret = 0;
}
else
{
ret = -1;
}
return ret;
}
/*******************************************************************************************************
** 函数名称: INT8S ISendStr(INT8U sla, INT8U suba, INT8U *s, INT32U no)
** 功能描述: 向有子地址器件发送多字节数据
** 输 入: sla--器件从机地址
suba-器件子地址
s----数据发送缓冲区指针
no---发送数据个数
** 输 出: 返回值为0时表示出错,为1时表示操作正确
** 全局变量: 无
** 调用模块:
** 作 者: 崔敬军
** 日 期: 2007年05月20日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
INT8S ISendStr(INT8U sla, INT8U suba, INT8U *s, INT32U no)
{ /* 参数设置 */
INT8S ret;
I2C_sla = sla; // 写操作的器件地址
I2C_suba = suba; // 子地址
I2C_buf = s;
I2C_num = no;
I2C_suba_en = 2; // 有子地址写
I2C_end = 0;
I2CONCLR = 0x2C;
I2CONSET = 0x60; // 设置为主机,并启动总线
while(0==I2C_end)
{
;//OSTimeDly(1);
}
if(1==I2C_end)
{
ret = 0;
}
else
{
ret = -1;
}
return ret;
}
/*******************************************************************************************************
** 函数名称: INT8S IRcvByte(INT8U sla, INT8U *dat)
** 功能描述: 向无子地址器件读取一字节数据
** 输 入: sla---器件地址 dat---接收数据的变量指针
** 输 出: 返回值为-1时表示操作出错,为0时表示操作正确
** 全局变量: 无
** 调用模块:
** 作 者: 崔敬军
** 日 期: 2007年05月20日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
INT8S IRcvByte(INT8U sla, INT8U *dat)
{ /* 参数设置 */
INT8S ret;
I2C_sla = sla+1; // 读操作的器件地址
I2C_buf = dat;
I2C_num = 1;
I2C_suba_en = 0; // 无子地址
I2C_end = 0;
I2CONCLR = 0x2C;
I2CONSET = 0x60; // 设置为主机,并启动总线
while(0==I2C_end)
{
//;OSTimeDly(1);
};
if(1==I2C_end)
{
ret = 0;
}
else
{
ret = -1;
}
return ret;
}
/*******************************************************************************************************
** 函数名称: INT8S IRcvStr(INT8U sla, INT8U suba, INT8U *s, INT32U no)
** 功能描述: 向无子地址器件读取一字节数据
** 输 入: sla---器件地址 suba---器件子地址 s---数据接收缓冲区指针 no---读取数据个数
** 输 出: 返回值为-1时表示操作出错,为0时表示操作正确
** 全局变量: 无
** 调用模块:
** 作 者: 崔敬军
** 日 期: 2007年05月20日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
INT8S IRcvStr(INT8U sla, INT8U suba, INT8U *s, INT32U no)
{
INT8S ret;
if(0==no)
{
ret = -1;
}
/* 参数设置 */
I2C_sla = sla+1; // 读操作的器件地址
I2C_suba = suba;
I2C_buf = s;
I2C_num = no;
I2C_suba_en = 1; // 有子地址读
I2C_end = 0;
I2CONCLR = 0x2C;
I2CONSET = 0x60; // 设置为主机,并启动总线
while(0==I2C_end)
{
//;OSTimeDly(1);
}
if(1==I2C_end)
{
ret = 0;
}
else
{
ret = -1;
}
return ret;
}
/*******************************************************************************************************
** 函数名称: INT8S IIRcvStr(INT8U sla, INT8U *s, INT32U no)
** 功能描述: 向无子地址器件读取一字节数据
** 输 入: sla---器件地址 suba---器件子地址 s---数据接收缓冲区指针 no---读取数据个数
** 输 出: 返回值为-1时表示操作出错,为0时表示操作正确
** 全局变量: 无
** 调用模块:
** 作 者: 崔敬军
** 日 期: 2007年05月20日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
INT8S IIRcvStr(INT8U sla, INT8U *s, INT32U no)
{
INT8S ret;
if(0==no)
{
ret = -1;
}
/* 参数设置 */
I2C_sla = sla+1; // 读操作的器件地址
I2C_buf = s;
I2C_num = no;
I2C_suba_en = 0; // 有子地址读
I2C_end = 0;
I2CONCLR = 0x2C;
I2CONSET = 0x60; // 设置为主机,并启动总线
while(0==I2C_end)
{
;//OSTimeDly(1);
}
if(1==I2C_end)
{
ret = 0;
}
else
{
ret = -1;
}
return ret;
}
/*********************************************************************************************************
** End Of File
**********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -