网站首页
IC库存
IC展台
电子资讯
技术资料
PDF文档
我的博客
IC72论坛
ic72 logo
资料首页最新产品 技术参数 电路图 设计应用 解决方案 代理商查询 IC替换 IC厂商 电子辞典
关键字: 技术文章 PDF资料 IC价格 电路图 代理商查询 IC替换 IC厂商 电子辞典

51单片机 普通IO口模拟IIC(I2C)接口通讯的程序代码

下面我们用一个使用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; i93; 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; bitCnt8; bitCnt++)

{

SCL = 0 ;

I2C_DELAY;

if ((datum0x80) == 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; bitCnt8; bitCnt++)

{

SCL = 0; //?????????????????????????huan???????????????

I2C_DELAY;

tempbit = SDA ;

if (tempbit)

temp |= 0x01 ;

else

temp = 0xfe ;

SCL = 1 ;

I2C_DELAY;

if(bitCnt7)

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

{

writeByte(*(datum_P+i)) ;

if(!checkAck())

{

I2C_Stop() ;

mDelay(100) ;

}

}

I2C_Stop() ;

}

/*-----------------------------------------------------------------

read some bytes from ROM`s sequential address

-----------------------------------------------------------------*/

void readFromROM(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();

I2C_Start() ;

writeByte(0xa1) ;

tempbit = checkAck();

for(i=0; i

{

*(datum_P+i) = readByte() ;

if(i!=num-1)

{

sendAck() ;

}

else

{

sendNoAck() ;

}

}

I2C_Stop() ;

}

/*-----------------------------------------------------------------

wirte one byte to ROM --random write

-----------------------------------------------------------------*/

void writeOneByte(INT8U addr, INT8U datum)

{

bit tempbit ;

/*write a byte to mem*/

I2C_Start();

writeByte(0xa0);

tempbit = checkAck();

writeByte(addr); /*address*/

tempbit = checkAck();

writeByte(datum); /*the data*/

tempbit = checkAck();

I2C_Stop();

mDelay(100) ;

}

/*-----------------------------------------------------------------

read one byte from rom --random read

-----------------------------------------------------------------*/

INT8U readOneByte(INT8U addr)

{

bit tempbit = 1;

INT8U mydata;

/*read a byte from mem*/

I2C_Start();

writeByte(0xa0);

tempbit = checkAck();

writeByte(addr); /*address*/

tempbit = checkAck();

I2C_Start();

writeByte(0xa1);

tempbit = checkAck();

mydata = readByte();

tempbit = checkAck();

return (mydata) ;

I2C_Stop();

}

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门搜索:TLM825GF PS-410-HGOEMCC PSF2408 UL24RA-15 TLM626SA N060-002 2920120 TRAVELER3USB 2866349 BSV17-16 RS-1215 PDUMV20 TLM815NS BT05-F250H-03 TLP1008TEL TLP712 1301380020 6SPDX PS240406 2838254 UL17CB-15 2320351 2839211 02C1001JF TLP1210SATG
COPYRIGHT:(1998-2010) IC72 达普IC芯片交易网
客户服务:service@IC72.com 库存上载:IC72@IC72.com
(北京)联系方式: 在线QQ咨询:点击这里给我发消息 联系电话:010-82614113 传真:010-82614123
京ICP备06008810号-21 京公网安备 11010802032910 号 企业资质