原创 I2C总线驱动(24c04)对上一篇日志的更正

2007-10-22 20:02 6991 19 19 分类: MCU/ 嵌入式

在下一篇日志中我贴出的程序和电路图都有错误,但是我不想改了。我是一个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文件)


rar

文章评论0条评论)

登录后参与讨论
我要评论
0
19
关闭 站长推荐上一条 /2 下一条