iic读取总是返回0xff,请高手帮忙看看。谢谢

2019-07-15 16:21发布

#include <reg52.h>
sbit scl=P1^2;
sbit sda=P1^1;

sbit led1=P3^7;
sbit led2=P3^6;
sbit led3=P3^5;
sbit led4=P3^4;

void yanshi()
{
        ;;
}

void iic_init()//总线初始化,降总线拉高以释放总线
{
        scl=1;
        yanshi();
        sda=1;
        yanshi();
}

void iic_start()//启动信号,在SCL高电平期间,SDA一个下降沿启动信号
{
        scl=1;
        yanshi();
        sda=1;
        yanshi();
        sda=0;
        yanshi();
}

void respons()//应答信号,SCL高电平期间,SDA被从设备拉低表示应答
{
        unsigned char a;
        scl=1;
        yanshi();
        while((sda==1)&&(a<250))a++;
        scl=0;
        yanshi();
}

void stop()//SCL在高电平期间,SDA一个上升沿信号表示停止
{
        sda=0;
        yanshi();
        scl=1;
        yanshi();
        sda=1;
        yanshi();
}

void write_byte(unsigned char date)//写一个字节
{
        unsigned char i,temp;
        temp=date;
        for(i=0;i<8;i++)
        {
                temp=temp<<1;
                scl=0;
                yanshi();
                sda=CY;
                yanshi();
                scl=1;
                yanshi();
        }
        scl=0;
        yanshi();
        sda=1;
        yanshi();
}

unsigned char read_byte()//读一个字节
{
        unsigned char i,k;
        scl=0;
        yanshi();
        sda=1;
        yanshi();
        for(i=0;i<8;i++)
        {
                scl=1;
                yanshi();
                k=(k<<1)|sda;
                scl=0;
                yanshi();
        }
        return k;
}

void write_add(unsigned char address,unsigned char date)//写片内地址,数据
{
        iic_start();
        write_byte(0xa0);//写片选地址
        respons();
        write_byte(address);//写片内地址
        respons();
        write_byte(date);//写数据
        respons();
        stop();
}

void nack()
{
        scl=1;
        yanshi();
        sda=1;
        scl=0;
        yanshi();
}

unsigned read_add(unsigned char address)//读片内地址,数据
{
        unsigned char date;
        iic_start();
        write_byte(0xa0);//写片选地址
        respons();
        write_byte(address);//写片内地址
        respons();
        iic_start();//开始信号
        write_byte(0xa1);//读命令
        respons();
        date=read_byte();//读片内数据,把数据赋值给date
        nack();
        stop();
        return date;
}

void yanshi_10ms()
{
        unsigned char a,b;
        for(a=50;a>0;a--)
        {
                for(b=200;b>0;b--);
        }

}
void main()
{
        unsigned int aaa;
        iic_init();
        iic_start();
        led1=0;
        write_add(10,0xf0);
        led2=0;
        yanshi_10ms();
        led3=0;
        aaa=read_add(10);
        led4=0;
        while(1);

}

QQ截图20150807222011.png
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
4条回答
请叫我雷锋
2019-07-15 20:04

可以试试这个,IIC 的时序要正确 我不知道你是否按照时序图写了

#define I2C_DELAY; _nop_();_nop_();_nop_();_nop_();_nop_(); // >=4.7uS

//----------------------------------------------------------------
// delay 100us
//----------------------------------------------------------------
void mDelay(INT8U k)
{
INT16U i ;

for(; k>0; k--)
{
for(i=0; i<93; i++)
;
}
}



//----------------------------------------------------------------
//OK
//----------------------------------------------------------------
void I2C_Start(void)
{
SDA = 1;
I2C_DELAY;

SCL = 1;
I2C_DELAY;

SDA = 0;
I2C_DELAY;
I2C_DELAY;
}



//----------------------------------------------------------------
//OK
//----------------------------------------------------------------
void I2C_Stop(void)
{
SDA = 0 ;
I2C_DELAY;

SCL = 1 ;
I2C_DELAY;

SDA = 1 ;
I2C_DELAY;
I2C_DELAY;
}



//----------------------------------------------------------------
//
//----------------------------------------------------------------
void sendAck(void)
{
SCL = 0;
I2C_DELAY;

SDA = 0;
I2C_DELAY;

SCL = 1;
I2C_DELAY;

}


