a5608662 发表于 2011-11-19 16:11:50

关于AT24c02多字节的读写,求解决?

IIC总线协议写的两个字节读写,用数码管显示,但不知道为什么一直读不出第二个数据,求解决。程序如下:
#include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit sda=P1^2;//根据板的原理图,定义相应管脚,数据线
sbit scl=P1^1;//时钟线
sbit wp=P1^0;//写保护,高电平则只能读,为低电平时,读写正常
uchar x,y;
void delay()//少少的延时
{
        _nop_();        _nop_();
        _nop_();         _nop_();
        _nop_();         _nop_();
        _nop_();        _nop_();
}
void delay1()
{
        uint a=60000;
        while(a--);               
}

void start()//开始信号
{       
        sda=1;
        delay();
        scl=1;
        delay();
        sda=0;
        delay();
}

void stop()   //停止
{
        sda=0;
        delay();
        scl=1;
        delay();
        sda=1;
        delay();
}

void ack()//应答,判断是否要终止发送
{
        uchar i;
        scl=1;
        delay();
        while((sda==1)&&(i<200))i++;//当sda为1且小于这个时间,表示从机向主机发出了应答信号,不用终止
        scl=0;
        delay();
}

void noack()
{
        sda=1;
        delay();
        scl=1;
        delay();
        scl=0;
        delay();
}


void iicwr_byte(uchar dat)//写入地址、数据函数
{
        uchar i;
        scl=0;
        for(i=0;i<8;i++)
                {
                        if(dat&0x80)
                                {
                                        sda=1;
                                }
                        else
                                {
                                        sda=0;
                                }
                        dat=dat<<1;
                        delay();
                        scl=1;
                        delay();
                        scl=0;
                        delay();
                }
        sda=1;//养成释放总线的习惯
        delay();
}

uchar iicre_byte()//读出数据和地址函数
{
        uchar i,dat;
        scl=0;
        delay();
        sda=1;//释放总线
        delay();
        for(i=0;i<8;i++)//每次将sda的k或一次,就将sda的数据或地址存在k中
                {
                        scl=1;//要在稳定的情况下读出数据
                        delay();
                        dat=dat<<1;       
                        if(sda)
                                {
                                        dat++;       
                                }
                        scl=0;
                        delay();
                               
                }
        return dat;
}

void init()//函数初始化
{
        wp=0;
        sda=1;//把数据总线全部释放
        delay();
        scl=1;
        delay();
}

void write_add(uchar add,uchar dat1,uchar dat2)
{
        init();
        start();
        iicwr_byte(0xae);
        ack();
        iicwr_byte(add);
        ack();
        iicwr_byte(dat1);
        ack();
        iicwr_byte(dat2);
        ack();
        stop();
}
void read_add(uchar add)
{
        init();
        start();
        iicwr_byte(0xae);
        ack();
        iicwr_byte(add);
        ack();
        start();
        iicwr_byte(0xaf);
        ack();
        x=iicre_byte();
        ack();
        y=iicre_byte();
        noack();
        stop();
}
void main()
{
        write_add(3,0x3f,0x06);
        delay1();
        read_add(3);
        delay1();
        while(1)
        {
                P0=x;
                P2=0XF7;
                delay();
                P0=y;
                P2=0xf6;
        }
}

a5608662 发表于 2011-11-19 16:12:33

坐等解决,急急急呀。

rocky-zou 发表于 2011-11-23 13:47:52

#include<reg52.h>
#include<delay.h>
#include<intrins.h>
#include"iic.h"
#include"delay.h"
#define _Nop() _nop_()
bit ack;
void start_I2c();
void stop_I2c();
void sendbyte(uchar c);
uchar rcvbyte();
void ack_I2c(bit a);

/*启动总线函数*/
void start_I2c()
{SDA=1;
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA=0;
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0;
_Nop();
_Nop();
}
/*结束总线函数*/

void stop_I2c()
{SDA=0;
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA=1;
_Nop();
_Nop();
_Nop();
_Nop();
}
/*字节数据传送函数*/
void sendbyte(uchar c)
{uchar bitcnt;
for (bitcnt=0;bitcnt<8;bitcnt++)
{if ((c<<bitcnt)&0x80)
    SDA=1;
   else SDA=0;
    _Nop();
        SCL=1;
    _Nop();
    _Nop();
    _Nop();
    _Nop();
        _Nop();
        SCL=0;
}
_Nop();
_Nop();
SDA=1;
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
if (SDA==1)
           ack=0;
else
           ack=1;
SCL=0;
_Nop();
_Nop();

}

/*字节数据接受函数*/
uchar rcvbyte()
{uchar retc;
uchar bitcnt;
retc=0;
SDA=1;
for (bitcnt=0;bitcnt<8;bitcnt++)
{_Nop();
   SCL=0;
   _Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop();
retc=retc<<1;
if (SDA==1)retc=retc+1;
_Nop();
_Nop();
}
SCL=0;
_Nop();
_Nop();
return (retc);
}

/* 应答函数*/
void ack_I2c(bit a)
{if (a==0)
   SDA=0;
else SDA=1;
_Nop();
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0;
_Nop();
_Nop();
}

/*写N个字节数据
入口地址参数:从地址sla,子地址suba,发送no字节数据是S指向的内容
   出口参数:返回1,操作成功,否则有误*/
bit nsend (uchar sla,uchar suba,uchar *s,uchar no)
{ uchar i;
start_I2c();
sendbyte(sla);
if (ack==0)return(0);
    sendbyte(suba);
if (ack==0)return(0);
for (i=0;i<no;i++)
    {
          sendbyte(*s);
          if (ack==0)return(0);
          s++;
       }
   stop_I2c();
   return(1);
}

/*读N个字节数据
入口地址参数:从地址sla,子地址suba,读出的内容存放到S指向的内容单元
   出口参数:返回1,操作成功,否则有误*/
bit nread(uchar sla,uchar suba,uchar *s,uchar no)
{ uchar i;
start_I2c();
sendbyte(sla);
if (ack==0)return(0);
    sendbyte(suba);
if (ack==0)return(0);
   start_I2c();
   sendbyte(sla+1);
if (ack==0) return (0);
for (i=0;i<no-1;i++)
    {*s=rcvbyte();
      ack_I2c(0);
      s++;
   }
*s=rcvbyte();
ack_I2c(1);
stop_I2c();
return (1);
}

rocky-zou 发表于 2011-11-23 13:48:28

我写的函数修改下直接用吧

hanliang0330 发表于 2011-11-23 18:09:42

一般都是时序的问题,你再仔细检查下就知道了,呵呵

gbwaikp2011 发表于 2013-1-7 12:29:03

rocky-zou 发表于 2011-11-23 13:48 static/image/common/back.gif
我写的函数修改下直接用吧

你好,你这个函数可以向24C02里边写入多少字节的数据,是256字节吗?有点不太懂,希望你能帮帮忙,谢过了

dlmaowf 发表于 2013-1-7 12:46:40

24C02一次只能写8个字节吧,写完后还得延迟个5ms左右等待写完成
页: [1]
查看完整版本: 关于AT24c02多字节的读写,求解决?