[求助] 用51单片机控制的AT24C02的写入与读取程序问题咨询

30419089   2015-6-23 20:15 楼主
#include
sbit SCL = P3^5;
sbit SDA = P3^6;
sbit RS = P2^6 ;
sbit RW = P2^5 ;
sbit EN = P2^7 ;
sbit BUSY = P0^7;
char senddata[8]={"11:28:37"};
char recdata[8];
/*********************************************************************
  LCD1602       
***********************************************************************/
/**
* 等待繁忙标志
*/
void wait(void)
{
        P0 = 0xFF;
        do
        {
                RS = 0;
                RW = 1;
                EN = 0;
                EN = 1;
        }while (BUSY == 1);
        EN = 0;
}

//写数据

void w_dat(char dat)
{
        wait();
        EN = 0;
        P0 = dat;
        RS = 1;
        RW = 0;
        EN = 1;
        EN = 0;
}

//写命令

void w_cmd(char cmd)
{
        wait();
        EN = 0;
        P0 = cmd;
        RS = 0;
        RW = 0;
        EN = 1;
        EN = 0;
}

/**
* 初始化1602
*/
void Init_LCD1602(void)
{
        w_cmd(0x38);  // 16*2显示,5*7点阵,8位数据接口
        w_cmd(0x0C);  // 显示器开、光标开、光标允许闪烁
        w_cmd(0x06);  // 文字不动,光标自动右移
        w_cmd(0x01);  // 清屏
}
/*************延时函数************/
void DELAY(char time)
{
   while(time!=0) time--;
}
/************开始函数*************/
void start(void)
{
  SDA = 1;
  SCL = 1;
  DELAY(70);
  SDA = 0;
  DELAY(70);
  SCL = 0;
  DELAY(70);
}
/************停止函数*************/
void stop(void)
{
  SDA = 0;
  SCL = 1;
  DELAY(70);
  SDA = 1;
  DELAY(70);
  SCL = 0;
  DELAY(70);
}

/*检验设备是否有应答信号函数CKAck*/
bit CKAck(void)
{
  SDA = 1;
  SCL = 1;
  DELAY(35);
  F0 = SDA;
  DELAY(35);
  SCL = 0;
  DELAY(70);
  if(F0==1)
  {return 0;}
  return 1;
}
/*向IIC总线送一个字节函数*/
void WByte(char b)reentrant
{
  char i ;
  for(i=0;i<8;i++)
   if((b<    {
     SDA = 1;
         SCL = 1;
         DELAY(70);
         SCL = 0;
         DELAY(70);
    }
   else
   {
            SDA = 0;
         SCL = 1;
         DELAY(70);
         SCL = 0;
         DELAY(70);
    }
}
/*从IIC总线读一个字节*/
char RByte(void) reentrant
{
  char a,i;
  for(i=0;i<8;i++)
   {
            SDA=1;
         SCL=1;
         DELAY(10);
         F0=SDA;
         DELAY(10);
         SCL=0;
         if(F0==1)
          {
            a=a<<1;
                a=1|0x01;
          }
            else
           a=a<<1;
    }
        return a;

}
/*写一页数据函数W8Byte,其中addr为8个写入数据的首地址,adr为存放的起始地址*/
void W8Byte(char *addr,char adr)
{
  bit ack;
  int i;
  start();
  WByte(0xa0);
  ack = CKAck();
  WByte(adr);
  ack = CKAck();
  for(i=0;i<8;i++)
    {
          WByte(addr[i]);
          if(!CKAck())
            { stop();}
        }
        stop();
}
/*读N个字节函数,Read,其中,addr为要存放的数据的首地址,n为字节数,adr为要读取数据的首地址*/
void RNByte(char *addr,char n,char adr)
{
  bit ack;
  int i=0;
  start();
  WByte(0xa0);
  ack = CKAck();
  WByte(adr);
  ack=CKAck();
  start();
  WByte(0xa1);
  ack = CKAck();
  for(i=0;i    {
            addr[i]=RByte();
         if(i!=n-1)
         {
          SDA=0;
          SCL=1;
          DELAY(70);
          SCL=0;
          DELAY(70);
          }
         else
          {
           SDA=1;
           SCL=1;
           DELAY(70);
           SCL=0;
           DELAY(70);
          }
             stop();
    }
}
/*******主函数**************/
void main()
{
  Init_LCD1602();
  W8Byte(senddata,0x10);
  RNByte(recdata,1,0x10);
        while(1)
        {
               w_cmd(0x80);
          w_dat(recdata[0]);
                    w_cmd(0x81);
          w_dat(recdata[1]);
                    w_cmd(0x82);
          w_dat(recdata[2]);
                    w_cmd(0x83);
          w_dat(recdata[3]);
                    w_cmd(0x84);
          w_dat(recdata[4]);
                    w_cmd(0x85);
          w_dat(recdata[5]);
                    w_cmd(0x86);
          w_dat(recdata[6]);
                    w_cmd(0x87);
          w_dat(recdata[7]);   

        }  
}




为什么液晶屏上面显示乱码?

回复评论 (11)

学知识了,谢谢搂住
点赞  2015-6-23 20:28
别的没有多看,你的这个LCD的写指令和读指令等函数中,我感觉有些语句后面应该加个延时,这个你看下LCD1602的datasheet就知道了,举个例子:你的EN=0;然后马上就变成了EN=1.我记得时序不是这样的吧,中间还有个延时吧? 你的这种情况,应该先调显示,然后再调显示+eeprom
点赞  2015-6-23 21:04
引用: huaiqiao 发表于 2015-6-23 21:04
别的没有多看,你的这个LCD的写指令和读指令等函数中,我感觉有些语句后面应该加个延时,这个你看下LCD1602 ...

我的这个LCD的驱动程序以前用过    可以显示。
点赞  2015-6-23 21:22
引用: 30419089 发表于 2015-6-23 21:22 我的这个LCD的驱动程序以前用过 可以显示。
难道你的延时没有问题吗? 如果不是,就是eeprom时序的问题了,这个时序中特别要注意点延时,还有scl和sda的时序 本帖最后由 huaiqiao 于 2015-6-23 22:49 编辑
点赞  2015-6-23 21:33
显示乱码肯定是显示的问题。注意延时
点赞  2015-6-23 21:51
引用: huaiqiao 发表于 2015-6-23 21:33
难道你的延时没有问题吗? 如果不是,就是eeprom时序的问题了,这个时序中特别要注意点延时,还有scl和sd ...

这个LCD的程序我以前用到过其他地方,完全可以。
点赞  2015-6-24 11:39
过路的来看看
点赞  2015-6-24 11:45
谢谢楼主
点赞  2015-6-24 11:46
引用: 30419089 发表于 2015-6-24 11:39
这个LCD的程序我以前用到过其他地方,完全可以。

那就看下sda和scl的读写时序是否正确咯
点赞  2015-6-24 12:32
引用: huaiqiao 发表于 2015-6-24 12:32
那就看下sda和scl的读写时序是否正确咯

其实是延迟的问题   谢谢了   解决了
点赞  2015-6-30 17:04
引用: 30419089 发表于 2015-6-30 17:04
其实是延迟的问题   谢谢了   解决了

对啊,所以咯,你看到我7楼给你回复的帖子,你就应该想到去看延时,延时也是时序,只要时序没有问题。其他基本不会有大的问题的。
点赞  2015-6-30 17:07
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复