⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 51

📁 siglechip_development 单片机开发资料
💻
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0036)http://go.163.com/~czlyzhj/51i2c.htm -->
<HTML><HEAD><TITLE>51单片机模拟I2C总线的C语言实现</TITLE>
<META content="text/html; charset=gb_2312-80" http-equiv=Content-Type>
<META content="MSHTML 5.00.2314.1000" name=GENERATOR>
<META content="D:\MICROSOFT OFFICE\OFFICE\html.dot" name=Template></HEAD>
<BODY background=51单片机模拟I2C总线的C语言实现.files/404.htm link=#0000ff vLink=#800080><B>
<P align=center><FONT face=System,黑体 lang=ZH-CN size=5>51</FONT><FONT face=宋体 
lang=ZH-CN size=5>单片机模拟</FONT><FONT face=System,黑体 lang=ZH-CN 
size=5>I<SUP>2</SUP>C</FONT><FONT face=宋体 lang=ZH-CN size=5>总线的</FONT><FONT 
face=System,黑体 lang=ZH-CN size=5>C</FONT><FONT face=宋体 lang=ZH-CN 
size=5>语言实现</FONT></P></B>
<OL><FONT face=宋体 lang=ZH-CN size=5><B></B></FONT><FONT face=宋体 lang=ZH-CN>
  <P align=justify>
  <LI>电路原理图 
  <P></P>
  <P align=justify> </P><IMG height=193 src="51单片机模拟I2C总线的C语言实现.files/i2c.gif" 
  width=186> 
  <P align=justify>EEPROM为ATMEL公司的AT24C01A。单片机为ATMEL公司的AT89C51。</P>
  <P align=justify></P>
  <LI>软件说明 
  <P></P></FONT></LI></OL><FONT face=宋体 lang=ZH-CN>
