📄 iic.c
字号:
#include <REG952.H>
#define uchar unsigned char
#define uint unsigned int
//以下为I2C操作时所需要的变量
volatile uchar I2C_sla; // 从机地址(即器件地址)
volatile uchar I2C_suba; // 子地址
volatile uchar *I2C_buf; // 数据缓冲区指针 (读操作时会被更改)
volatile uchar I2C_num; // 操作数据个数 (会被更改)
volatile uchar I2C_end; // 操作结束标志,为1时表示操作结束,为0xFF时表示操作失败 (会被设置)
volatile uchar I2C_suba_en; // 子地址使能控制,读操作时请设置为1,写操作时请设置为2 (会被更改)
//--------------------------------
//功能:IIC主机初始化
//--------------------------------
void IIC_Init()
{
// EI2C=1; //开I2C中断
CRSEL=0;
I2SCLL=15;
I2SCLH=15; //12Mhz下,IIC总线速率为120kbit/s
I2EN=1; //初始化为主机
STA=0; // 设置为主机,并启动总线
STO=0;
SI=0;
}
//--------------------------------
/****************************************************************************
* 名称:IRQ_I2C()
* 功能:I2C中断,通过判断I2C状态字进行相应的操作。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void IRQ_I2C(void) //interrupt 7
{
uchar sta;
sta = I2STAT; // 读出I2C状态字
switch(sta)
{
case 0x08: // 己发送起始条件
if(1==I2C_suba_en)
I2DAT = I2C_sla&0xFE; // 指定子地址读时,先写入地址
else I2DAT = I2C_sla; // 否则直接发送从机地址
STO=0;
SI=0; // SI=0
break;
case 0x10:
STO=0;
SI=0;
break;
case 0x20:
case 0x18:
if(0==I2C_suba_en) // 无子地址,则直接发送数据
{
if(I2C_num>0)
{
I2DAT = *I2C_buf++;
SI=0;
I2C_num--;
}
else
{
I2CON = I2CON|0x10; // 无数据发送,结束总线
SI=0;
I2C_end = 1; // 设置总线操作结束标志
}
break;
}
if(1==I2C_suba_en) // 发送子地址
{
I2DAT = I2C_suba;
SI=0;
}
if(2==I2C_suba_en)
{
I2DAT = I2C_suba;
STA=0;
STO=0;
SI=0;
I2C_suba_en = 0; // 子地址己处理
}
break;
case 0x28:
case 0x30:
if(0==I2C_suba_en) // 无子地址,则直接发送数据
{
if(I2C_num>0)
{
I2DAT = *I2C_buf++;
STA=0;
STO=0;
SI=0;
I2C_num--;
}
else
{
STA=0; // 无数据发送,结束总线
STO=1;
SI=0;
I2C_end = 1;
}
break;
}
if(1==I2C_suba_en) // 若是指定地址读,则重新启动总线
{
I2CON = I2CON|0x20;
I2CON = I2CON&~0x08;
I2C_suba_en = 0; // 子地址己处理
}
break;
case 0x38:
STA=0;
STO=0;
SI=0;
break;
default: break;
}
}
//延时子程序
void Delay(uint data DelayTime)
{
uint data j;
for(;DelayTime>0;DelayTime--)
for(j=0;j<125;j++)
{}
}
/****************************************************************************
* 名称:ISendStr()
* 功能:向有子地址器件发送多字节数据。
* 入口参数:sla 器件从机地址
* suba 器件子地址
* s 数据发送缓冲区指针
* no 发送数据个数
* 出口参数:返回值为0时表示出错,为1时表示操作正确。
* 说明:使用前要初始化好I2C引脚功能和I2C中断,并已使能I2C主模式
****************************************************************************/
void ISendStr(uchar sla, uchar suba, uchar *s, uchar no)
{ /* 参数设置 */
I2C_sla = sla; // 写操作的器件地址
I2C_suba = suba; // 子地址
I2C_buf = s;
I2C_num = no;
I2C_suba_en = 2; // 有子地址写
I2C_end = 0;
STA=1;
Delay(1); //延时1ms,等待从机完成IIC初始化
while(0==I2C_end)
{
if(SI==1)
IRQ_I2C();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -