i2c汇编语言,I2C模拟程序----汇编语言格式

模块名:I2C总线驱动    型号:I2C

功能描述:

此模块包括发送数据及接收数据,应答位发送,并提供了几个直接面对器件的操作函数,能很

方便的与用户程序进行连接并扩展。

需要注意的是,函数是采用延时方法产生 SCL 脉冲,对高晶振频率要做一定的修改!!

在写E2PROM的时候一定要延时!!!

说明:

1us机器周期,晶振频率要小于12MHz

返回 1 则操作成功,返回 0 则操作失败。

sla 为器件从地址,suba 为器件子地址。

*************************************************************************************/

#include "AT89X52.h"

#include

#define   _Nop() _nop_()    //定义空指令

sbit   SDA = P1^3;     //模拟I2C数据传输位

sbit   SCL = P1^2;     //模拟I2C时钟控制位

bit   bdata I2C_Ack;    //应答标志位

/************************************ I2C_Start ************************************

函数名:void I2C_Start()

入口:

出口:

功能描述:启动I2C总线,即发送I2C初始条件

调用函数:

全局变量:

创建者:陈曦    日期:2005-6-15

修改者:           日期:

**********************************************************************************/

void I2C_Start()

{

SDA = 1;      //发送起始条件的数据信号

_Nop();

SCL = 1;

_Nop();       //起始条件建立时间大于4.7us,延时

_Nop();

_Nop();

_Nop();

_Nop();

SDA = 0;      //发送起始信号

_Nop();       //起始条件建立时间大于4us,延时

_Nop();

_Nop();

_Nop();

_Nop();

SCL = 0;      //钳住I2C总线准备发送或接收数据

_Nop();

_Nop();

}

/************************************ I2C_Stop ************************************

函数名:void I2C_Stop()

入口:

出口:

功能描述:结束I2C总线,即发送I2C结束条件

调用函数:

全局变量:

创建者:陈曦   日期:2005-6-15

修改者:    日期:

**********************************************************************************/

void I2C_Stop()

{

SDA = 0;      //发送结束条件的数据信号

_Nop();

SCL = 1;      //发送结束条件的时钟信号

_Nop();       //结束条件建立时间大于4us,延时

_Nop();

_Nop();

_Nop();

_Nop();

SDA = 1;      //发送I2C总线结束信号

_Nop();

_Nop();

_Nop();

_Nop();

}

/************************************ I2C_CheckAck ************************************

函数名:bit I2C_CheckAck(void)

入口:

出口:0(无应答),1(有应答)

功能描述:

检验I2C总线应答信号,有应答则返回1,否则返回0,超时值取255

调用函数:void I2C_Stop()

全局变量:

创建者:陈曦   日期:2005-6-15

修改者:          日期:

**********************************************************************************/

bit I2C_CheckAck(void)

{

uchar errtime = 255;     // 因故障接收方无 Ack,超时值为255

SDA = 1;

_Nop();

_Nop();

_Nop();

SCL = 1;

_Nop();         //时钟电平周期大于 4 us

_Nop();

_Nop();

_Nop();

_Nop();

while(SDA)

{

errtime--;

if(errtime==0)

{

I2C_Stop();

return(0);

}

}

SCL = 0;

_Nop();

return(1);

}

/************************************ I2C_SendB ************************************

函数名:void I2C_SendB(uchar c)

入口:uchar 型数据

出口:

功能描述:

字节数据传送函数,将数据 c 发送出去,可以是地址,也可以是数据,发完后等待应答,并对

此状态位进行操作

调用函数:bit I2C_CheckAck()

全局变量:I2C_Ack

创建者:陈曦   日期:2005-6-15

修改者:          日期:

**********************************************************************************/

void I2C_SendB(uchar c)