//----------------------------------------------------------------
//
//----------------------------------------------------------------
void sendNoAck(void)
{
SCL = 0;
I2C_DELAY;

SDA = 1;
I2C_DELAY;

SCL = 1;
I2C_DELAY;

}


//----------------------------------------------------------------
// 0 = noACK; 1 = ACK ;
//----------------------------------------------------------------
bit checkAck()
{
bit tempbit;
/*发送完一个字节后检验设备的应答信号*/
SDA = 1;
I2C_DELAY;

SCL = 0;
I2C_DELAY;

tempbit = SDA;

SCL = 1;
I2C_DELAY;

if(tempbit==1)
{
return 0; //noACK
}
else
{
return 1; //ACK
}
}



//----------------------------------------------------------------
//OK
// a positive clock edge clock a bit into the ROM
//----------------------------------------------------------------
void writeByte(INT8U datum)
{
INT8U bitCnt = 0 ;

for(bitCnt=0; bitCnt<8; bitCnt++)
{
SCL = 0 ;
I2C_DELAY;

if ((datum&0x80) == 0x80) //if the MSb is 1
SDA = 1 ;
else
SDA = 0 ;
I2C_DELAY;

SCL = 1 ;
I2C_DELAY;

datum<<=1 ;
}

}



//----------------------------------------------------------------
//OK
//----------------------------------------------------------------
INT8U readByte(void)
{
bit tempbit = 1 ;
INT8U temp = 0 ;
INT8U bitCnt ;

SDA = 1 ; // release the bus,ready to receive byte??????????????
I2C_DELAY;

for(bitCnt=0; bitCnt<8; bitCnt++)
{
SCL = 0; //?????????????????????????huan???????????????
I2C_DELAY;

tempbit = SDA ;
if (tempbit)
temp |= 0x01 ;
else
temp &= 0xfe ;

SCL = 1 ;
I2C_DELAY;

if(bitCnt<7)
temp <<= 1 ;

}

return(temp) ;
}



/*~~~~~~~~~~~~~~~~~~~~~~~ API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*-----------------------------------------------------------------
write some bytes to sequential address
-----------------------------------------------------------------*/
void writeToROM(INT8U datum[], INT8U address, INT8U num)
{
bit tempbit ;
INT8U i ;
INT8U *datum_P ;
datum_P = datum ;

I2C_Start() ;

writeByte(0xa0) ;
tempbit = checkAck();

writeByte(address) ;
tempbit = checkAck();

for(i=0; i
{
writeByte(*(datum_P+i)) ;


if(!checkAck())
{
I2C_Stop() ;
mDelay(100) ;
}
}

I2C_Stop() ;
}



/*-----------------------------------------------------------------
read some bytes from ROM`s sequential address
-----------------------------------------------------------------*/
void readFromROM(INT8U datum[], INT8U address, INT8U num)
{
bit tempbit ;
INT8U i ;
INT8U *datum_P ;

datum_P = datum;

I2C_Start() ;

writeByte(0xa0) ;
tempbit = checkAck();

writeByte(address) ;
tempbit = checkAck();

I2C_Start() ;
writeByte(0xa1) ;
tempbit = checkAck();

for(i=0; i
{
*(datum_P+i) = readByte() ;

if(i!=num-1)
{
sendAck() ;
}
else
{
sendNoAck() ;
}
}

I2C_Stop() ;
}



/*-----------------------------------------------------------------
wirte one byte to ROM --random write
-----------------------------------------------------------------*/
void writeOneByte(INT8U addr, INT8U datum)
{
bit tempbit ;
/*write a byte to mem*/

I2C_Start();

writeByte(0xa0);
tempbit = checkAck();

writeByte(addr); /*address*/
tempbit = checkAck();

writeByte(datum); /*the data*/

tempbit = checkAck();

I2C_Stop();
mDelay(100) ;

}



/*-----------------------------------------------------------------
read one byte from rom --random read
-----------------------------------------------------------------*/
INT8U readOneByte(INT8U addr)
{
bit tempbit = 1;
INT8U mydata;
/*read a byte from mem*/

I2C_Start();

writeByte(0xa0);
tempbit = checkAck();

writeByte(addr); /*address*/
tempbit = checkAck();

I2C_Start();

writeByte(0xa1);
tempbit = checkAck();

mydata = readByte();
tempbit = checkAck();

return (mydata) ;

I2C_Stop();
}

一周热门 更多>