#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();
}
一周热门 更多>