{

uchar BitCnt;

for (BitCnt=0; BitCnt<8; BitCnt++)   //要传送的数据长度为8位

{

if((c

SDA = 1;

}

else

{

SDA = 0;

}

_Nop();

_Nop();

SCL = 1;        //置时钟线为高通知被控器开始接收数据位

_Nop();         //保证时钟高电平周期大于 4us

_Nop();

_Nop();

_Nop();

_Nop();

SCL = 0;

}

_Nop();

_Nop();

I2C_Ack = I2C_CheckAck();     //检验应答信号

_Nop();

_Nop();

}

/************************************ I2C_RcvB ************************************

函数名:uchar I2C_RcvB()

入口:

出口:uchar型数据

功能描述:

接收从器件传来的数据,并判断总线错误(不发应答信号),收完后需要调用应答函数。

调用函数:

全局变量:

创建者:陈曦   日期:2005-6-15

修改者:          日期:

**********************************************************************************/

uchar I2C_RcvB()

{

uchar retc;

uchar BitCnt;         //位

retc = 0;

SDA = 1;          //置数据总线为输入方式

for(BitCnt=0;BitCnt<8;BitCnt++)

{

_Nop();

SCL = 0;         //置时钟线为低准备接收数据位

_Nop();          //时钟低电平周期大于4.7us

_Nop();

_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);

}

/************************************ I2C_Ackn ************************************

函数名:void I2C_Ackn(bit a)

入口:0或1

出口:

功能描述:主控制器进行应答信号(可以是应答或非应答信号)

调用函数:

全局变量:

创建者:陈曦   日期:2005-6-15

修改者:          日期:

**********************************************************************************/

void I2C_Ackn(bit a)

{

if(a==0)      //在此发送应答或非应答信号

{

SDA = 0;

}

else

{

SDA = 1;

}

_Nop();

_Nop();

_Nop();

SCL = 1;

_Nop();       //时钟电平周期大于 4 us

_Nop();

_Nop();

_Nop();

_Nop();

SCL = 0;      //清时钟线钳住I2C总线以便继续接收

_Nop();

_Nop();

}

/******************************** I2C_ISendB ************************************

函数名:bit I2C_ISendB(uchar sla, uchar suba, uchar c)

入口:从器件地址 sla,子地址 suba, 发送字节 c

出口:0(操作有误),1(操作成功)

功能描述:从启动总线到发送地址、数据,结束总线的全过程,

如果返回1,表示操作成功,否则操作有误。

调用函数:I2C_Start(),I2C_SendB(uchar c),I2C_Stop()

全局变量:I2C_Ack

创建者:陈曦   日期:2005-6-15

修改者:           日期:

**********************************************************************************/

bit I2C_ISendB(uchar sla, uchar suba, uchar c)

{

I2C_Start();     //启动总线

I2C_SendB(sla);     //发送器件地址

if(!I2C_Ack)

{

return(0);

}

I2C_SendB(suba);    //发送器件子地址

if(!I2C_Ack)

{

return(0);

}

I2C_SendB(c);     //发送数据

if(!I2C_Ack)

{

return(0);

}

I2C_Stop();      //结束总线

return(1);

}

/********************************** I2C_IRcvB ************************************

函数名:bit I2C_IRcvB(uchar sla, uchar suba, uchar *c)

入口:从器件地址 sla, 子地址 suba, 收到的数据在 c

出口:1(操作成功),0(操作有误)

功能描述:从启动总线到发送地址、读数据,结束总线的全过程。

调用函数: I2CS_tart(),

I2C_SendB(uchar c),

I2C_RcvB(),

I2C_Ackn(bit a),

I2C_Stop()

全局变量:I2C_Ack

创建者:陈曦   日期:2005-5-15

修改者:          日期:

**********************************************************************************/

bit I2C_IRcvB(uchar sla, uchar suba, uchar *c)

{

I2C_Start();      //启动总线

I2C_SendB(sla);

if(!I2C_Ack)

{

return(0);

}

I2C_SendB(suba);     //发送器件子地址

if(!I2C_Ack)

{

return(0);

}

I2C_Start();      //重复起始条件

I2C_SendB(sla+1);     //发送读操作的地址

if(!I2C_Ack)

{

return(0);

}

*c = I2C_RcvB();     //读取数据

I2C_Ackn(1);      //发送非应答位

I2C_Stop();       //结束总线

return(1);

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值