具体我没空看了,我发个程序给你看看
void _24c02menu(void) //处理I2C数据时用的函数
{
unsigned char tmp,tmp2;
P2=0; //数码管显示清0
l_key=0xfe; //进入存储器处理程序先读取0地址的数据
while (1){
if(l_key==0x0c){ //如果按下*号键退出循环,即退出回到主函数
l_key=0xff;
break;
}
switch(l_key){ //扫描键盘做相应处理
case 0x0a: //按下0X0A键,我们可将它理解为上翻键
l_key=0xff;
if(l_address>0){
l_address--; //将地址减1
l_key=0xfe; //读取数据
}
break;
case 0x0b: //按下0X0A键,我们可将它理解为下翻键
l_key=0xff;
if(l_address<255){
l_address++; //将地址加1
l_key=0xfe; ////读取数据
}
break;
case 0x0e: //如果按下#号键,调用写存储器函数
l_key=0xff;
_24c02wdate(tmp);
l_key=0xfe;
break;
case 0xfe: //此按值是在键盘是没有的,我们有内部给他增加做为读数据处理
l_key=0xff;
I2C_start(); //I2C读数据的开始,到下面的结束是读一地址的整个过程,
I2C_write(W24C02); //向I2C总线发出读取24C02的地址
I2C_ACK(0); //下面就得你们自己结合I2C串口协议进行,先看看24C02数据手册是怎么讲I2C协议的
I2C_write(l_address);//先写入地址,
I2C_ACK(1);
I2C_stop();
I2C_start(); //再开始读取数据
I2C_write(R24C02);
I2C_ACK(0);
tmp=I2C_read();
I2C_ACK(1);
I2C_stop(); //读取一个地址的数据结束
l_tmpdate[0]=l_address/16; //数码管前两位显示地址(以16进制显示)
l_tmpdate[1]=l_address%16; //将地址变量分开用两位数据
l_tmpdate[3]=tmp/100; //后面用10进制数显示数据,中间用"-"隔开,数组l_tmpdate[2]
tmp2=tmp%100; //8位二进制最大十进制为255,所以我们也将它分开三位显示
l_tmpdate[4]=tmp2/10;
l_tmpdate[5]=tmp2%10;
break;
}
display(l_tmpdate,6);
}
}
void _24c02wdate(unsigned char tmp)//对24C02的写数据处理函数
{
unsigned char tmp2=0;
while(1){
if (l_key==0x0c){ //如果按下*号键退出循环,即退出回到上一极函数
l_key=0xff;
break;
}
if(l_key==0x0e){ //如果按下#号键,将更改的数据写入24C02存储器
l_key=0xff;
I2C_start(); //下面是写一地址数据的过程
I2C_write(W24C02); //先向总线发出写24C02的地址
I2C_ACK(0);
I2C_write(l_address); //写入地址
I2C_ACK(0);
I2C_write(tmp); //然后写入数据
I2C_ACK(1);
I2C_stop();
break;
}
switch(l_key){ //下面是对数据的处理
case 0x01: //如果按下1键,数据百位加1
l_key=0xff;
if(tmp<155)
tmp+=100;
break;
case 0x02: //如果按下2键,数据十位加1
l_key=0xff;
if(tmp<245)
tmp+=10;
break;
case 0x03: //如果按下3键,数据个位加1
l_key=0xff;
if(tmp<255)
tmp++;
break;
case 0x04: //如果按下4键,数据百位减1
l_key=0xff;
if(tmp>=100)
tmp-=100;
break;
case 0x05: //如果按下5键,数据十位减1
l_key=0xff;
if(tmp>=10)
tmp-=10;
break;
case 0x06: //如果按下6键,数据个位减1
l_key=0xff;
if(tmp>0)
tmp--;
break;
}
l_tmpdate[3]=tmp/100; //地址不变我们不用修改,更改数据显示即可
tmp2=tmp%100;
l_tmpdate[4]=tmp2/10;
l_tmpdate[5]=tmp2%10;
display(l_tmpdate,6);
}
}
void I2C_write(unsigned char tmp)//I2C写入一个8位二进制数,高位在前低位在后
{
unsigned char i;
for(i=0;i<8;i++){
SCL=0;
_nop_();
_nop_();
_nop_();
SDA=(bit)(tmp&0x80);
tmp<<=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
SCL=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
}
SCL=0;
}
unsigned char I2C_read(void)////I2C读取一个8位二进制数,也是高位在前低位在后
{
unsigned char i,tmp;
tmp=0;
for(i=0;i<8;i++){
SCL=0;
_nop_();
_nop_();
_nop_(); //加入空指令增加稳定性,这关系到频率问题
SDA=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
SCL=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
tmp<<=1;
if(SDA==1)
tmp++;
}
SCL=0;
return tmp;
}
void I2C_ACK(bit tmp) //根据tmp的1、0来决定应答信号
{
SDA=tmp;
_nop_();_nop_();_nop_();_nop_();_nop_();
SCL=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
SCL=0;
}
void I2C_start(void) //看看I2C开始的波形,再对应SDA、SCL的输出
{
SDA=1;
_nop_();
SCL=1;
_nop_();
SDA=0;
_nop_();
SCL=0;
_nop_();
}
/*********/
void I2C_stop(void) //I2C结束
{
SDA=0;
_nop_();
SCL=1;
_nop_();
SDA=1;
_nop_();
SCL=0;
_nop_();
}
你的程序编译是通过的,看你的原理图,指出两点:
1.你的地址端接的是高电平,读写时是不是和0xae,0xaf地址码对应,请请查看使用说明解决。
2.SCL、SDA需要接上上电阻的,不然高电平上不去。
希望对你有帮助!