微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > iic读取总是返回0xff,请高手帮忙看看。谢谢

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

时间:10-02 整理:3721RD 点击:
#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);
}


可以试试这个,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();
}

遇到同样问题了,小编,请问你解决了么

没有读出来,没有写进去

小编我用你的代码显示到数码管上表明已经写进去和读出来了
你源代码中哪里可以显示读出来?


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top