以下是一个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);
}
|