在下一篇日志中我贴出的程序和电路图都有错误,但是我不想改了。我是一个proteus和初学者,如果你也是一名初学者的话,你也很有可能会犯和我一样的错误。建议不妨看看上篇日志。如果是老鸟的话,就原谅小生了。在这里把正确的程序贴下,很简单的,半年以上学历的同志尽可不看了:
/*====================================
下为此程序的说明
功能:I2c总线驱动
版本:Ver 1.0
作者:刘保健 QQ:317182677
感谢:杨德富、zqp
日期:2007年10月21日
====================================*/
#include <reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define NOP _nop_()
#define NNOP NOP;NOP;NOP;NOP;NOP
void I2C_Start();
void I2C_Stop();
void Ack_I2C();
bit ISendB(uchar sla,uchar c);
bit IRcvB(uchar sla,uchar *c);
bit ISendStr(uchar sla,uchar sub,uchar *s,uchar n);
bit IRcvStr(uchar sla,uchar sub,uchar *s,uchar n);
void Delay(uchar);
uchar code ledcode[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
/* == == == == == == == == == == == == == == == == == ==
全局变量定义&位定义
== == == == == == == == == == == == == == == == == == */bit ack;
sbit SDA="P1"^0 ;
sbit SCL="P1"^1 ;
void main()
{
uchar Send_data[3]={1,5,9};
uchar Rec_data[3];
uchar *s;
s=Send_data;
P1=0xff;
I2C_Start();
ISendStr(0xa0,0x20,s,3);
Delay(1);
P1=0xff;
s=Rec_data;
IRcvStr(0xa0,0x20,s,3);
while(1)
{
P2=ledcode[Rec_data[0]];
Delay(100);
P2=ledcode[Rec_data[1]];
Delay(100);
P2=ledcode[Rec_data[2]];
Delay(100);
}
}
//n=1->10ms
void Delay(uchar n)
{
uchar i,j;
i=100;
j=100;
while(j--)
{
while(i--);
};
}
/* == == == == == == == == == == == == == == == == == ==
函数功能:开始
入口参数:
说 明 :
== == == == == == == == == == == == == == == == == == =*/void I2C_Start(void)
{
SDA=1;
NOP;
SCL=1;
NNOP;
SDA=0;
NNOP;
SCL=0;
NOP;
NOP;
}
/* == == == == == == == == == == == == == == == == == ==
函数功能:I2C STOP
入口参数:
说 明 :
== == == == == == == == == == == == == == == == == == =*/void I2C_Stop(void)
{
SDA=0;
NOP;
SCL=1;
NNOP;
SDA=1;
NNOP;
}
/* == == == == == == == == == == == == == == == == == ==
函数功能:送一字节
入口参数:
说 明 :
== == == == == == == == == == == == == == == == == == =*/void SendB(uchar c)
{
uchar i;
for(i=0;i<8;i++)
{
if((c<<i)&0x80)SDA=1;
else SDA="0";
NOP;
SCL=1;
NNOP;
SCL=0;
}
NOP;
NOP;
SDA=1; //8位传完后释放SDA,也就SDA=1
// SCL=0;
NOP;
NOP;
SCL=1;
NOP;
NOP;
NOP;
if(SDA == 1)ack=0;//no ack
else ack="1"; //ack
SCL=0;
NOP;
NOP;
}
/* == == == == == == == == == == == == == == == == == ==
函数功能:接收来处SLA的数据
入口参数:
说 明 :操作后调用应答函数 ACK_I2C();
== == == == == == == == == == == == == == == == == == =*/uchar RcvB(void)
{
uchar rete;
uchar i;
rete=0;
SDA=1; //置数据线为接收状态
for(i=0;i<8;i++)
{
NOP;
SCL=0;
NNOP;
SCL=1;
NOP;
NOP;
rete=rete<<1;
if(SDA == 1)rete++;
NOP;
NOP;
}
SCL=0;
NOP;
NOP;
return(rete);
}
/* == == == == == == == == == == == == == == == == == ==
函数功能:主控器件应答功能
入口参数:
说 明 :送0发0,送1发1,发1表示NO ACK
== == == == == == == == == == == == == == == == == == =*/void Ack_I2C(bit a)
{
if(a == 0)SDA=0; //是不发出应答信号
else SDA="1";
NOP;NOP;NOP;
SCL=1; //时钟高电平同期大于4us
NNOP;
SCL=0;
NOP;
NOP;
}
/* == == == == == == == == == == == == == == == == == ==
函数功能:发送一字节的数据 ,返回ack
入口参数:
说 明 :ack=1,应答;ack=0,无应答
== == == == == == == == == == == == == == == == == == =*/bit ISendB(uchar sla,uchar c)
{
I2C_Start();
SendB(sla);
if(ack == 0) return (0);
SendB(c);
if(ack == 0) return (0);
I2C_Stop();
return (1);
}
/* == == == == == == == == == == == == == == == == == ==
函数功能:接收一字节数据
入口参数:从器件地址,数据地址,操作数年地址,字节数
说 明 :
== == == == == == == == == == == == == == == == == == =*/bit ISendStr(uchar sla,uchar sub,uchar *s,uchar n)
{
uchar i;
I2C_Start();
SendB(sla);
if(ack == 0) return (0);
SendB(sub);
if(ack == 0) return (0);
for(i=0;i<n;i++)
{
SendB(*s);
if(ack == 0) return (0);
s++;
}
I2C_Stop();
return (1);
}
/* == == == == == == == == == == == == == == == == == ==
函数功能:收一字节的数据
入口参数:slave address
说 明 :
== == == == == == == == == == == == == == == == == == =*/bit IRcvB(uchar sla,uchar *c)
{
I2C_Start();
SendB(sla+1);
if(ack == 0) return (0);
*c=RcvB();
Ack_I2C(1);
I2C_Stop();
return(1);
}
/* == == == == == == == == == == == == == == == == == ==
函数功能:读取多字节数据
入口参数:从器件地址,数据地址,操作数年地址,字节数
说 明 :成功则返回1
== == == == == == == == == == == == == == == == == == =*/bit IRcvStr(uchar sla,uchar sub,uchar *s,uchar n)
{
uchar temp;
I2C_Start();
SendB(sla);
if(ack == 0) return (0);
SendB(sub);
if(ack == 0) return (0);
I2C_Start();
SendB(sla+1);
if(ack == 0) return(0);
temp=n-1;
while(temp--)
{
*s=RcvB();
Ack_I2C(0);
s++;
}
*s=RcvB();
Ack_I2C(1);
I2C_Stop();
return(1);
}
//////////////////////////复制到此
以下是打包文件(内有电路,程序,hex文件)
文章评论(0条评论)
登录后参与讨论