当前位置: 代码迷 >> C语言 >> 关于一个I2C程序求教!
  详细解决方案

关于一个I2C程序求教!

热度:393   发布时间:2006-04-15 13:19:00.0
关于一个I2C程序求教!
下面一个程序中,main()函数中执行到 wrnbyt(0xc0,ff,5)时,不执行相应子程序而直接跳
过,不知道是什么原因,还有执行rdnbyt(0xc1,qq,5)时,也并不完全执行相应子函数,而是从

cack( );开始,由于不太精通C语言编程,希望得到大家的指点.谢谢

#include <intrins.h>
#include <reg52.h>
sbit SDA=P1^7 ; /*定义I2C数据口*/
sbit SCL=P1^6 ; /*定义I2C时钟口*/
sbit BUS=P1^5;
#define uchar unsigned char

void sta( ); /*启动I2C总线*/
void cack( ); /*检测应答位*/
void stop( ); /*停止I2C总线*/
void mnack( ); /*发送应答位*/
void mack( ); /*发送非应答位*/
void wrbyt(uchar shu); /*向虚拟I2C总线上发送1个数据字节*/
void wrnbyta(uchar slaw,uchar gg[],uchar n);
/*向slaw写入gg[n]中的数据*/
void wrnbyt(uchar slaw,uchar ff[],uchar number);
/*向虚拟I2C总线上发送n个字节的数据*/
uchar rdbyt( ); /*从I2C总线上读取1个数据字节*/
void rdnbyt(uchar slar,uchar qq[],uchar number);
/*从虚拟I2C总线上读取n个字节的数据*/

/*源程序由9个函数组成,程序清单如下:*/
void sta(void) /*启动I2C总线*/
{ SDA=1;
SCL=0;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
_nop_();
}

void stop(void ) /*停止I2C总线*/
{
SDA=0;
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
_nop_();
SCL=0;
}

void mack(void) /*发送应答位*/
{
SDA=0;
SCL=1;
_nop_();
SCL=0;
SDA=1;
}

void mnack(void) /*发送非应答位*/
{
SDA=1;
SCL=1;
_nop_();
SCL=0;
SDA=0;
}

void cack(void) /*应答位检查*/
{
SDA=0;
SCL=1;
F0=0; /*接收到应答位*/
if(SDA==1)
F0=1; /*未接收到应答位*/
SCL=0;
_nop_();
}

void wrbyt(uchar shu) /*向虚拟I2C总线上发送1个数据字节*/
{
uchar i;
for(i=0;i<8;i++)
{
if((shu&0x80)>0)
{
SDA=1;
SCL=1;
_nop_();
SCL=0;
SDA=0;
}
else
{
SDA=0;
SCL=1;
_nop_();
SCL=0;
}
shu=shu<<1;
}
}

uchar rdbyt(void) /*从I2C总线上读取1个数据字节*/
{
uchar nn=0xff,mm=0x80,uu=0x7f;
uchar j;
for(j=0;j<8;j++)
{
SDA=1;
SCL=1;
if(SDA==0)
nn=(nn&uu);
else
nn=(nn|mm);
nn=_crol_(nn,1); /*字符循环左移*/
SCL=0;
}
return(nn);
}

void wrnbyta(uchar slaw,uchar gg[],uchar n) /*向slaw写入gg[n]中的数据*/
{
do{
sta( ); /*启动I2C总线*/
wrbyt(slaw); /*写地址*/
cack( ); /*检测应答位*/
}while(F0==1); /*当未检测到应答位继续发送地址*/
wrbyt(gg[n]); /*写数据*/
cack( ); /*检测应答位*/
}


/*向虚拟I2C总线上发送n个字节的数据*/
void wrnbyt(uchar slaw,uchar ff[],uchar number)
{
uchar idata k;
do{
sta( );
wrbyt(slaw);
cack( );
}while(F0==1);
for(k=0;k<number;k++)
{
wrbyt(ff[k]);
cack( );
while(F0==1)
wrnbyta(slaw,ff,k); /*如果没有检测到应答位,重新发ff[k]*/
}
stop( );
}

/*从虚拟I2C总线上读取n个字节的数据*/
void rdnbyt(uchar slar,uchar qq[],uchar number)
{
uchar idata data0,l;
do
{
sta( );
wrbyt(slar);
cack( );
}while(F0==1);
for(l=0;l<number;l++)
{
data0=rdbyt( );
qq[l]=data0; /*将读的数据存到qq[]中*/
mack( ); /*发送应答位*/
}
data0=rdbyt( );
qq[l]=data0;
mnack( );
stop( );
}

main( )
{
uchar slaw;
uchar slar;
#define slaw 0xc0;
#define slar 0xc1;
uchar qq[]={0,0,0,0,0};
uchar ff[]={0x55,0xaa,0xb1,0x50,0x80};
BUS=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();

wrnbyt(0xc0,ff,5); /*问题所在,直接跳过,并不执行wrnbyt(0xc0,ff,5)函数*/

_nop_();
_nop_();
_nop_();
_nop_();
_nop_();

rdnbyt(0xc1,qq,5); /*跳到相应子程序时从cack( )开始往下执行,并没有sta( )和
wrbyt(slar)*/

}
谢谢您的指教!多谢

----------------解决方案--------------------------------------------------------
  相关解决方案