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

2019-03-24 17:57发布

#include <reg52.h>
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<<i)&0x80)
   {
     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<n;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条回答
huaiqiao
2019-03-25 06:06
别的没有多看,你的这个LCD的写指令和读指令等函数中,我感觉有些语句后面应该加个延时,这个你看下LCD1602的datasheet就知道了,举个例子:你的EN=0;然后马上就变成了EN=1.我记得时序不是这样的吧,中间还有个延时吧? 你的这种情况,应该先调显示,然后再调显示+eeprom

一周热门 更多>