/********************************************************************
MCS-51单片机模拟I2C软件包(V1.1)
文件名:VI2C_C51.C
相关文件:VI2C_C51.H,VI2C_C51.LIB
功能说明:本模拟I2C软件包包含了I2C操作的底层函数,如发送数据及接收
数据,应答位发送,并提供了几个直接面对器件
注意:函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作 一定的
修改....(本软件包是1us的操作函数,它很方便的与用户程
序连接并扩展..... 机器周期,即晶振频率要小于12MHZ)
总线时序符合I2C标准模式,100Kbit/S。
********************************************************************/
#include <INIF.h>
bit ack; //应答标志位
/*******************************************************************
起动总线函数
函数原型: void Start_I2c();
功能: 启动I2C总线,即发送I2C起始条件.
********************************************************************/
void Start_I2c()
{
SDA=1; //发送起始条件的数据信号
_Nop();
SCL=1;
_Nop(); //起始条件建立时间大于4.7us,延时
_Nop();
_Nop();
_Nop();
_Nop();
SDA=0; //发送起始信号
_Nop(); // 起始条件锁定时间大于4μs
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0; //钳住I2C总线,准备发送或接收数据
_Nop();
_Nop();
}
/*******************************************************************
结束总线函数
函数原型: void Stop_I2c();
功能: 结束I2C总线,即发送I2C结束条件.
********************************************************************/
void Stop_I2c()
{
SDA=0; //发送结束条件的数据信号
_Nop(); //发送结束条件的时钟信号
SCL=1; //结束条件建立时间大于4μs
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA=1; //发送I2C总线结束信号
_Nop();
_Nop();
_Nop();
_Nop();
}
/*******************************************************************
字节数据发送函数
函数原型: void SendByte(uchar c);
功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
此状态位进行操作.(不应答或非应答都使ack=0)
发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
********************************************************************/
void SendByte(uchar c)
{
uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++) //要传送的数据长度为8位
{
if((c<<BitCnt)&0x80)SDA=1; //判断发送位
else SDA=0;
_Nop();
SCL=1; //置时钟线为高,通知被控器开始接收数据位
_Nop();
_Nop(); //保证时钟高电平周期大于4μs
_Nop();
_Nop();
_Nop();
SCL=0;
}
_Nop();
_Nop();
SDA=1; //8位发送完后释放数据线,准备接收应答位
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
if(SDA==1)ack=0;
else ack=1; //判断是否接收到应答信号
SCL=0;
_Nop();
_Nop();
}
/*******************************************************************
字节数据接收函数
函数原型: uchar RcvByte();
功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
发完后请用应答函数应答从机。
********************************************************************/
uchar RcvByte()
{
uchar retc;
uchar BitCnt;
retc=0;
SDA=1; //置数据线为输入方式
for(BitCnt=0;BitCnt<8;BitCnt++)
{
_Nop();
SCL=0; //置时钟线为低,准备接收数据位
_Nop();
_Nop(); //时钟低电平周期大于4.7μs
_Nop();
_Nop();
_Nop();
SCL=1; //置时钟线为高使数据线上数据有效
_Nop();
_Nop();
retc=retc<<1;
if(SDA==1)retc=retc+1; //读数据位,接收的数据位放入retc中
_Nop();
_Nop();
}
SCL=0;
_Nop();
_Nop();
return(retc);
}
/********************************************************************
应答子函数
函数原型: void Ack_I2c(bit a);
功能: 主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
********************************************************************/
void Ack_I2c(bit a)
{
if(a==0)SDA=0; //在此发出应答或非应答信号
else SDA=1;
_Nop();
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop(); //时钟低电平周期大于4μs
_Nop();
_Nop();
_Nop();
SCL=0; //清时钟线,钳住I2C总线以便继续接收
_Nop();
_Nop();
}
/*******************************************************************
用户接口函数
*******************************************************************/
/*******************************************************************
向有子地址器件发送多字节数据函数
函数原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
********************************************************************/
bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
Start_I2c(); //启动总线
SendByte(sla); //发送器件地址
if(ack==0)return(0);
SendByte(suba); //发送器件子地址
if(ack==0)return(0);
for(i=0;i<no;i++)
{
SendByte(*s); //发送数据
if(ack==0)return(0);
s++;
}
Stop_I2c(); //结束总线
return(1);
}
/*******************************************************************
向有子地址器件读取多字节数据函数
函数原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能: 从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
********************************************************************/
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
Start_I2c(); //启动总线
SendByte(sla); //发送器件地址
if(ack==0)return(0);
SendByte(suba); //发送器件子地址
if(ack==0)return(0);
Start_I2c(); //重新启动总线
SendByte(sla+1);
if(ack==0)return(0);
for(i=0;i<no-1;i++)
{
*s=RcvByte(); //发送数据
Ack_I2c(0); //发送就答位
s++;
}
*s=RcvByte();
Ack_I2c(1); //发送非应位
Stop_I2c(); //结束总线
return(1);
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
IIC.rar (96个子文件)
IIC
PCF8574
main.OBJ 6KB
I2C.LST 7KB
I2C.c 4KB
PCF8574 21KB
PCF8574.uvopt 56KB
LCD1602.LST 3KB
PCF8574.plg 219B
main.c 1KB
I2C.OBJ 9KB
main.LST 3KB
PCF8574.M51 14KB
PCF8574.uvproj 13KB
LCD1602.c 1KB
PCF8574.opt.bak 1KB
PCF8574.lnp 56B
LCD1602.OBJ 8KB
LCD1602.h 189B
INIF.h 646B
PCF8574.hex 2KB
I2C.h 117B
PCF8574.Uv2.bak 2KB
LM75
main.OBJ 7KB
UART.c 436B
LED.c 1KB
I2C.LST 10KB
LM75.hex 5KB
I2C.c 6KB
LCD1602.LST 3KB
main.c 2KB
UART.LST 2KB
I2C.OBJ 12KB
LM75.lnp 53B
LM75 25KB
uart.h 68B
LM75.M51 19KB
main.LST 4KB
LED.LST 3KB
LCD1602.c 1KB
UART.OBJ 4KB
LCD1602.OBJ 8KB
LM75.Uv2 2KB
LM75.Opt 1KB
LCD1602.h 189B
INIF.h 724B
LM75.plg 618B
LED.OBJ 4KB
I2C.h 118B
AT24C01
main.OBJ 6KB
LED.c 1KB
I2C.LST 11KB
I2C.c 7KB
LCD1602.LST 3KB
main.c 2KB
uart.LST 3KB
I2C.OBJ 13KB
uart.h 76B
I2C.lnp 52B
main.LST 3KB
LED.LST 3KB
LCD1602.c 1KB
I2C 25KB
I2C.Opt 1KB
uart.c 1KB
uart.OBJ 3KB
LCD1602.OBJ 8KB
I2C.plg 188B
I2C.hex 2KB
LCD1602.h 189B
I2C.Uv2 2KB
INIF.h 643B
I2C.M51 18KB
LED.OBJ 4KB
I2C.h 171B
FCF8563
main.OBJ 8KB
PCF8563.plg 636B
I2C.LST 11KB
I2C.c 7KB
PCF8563.lnp 56B
LCD1602.LST 3KB
main.c 2KB
uart.LST 3KB
I2C.OBJ 13KB
uart.h 84B
main.LST 4KB
PCF8563 26KB
PCF8563.Uv2 2KB
LCD1602.c 1KB
PCF8563.hex 4KB
uart.c 1KB
uart.OBJ 3KB
LCD1602.OBJ 8KB
PCF8563.M51 19KB
LCD1602.h 189B
INIF.h 660B
I2C.h 406B
PCF8563.Opt 1KB
共 96 条
- 1
资源评论
局外狗
- 粉丝: 64
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功