<DIR>
<P align=justify>C语言为Franklin C V3.2。将源程序另存为testi2c.c,用命令</P>
<P align=justify>C51 testi2c.c</P>
<P align=justify>L51 TESTI2C.OBJ</P>
<P align=justify>OHS51 TESTI2C</P>
<P align=justify>编译,连接,得到TESTI2C.HEX文件,即可由编程器读入并进行写片,实验。</P>
<P align=justify>3.源程序</P></DIR></FONT><FONT face=宋体 lang=ZH-CN size=3>
<P align=justify>#include &lt;reg51.h&gt;</P>
<P align=justify>#include &lt;intrins.h&gt; </P>
<P align=justify>#define uchar unsigned char</P>
<P align=justify>#define uint unsigned int</P>
<P align=justify>#define AddWr 0xa0 /*器件地址选择及写标志*/</P>
<P align=justify>#define AddRd 0xa1 /*器件地址选择及读标志*/</P>
<P align=justify>#define Hidden 0x0e /*显示器的消隐码*/</P>
<P align=justify>/*有关全局变量*/</P>
<P align=justify>sbit Sda= P3^7; /*串行数据*/</P>
<P align=justify>sbit Scl= P3^6; /*串行时钟*/</P>
<P align=justify>sbit WP= P3^5; /*硬件写保护*/</P>
<P align=justify>void mDelay(uchar j)</P>
<P align=justify>{ uint i;<BR>for(;j&gt;0;j--)<BR>{ 
for(i=0;i&lt;125;i--)<BR>{;}<BR>}<BR>}</P>
<P align=justify>/*发送起始条件*/</P>
<P align=justify>void Start(void) /*起始条件*/</P>
<P align=justify>{</P>
<P align=justify>Sda=1;</P>
<P align=justify>Scl=1;</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>Sda=0;</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>}</P>
<P align=justify>void Stop(void) /*停止条件*/</P>
<P align=justify>{</P>
<P align=justify>Sda=0;</P>
<P align=justify>Scl=1;</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>Sda=1;</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>}</P>
<P align=justify>void Ack(void) /*应答位*/</P>
<P align=justify>{</P>
<P align=justify>Sda=0;</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>Scl=1;</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>Scl=0;</P>
<P align=justify>}</P>
<P align=justify>void NoAck(void) /*反向应答位*/</P>
<P align=justify>{</P>
<P align=justify>Sda=1;</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>Scl=1;</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>Scl=0;</P>
<P align=justify>}</P>
<P align=justify>void Send(uchar Data) /*发送数据子程序,Data为要求发送的数据*/</P>
<P align=justify>{</P>
<P align=justify>uchar BitCounter=8; /*位数控制*/</P>
<P align=justify>uchar temp; /*中间变量控制*/</P>
<P align=justify>do</P>
<P align=justify>{</P>
<P align=justify>temp=Data;</P>
<P align=justify>Scl=0;</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>if((temp&amp;0x80)==0x80)/* 如果最高位是1*/</P>
<P align=justify>Sda=1;</P>
<P align=justify>else</P>
<P align=justify>Sda=0;</P>
<P align=justify>Scl=1;</P>
<P align=justify>temp=Data&lt;&lt;1; /*RLC*/</P>
<P align=justify>Data=temp;</P>
<P align=justify>BitCounter--;</P>
<P align=justify>}while(BitCounter);</P>
<P align=justify>Scl=0;</P>
<P align=justify>}</P>
<P align=justify></P>
<P align=justify>uchar Read(void) /*读一个字节的数据,并返回该字节值*/</P>
<P align=justify>{</P>
<P align=justify>uchar temp=0;</P>
<P align=justify>uchar temp1=0;</P>
<P align=justify>uchar BitCounter=8;</P>
<P align=justify>Sda=1;</P>
<P align=justify>do{</P>
<P align=justify>Scl=0;</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>Scl=1;</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>_nop_ ();</P>
<P align=justify>if(Sda) /*如果Sda=1;*/</P>
<P align=justify>temp=temp|0x01; /*temp的最低位置1*/</P>
<P align=justify>else</P>
<P align=justify>temp=temp&amp;0xfe; /*否则temp的最低位清0*/</P>
<P align=justify>if(BitCounter-1)</P>
<P align=justify>{ temp1=temp&lt;&lt;1;</P>
<P align=justify>temp=temp1;</P>
<P align=justify>}</P>
<P align=justify>BitCounter--;</P>
<P align=justify>}while(BitCounter);</P>
<P align=justify>return(temp);</P>
<P align=justify>}</P>
<P align=justify></P>
<P align=justify>void WrToROM(uchar Data[],uchar Address,uchar Num)</P>
<P align=justify>{</P>
<P align=justify>uchar i;</P>
<P align=justify>uchar *PData;</P>
<P align=justify>PData=Data;</P>
<P align=justify>for(i=0;i&lt;Num;i++)</P>
<P align=justify>{</P>
<P align=justify>Start(); /*发送启动信号*/</P>
<P align=justify>Send(0xa0); /*发送SLA+W*/</P>
<P align=justify>Ack();</P>
<P align=justify>Send(Address+i); /*发送地址*/</P>
<P align=justify>Ack();</P>
<P align=justify>Send(*(PData+i));</P>
<P align=justify>Ack();</P>
<P align=justify>Stop();</P>
<P align=justify>mDelay(20);</P>
<P align=justify>}</P>
<P align=justify>}</P>
<P align=justify>void RdFromROM(uchar Data[],uchar Address,uchar Num)</P>
<P align=justify>{</P>
<P align=justify>uchar i;</P>
<P align=justify>uchar *PData;</P>
<P align=justify>PData=Data;</P>
<P align=justify>for(i=0;i&lt;Num;i++)</P>
<P align=justify>{</P>
<P align=justify>Start();</P>
<P align=justify>Send(0xa0);</P>
<P align=justify>Ack();</P>
<P align=justify>Send(Address+i);</P>
<P align=justify>Ack();</P>
<P align=justify>Start();</P>
<P align=justify>Send(0xa1);</P>
<P align=justify>Ack();</P>
<P align=justify>*(PData+i)=Read();</P>
<P align=justify>Scl=0;</P>
<P align=justify>NoAck();</P>
<P align=justify>Stop();</P>
<P align=justify>}</P>
<P align=justify>}</P>
<P align=justify>void main()</P>
<P align=justify>{</P>
<P align=justify>uchar Number[4]={1,2,3,4};</P>
<P align=justify>WP= 1;</P>
<P align=justify>WrToROM(Number,4,4); /*将初始化后的数值写入EEPROM*/</P>
<P align=justify>mDelay(20);</P>
<P align=justify>Number[0]=0;</P>
<P align=justify>Number[1]=0;</P>
<P align=justify>Number[2]=0;</P>
<P align=justify>Number[3]=0; /*将数组中的值清掉,以验证读出的数是否正确*/</P>
<P align=justify>RdFromROM(Number,4,4);</P>
<P align=justify>}</P></FONT><FONT face=宋体 lang=ZH-CN>
<P 
align=justify>问题:本程序中未采用块读写的方法,显得有点‘笨’,这是由于项目原因,现项目已完成,程序已写好,短时不会修改,也不会花上一定的精力去做,虽然理论上已很成熟,就这样写一下,未必不对,但与我的本栏目要求不符,所以就未做上去,如果以后我做了,将再补上。 </P>
<P align=center><A href="http://go.163.com/~czlyzhj/fxzl.htm"><IMG border=0 
height=55 src="51单片机模拟I2C总线的C语言实现.files/back1.gif" width=43></A></P>
<P align=justify> </P></FONT></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -