微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 51单片机—再论IIC—软件通用包(汇编、c语言)—03

51单片机—再论IIC—软件通用包(汇编、c语言)—03

时间:11-25 来源:互联网 点击:
感觉心有不甘,呵呵,小小整理一下。

我们知道51单片机中具有IIC总线接口的毕竟是少数(其实我就不知道那款~~)如果是是不带IIC总线的单片机,并不必扩展IIC总线接口,只是需要通过软件模拟,这无疑会给IIC总线的应用提供更广泛的空间。通常大多数的单片机应用系统中只有一个CPU,这种单主系统如果采用IIC总线技术,则总线上只有单片机对IIC总线从器件的访问,没有总线的竞争问题。这是后只需要模拟主发送和主接收时序。基于上述考虑,(这才是重点,呵呵),提供在这种使用情况下的时序模拟软件,使IIC总线的使用不受单片机必须带有IIC总线接口的限制。

下面的9个例子可以作为一个软件包,这个软件放入单片机系统的程序程序存储器中,以便用来调用。

1、IIC总线典型信号时序及模拟子程序(其实上一篇已经介绍过了,不过我这里有点补充,顺便小小介绍一下吧)

IIC总线上数据传送时,有起始位,停止位,应答位,非应答位等信号。按照典型IIC总线传送速率的要求,如图:



对于IIC总线的典型信号,可以用指令操作来模拟其时序过程。

若89C51单片机的系统时钟为12MHz,相信的单周期指令为1us,则起始位(START)、停止位(STOP)、发送应答位(MACK)、发送非应答位(MNACK)的5个模拟子程序如下:

1)启动IIC总线子程序START(先是汇编,然后是c语言的)

;--------------------------------------------------------
;发开始信号子程序
START:SETBSDA
SETBSCL;起始条件建立大于4.7us
NOP
NOP
NOP
NOP
NOP
CLRSDA;起始条件锁定大于4us
NOP
NOP
NOP
NOP
NOP
CLRSCL;钳住总线,准备好发送数据
NOP
RET

//----------------------------------------------------------
//开始信号函数
void IIC_start()
{
sda=1;
_nop_();
scl=1;//开始信号建立时间大于4.7us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
sda=0; //开始信号锁定大于4us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
scl=0;//钳住IIC总线,准备发送或者接收数据
_nop_();
_nop_();
}

2)停止IIC总线程序STOP(先是汇编,后是c语言)

;--------------------------------------------------------
;发结束信号子程序
STOP:CLRSDA
NOP
SETBSCL;结束总时间大于4us
NOP
NOP
NOP
NOP
NOP
SETBSDA
NOP ;保证一个终止信号和其实信号的空闲时间大于4.7us
NOP
NOP
NOP
NOP
RET

//---------------------------------------------------------------
//结束信号函数
void IIC_stop()
{
sda=0;
_nop_();
scl=1; //结束时间大于4us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
sda=1;//保证一个终止信号和其实信号的空闲时间大于4.7us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}

3)主控器向被控器发送应答位信号子程序MACK(由于这个信号和发送非应答信号在c语言里写在了一起,所以最后写c语言的程序)

;--------------------------------------------------------------
;发送应答信号子程序
MACK:
CLRSDA
NOP
NOP
SETBSCL
NOP;保持数据时间,既SCL为高,时间大于4.7us
NOP
NOP
NOP
NOP
CLRSCL
NOP
NOP
RET

4)主控器向被控器发送非应答新号子程序MNACK

;------------------------------------------------------------
;发送非应答信号子程序
MNACK:
SETBSDA
NOP
NOP
SETBSCL
NOP;保持数据时间,既SCL为高,时间大于4.7us
NOP
NOP
NOP
NOP
CLRSCL
NOP
NOP
RET

然后就是上两个的c的程序:

//---------------------------------------------------------------------
//主控器件向被控器件发送应答函数
void IIC_ack_send(bit a)
{
if(a==0) //发应答信号
sda=0;
else
sda=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
scl=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
scl=0;
_nop_();
_nop_();
}

5)主控器件检查被控器件发送来的应答位

;---------------------------------------------------------------
;检测应答位子程序
;返回值ACK=1时表示应达
CACK:
SETBSDA
NOP
NOP
SETBSCL
CLRACK
NOP
NOP
MOVC,SDA
JCCEND
SETBACK ;应答位置1,既返回应答位为1
CEND:
NOP
CLRSCL
NOP

//-----------------------------------------------------------------
//主控器件接收应答函数
void IIC_ack_acc()
{
_nop_();
_nop_();
sda=1;//8位数据发送完后,准备接收数据
_nop_();
_nop_();
scl=1;
_nop_();
_nop_();
_nop_();
if(sda==1)
ack=0;
else ack=1;//接收到应答位,ack为1,否则置0
scl=0;
_nop_();
_nop_();
}

在使用上述的子程序时,如果单片机不是12MHz,自己调整啊~~哈哈

2、IIC总线数据传送的模拟子程序

从IIC总线的数据操作中可以看出,出了起始位、停止位、发送应答函数、发送

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top