I2C总线是Philips公司提出的一种集成电路IC器件之间相连接的总线协议,其目的是使电子系统(不只限于单片机系统)各个IC器件之间的连线变得容易。因为使用传统的并行总线在IC器件之间连接,往往会使得IC之间连线较多,显得非常复杂。而I2C总线则使IC器件之间只需SDA、SCL两条连线就可以传送数据,因而十分方便。由于I2C在印刷体中不容易
书
关于书的成语关于读书的排比句社区图书漂流公约怎么写关于读书的小报汉书pdf
写(需要上标),所以实际书写时,还常见到IIC、I2C等书写
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
,本文采用IIC的写法,敬请注意。关于IIC总线的知识,请参阅相关书籍,此处不再做进一步介绍。
下面我们用一个使用IIC总线连接器件的例子来简单说明IIC总线的仿真。
例.EEPROM24C02是采用IIC接口的一种常用2Kbit(256×8bit)的存储器。编写程序使用AT89C51的IO口模拟实现IIC总线协议进行通信,并向24C02存储器内从字节0到字节FF写入数字0到FF。
51系列单片机本身没有IIC接口,但一些本身具有IIC接口的单片机往往是高端产品,一方面价格不菲,另一方面我们的系统也没有必要使用之。通常我们就使用软件通过51系列单片机的IO口来模拟实现IIC总线通信。
本例事实上比较简单,但需要对IIC总线时序有较好的理解。源文件如下图所示(采用C51语言编写):
在Keil中编辑好源文件以后,接下来就可以建立工程文件并生成相应的源代码了,然后我们来绘制电路图。
此例的电路图极其简单。只需两个IC,即AT89C51和24C02C,和两个上拉电阻,而且上拉电阻还可以省略。至于连接,就更为简单了。最后得到绘制好的电路图如下图所示:
绘制好电路图,我们就可以将前面刚刚生成的程序源代码装入单片机了,装入以后,下面我们就可以来进行仿真了。
首先点击仿真按钮,系统没有什么反映,只有高低电平变化的颜色。我们要想查看结果,还要用前文中仿真扩展RAM存储器的方法,先点击暂停,然后点击“Debug”菜单下的“I2C Memory Internal Memory – U2”子菜单来打开U2即EEPROM存储器24C02C的内容窗口“I2C Memory Internal Memory – U2”,然后我们就看到了其中的内容,也就是我们仿真程序的结果。如下图所示:
从图中我们能清楚地看到我们的仿真结果,程序完全正确地执行了我们的命令。
当然,如果你过早地点击了暂停按钮,那么你得到的结果可能和上图略有不同,那可能是因为程序尚未执行完毕。此时你可以继续点击运行按钮,或者点击单步按钮来仔细查看程序执行过程中24C02C存储器内容的改变情况。
/*----------------------------------------------------------------
Acess the eeprom--24c04
----------------------------------------------------------------*/
#include
#ifndef INT8U
#define INT8U unsigned char
#endif
#ifndef INT8S
#define INT8S signed char
#endif
#ifndef INT16U
#define INT16U unsigned int
#endif
#define I2C_DELAY; _nop_();_nop_();_nop_();_nop_();_nop_(); // >=4.7uS
//----------------------------------------------------------------
// delay 100us
//----------------------------------------------------------------
void mDelay(INT8U k)
{
INT16U i ;
for(; k>0; k--)
{
for(i=0; i<93; i++)
;
}
}
//----------------------------------------------------------------
//OK
//----------------------------------------------------------------
void I2C_Start(void)
{
SDA = 1;
I2C_DELAY;
SCL = 1;
I2C_DELAY;
SDA = 0;
I2C_DELAY;
I2C_DELAY;
}
//----------------------------------------------------------------
//OK
//----------------------------------------------------------------
void I2C_Stop(void)
{
SDA = 0 ;
I2C_DELAY;
SCL = 1 ;
I2C_DELAY;
SDA = 1 ;
I2C_DELAY;
I2C_DELAY;
}
//----------------------------------------------------------------
//
//----------------------------------------------------------------
void sendAck(void)
{
SCL = 0;
I2C_DELAY;
SDA = 0;
I2C_DELAY;
SCL = 1;
I2C_DELAY;
}
//----------------------------------------------------------------
//
//----------------------------------------------------------------
void sendNoAck(void)
{
SCL = 0;
I2C_DELAY;
SDA = 1;
I2C_DELAY;
SCL = 1;
I2C_DELAY;
}
//----------------------------------------------------------------
// 0 = noACK; 1 = ACK ;
//----------------------------------------------------------------
bit checkAck()
{
bit tempbit;
/*发送完一个字节后检验设备的应答信号*/
SDA = 1;
I2C_DELAY;
SCL = 0;
I2C_DELAY;
tempbit = SDA;
SCL = 1;
I2C_DELAY;
if(tempbit==1)
{
return 0; //noACK
}
else
{
return 1; //ACK
}
}
//----------------------------------------------------------------
//OK
// a positive clock edge clock a bit into the ROM
//----------------------------------------------------------------
void writeByte(INT8U datum)
{
INT8U bitCnt = 0 ;
for(bitCnt=0; bitCnt<8; bitCnt++)
{
SCL = 0 ;
I2C_DELAY;
if ((datum&0x80) == 0x80) //if the MSb is 1
SDA = 1 ;
else
SDA = 0 ;
I2C_DELAY;
SCL = 1 ;
I2C_DELAY;
datum<<=1 ;
}
}
//----------------------------------------------------------------
//OK
//----------------------------------------------------------------
INT8U readByte(void)
{
bit tempbit = 1 ;
INT8U temp = 0 ;
INT8U bitCnt ;
SDA = 1 ; // release the bus,ready to receive byte??????????????
I2C_DELAY;
for(bitCnt=0; bitCnt<8; bitCnt++)
{
SCL = 0; //?????????????????????????huan???????????????
I2C_DELAY;
tempbit = SDA ;
if (tempbit)
temp |= 0x01 ;
else
temp &= 0xfe ;
SCL = 1 ;
I2C_DELAY;
if(bitCnt<7)
temp <<= 1 ;
}
return(temp) ;
}
/*~~~~~~~~~~~~~~~~~~~~~~~ API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*-----------------------------------------------------------------
write some bytes to sequential address
-----------------------------------------------------------------*/
void writeToROM(INT8U datum[], INT8U address, INT8U num)
{
bit tempbit ;
INT8U i ;
INT8U *datum_P ;
datum_P = datum ;
I2C_Start() ;
writeByte(0xa0) ;
tempbit = checkAck();
writeByte(address) ;
tempbit = checkAck();
for(i=0; i
本文档为【51单片机IO口模拟IIC总线协议】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。