以下是一個24C02的存取函數,可以正常使用,想請教一下如果是24C04以上的,內部地址是10位二進制的,超過了一次所能發送的8位數據,這應該怎么弄呢
單片機源程序如下:
#include <STC89C5xRC.H>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit SDA=P2^7;
sbit SCL=P2^6;
sbit led=P1^6;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
void start( )
{
SDA=1; //發送起始條件的數據信號
_nop_( );
SCL=1;
_nop_( ); //起始條件建立時間大于4.7us,延時
_nop_( );
_nop_( );
_nop_( );
_nop_( );
SDA=0; //發送起始信號
_nop_( ); //起始條件鎖定時間大于4μ
_nop_( );
_nop_( );
_nop_( );
_nop_( );
SCL=0; //鉗住I2C總線,準備發送或接收數據
_nop_( );
_nop_( ); //SCL置低,準備接收或發送數據
}
void stop( )
{
SDA=0; //發送結束條件的數據信號
_nop_( ); //發送結束條件的時鐘信號
SCL=1; //結束條件建立時間大于4μ
_nop_( );
_nop_( );
_nop_( );
_nop_( );
_nop_( );
SDA=1; //發送I2C總線結束信號
_nop_( );
_nop_( );
_nop_( );
_nop_( ); //延時保持4.7US以上
}
void write(uchar a)
{
uchar b,shu;
for(b=0;b<8;b++) //要傳送的數據長度為8位
{
shu=a<<b; //把即將發送的數據的位移到最高位
if((shu&0x80)!=0) //判斷最高位是否為0
SDA=1; //不等于0說明最明當前要發送的數據為1
else SDA=0; //否則數據為0
SCL=1; //置時鐘線為高,通知被控器開始接收數據位
_nop_( );
_nop_( ); //保證時鐘高電平周期大于4μ
_nop_( );
_nop_( );
_nop_( );
SCL=0;
}
_nop_( );
SDA=1; //8位發送完后釋放數據線,準備接收應答位
_nop_( );
SCL=1;
_nop_( );
}
bit ack( ) //等待應答函數
{
bit h;
SDA=1;
_nop_( );
SCL=1; //SDA和SCL全部置高
_nop_( );
_nop_( );
_nop_( );
_nop_( );
SCL=0; //等待4.7US以上,把SCL置低
_nop_( );
_nop_( );
_nop_( );
_nop_( );
h=SDA; //等待4.7SU以上讀取SDA應答信號
return h; //應答成功則是0,沒有應答則是1
}
uchar reade( ) //接收數據
{
uchar d,g;
SDA=1; //數據線置高電平
for(d=0;d<8;d++)
{
_nop_( );
_nop_( );
SCL=0;
_nop_( );
_nop_( );
_nop_( );
_nop_( ); //SCL低電平,數據變化
SCL=1;
_nop_( );
_nop_( ); //SCL高電平,數據穩定
if(SDA==1)
g=(g<<1)|0x01; //如果讀到的數據是1就是最低位置1
else
g=g<<1; //否則讀到是0,直接左移1位(左移后右補0)
}
return g; //經過8次讀取移位,把g返回
}
void main( )
{
start( ); //啟動總線
write(0xa0); //器件地址(發送)
led=ack( ); //等待應答
// led=~led;
write(0x03); //發送器件內部地址
led=ack( ); //等待應答
//led=~led;
write(0xfe); //發送第一組數據
ack( ); //等待應答
write(0x35); //發送第二組數據(器件內部地址指針自動+1,不用重新指定地址)
ack( );
write(0xb2);
ack( );
write(0xc3);
ack( );
write(0x24);
ack( );
led=~led;
stop( ); //發送完成,停止總線
led=~led;
delay(100);
start( ); //讀取(開始-器件地址(發)- 器件內部地址 - 開始 - 器件地址(收)- 接收數據 -發應答或停止接收
write(0xa0);
ack( );
led=~led;
write(0x03);
ack( );
led=~led;
start( );
write(0xa1);
ack( );
led=~led;
P1=reade( );
stop( );
delay(1000);
start( );
write(0xa0);
ack( );
led=~led;
write(0x03);
ack( );
led=~led;
start( );
write(0xa1);
ack( );
led=~led;
P1=reade( );
stop( );
delay(1000);
start( );
write(0xa0);
ack( );
led=~led;
write(0x04);
ack( );
led=~led;
start( );
write(0xa1);
ack( );
led=~led;
P1=reade( );
stop( );
delay(1000);
start( );
write(0xa0);
ack( );
led=~led;
write(0x05);
ack( );
led=~led;
start( );
write(0xa1);
ack( );
led=~led;
P1=reade( );
stop( );
delay(1000);
start( );
write(0xa0);
ack( );
led=~led;
write(0x06);
ack( );
led=~led;
start( );
write(0xa1);
ack( );
led=~led;
P1=reade( );
stop( );
delay(1000);
start( );
write(0xa0);
ack( );
led=~led;
write(0x04);
ack( );
led=~led;
start( );
write(0xa1);
ack( );
led=~led;
P1=reade( );
stop( );
while(1);
}
|