论坛风格切换切换到宽版
  • 5139阅读
  • 11回复

51单片机模拟I2C总线的C语言实现 [复制链接]

上一主题 下一主题
离线BA3CE
 
发帖
1652
只看楼主 倒序阅读 0楼 发表于: 2002-11-25
51单片机模拟i2c总线的c语言实现




eeprom为atmel公司的at24c01a。单片机为atmel公司的at89c51。


软件说明

c语言为franklin c v3.2。将源程序另存为testi2c.c,用命令

c51 testi2c.c

l51 testi2c.obj

ohs51 testi2c

编译,连接,得到testi2c.hex文件,即可由编程器读入并进行写片,实验。

3.源程序

#include <reg51.h>

#include <intrins.h>

#define uchar unsigned char

#define uint unsigned int

#define addwr 0xa0 /*器件地址选择及写标志*/

#define addrd 0xa1 /*器件地址选择及读标志*/

#define hidden 0x0e /*显示器的消隐码*/

/*有关全局变量*/

sbit sda= p3^7; /*串行数据*/

sbit scl= p3^6; /*串行时钟*/

sbit wp= p3^5; /*硬件写保护*/

void mdelay(uchar j)

{ uint i;
for(;j>0;j--)
{ for(i=0;i<125;i--)
{;}
}
}

/*发送起始条件*/

void start(void) /*起始条件*/

{

sda=1;

scl=1;

_nop_ ();

_nop_ ();

_nop_ ();

_nop_ ();

sda=0;

_nop_ ();

_nop_ ();

_nop_ ();

_nop_ ();

}

void stop(void) /*停止条件*/

{

sda=0;

scl=1;

_nop_ ();

_nop_ ();

_nop_ ();

_nop_ ();

sda=1;

_nop_ ();

_nop_ ();

_nop_ ();

_nop_ ();

}

void ack(void) /*应答位*/

{

sda=0;

_nop_ ();

_nop_ ();

_nop_ ();

_nop_ ();

scl=1;

_nop_ ();

_nop_ ();

_nop_ ();

_nop_ ();

scl=0;

}

void noack(void) /*反向应答位*/

{

sda=1;

_nop_ ();

_nop_ ();

_nop_ ();

_nop_ ();

scl=1;

_nop_ ();

_nop_ ();

_nop_ ();

_nop_ ();

scl=0;

}

void send(uchar data) /*发送数据子程序,data为要求发送的数据*/

{

uchar bitcounter=8; /*位数控制*/

uchar temp; /*中间变量控制*/

do

{

temp=data;

scl=0;

_nop_ ();

_nop_ ();

_nop_ ();

_nop_ ();

if((temp&0x80)==0x80)/* 如果最高位是1*/

sda=1;

else

sda=0;

scl=1;

temp=data<<1; /*rlc*/

data=temp;

bitcounter--;

}while(bitcounter);

scl=0;

}


uchar read(void) /*读一个字节的数据,并返回该字节值*/

{

uchar temp=0;

uchar temp1=0;

uchar bitcounter=8;

sda=1;

do{

scl=0;

_nop_ ();

_nop_ ();

_nop_ ();

_nop_ ();

scl=1;

_nop_ ();

_nop_ ();

_nop_ ();

_nop_ ();

if(sda) /*如果sda=1;*/

temp=temp|0x01; /*temp的最低位置1*/

else

temp=temp&0xfe; /*否则temp的最低位清0*/

if(bitcounter-1)

{ temp1=temp<<1;

temp=temp1;

}

bitcounter--;

}while(bitcounter);

return(temp);

}


void wrtorom(uchar data[],uchar address,uchar num)

{

uchar i;

uchar *pdata;

pdata=data;

for(i=0;i<num;i++)

{

start(); /*发送启动信号*/

send(0xa0); /*发送sla+w*/

ack();

send(address+i); /*发送地址*/

ack();

send(*(pdata+i));

ack();

stop();

mdelay(20);

}

}

void rdfromrom(uchar data[],uchar address,uchar num)

{

uchar i;

uchar *pdata;

pdata=data;

for(i=0;i<num;i++)

{

start();

send(0xa0);

ack();

send(address+i);

ack();

start();

send(0xa1);

ack();

*(pdata+i)=read();

scl=0;

noack();

stop();

}

}

void main()

{

uchar number[4]={1,2,3,4};

wp= 1;

wrtorom(number,4,4); /*将初始化后的数值写入eeprom*/

mdelay(20);

number[0]=0;

number[1]=0;

number[2]=0;

number[3]=0; /*将数组中的值清掉,以验证读出的数是否正确*/

rdfromrom(number,4,4);

}
离线bg4jj
发帖
5094
只看该作者 1楼 发表于: 2002-11-26
c51是什么命令?
?
离线BA3CE
发帖
1652
只看该作者 2楼 发表于: 2002-11-26
c51是8051、8052系列单片机的c语言,比汇编语言开发效率高,我一直用c51开发,如果大家有兴趣我在本版办一个c51讲座。

                  73!
离线bg4jj
发帖
5094
只看该作者 3楼 发表于: 2002-11-26
欢迎呀
你用的c编译器能提供吗?
离线BA7IAG
发帖
2258
只看该作者 4楼 发表于: 2002-11-26
赞成!期待中。
离线bg4jj
发帖
5094
只看该作者 5楼 发表于: 2002-11-27
请问
这个程序用keil编译行吗?
离线BA3CE
发帖
1652
只看该作者 6楼 发表于: 2002-11-27
没用keil编译器试验过。我用的是franklin c51.
离线bg4jj
发帖
5094
只看该作者 7楼 发表于: 2002-11-27
up
离线bg4jj
发帖
5094
只看该作者 8楼 发表于: 2002-11-27
keil编译的
不知对吗?
附件: a.hex.txt (0 K) 下载次数:189
离线bg4jj
发帖
5094
只看该作者 9楼 发表于: 2002-11-29
up
?
离线bg4jj
发帖
5094
只看该作者 10楼 发表于: 2002-11-29
斑竹不来了吗?
讲座何时开呀??
离线BA3CE
发帖
1652
只看该作者 11楼 发表于: 2002-11-29
我发了个http://www.hellocq.net/forum/showthread.php?s=&threadid=17075
是关于c51的参考手册,,讲座欢迎大家提出要求,还有我最近设计了廉价的仿真机,图纸贴到论坛。

          73!