xinxin3219 发表于 2011-4-24 18:07:01

51读DS1302然后1602显示,不工作哦,求大侠指导

想测试下DS1302时钟芯片,结果仿真可以,实际就不行了,说不清楚,上图
http://cache.amobbs.com/bbs_upload782111/files_38/ourdev_633235ZMBAA0.png
(原文件名:QQ截图未命名.png)

http://cache.amobbs.com/bbs_upload782111/files_38/ourdev_633236PM9UFG.png
(原文件名:1302.png)


下面的是仿真时的情形,能工作
http://cache.amobbs.com/bbs_upload782111/files_38/ourdev_633238B61LD6.jpg
(原文件名:11.jpg)



就这两个,不知问题出哪,测试发现晶振没起振,程序如下:
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char


//DS1302管脚定义
sbit SCLK=P1^0;
sbit DQ=P1^1;
sbit RST=P1^2;
//液晶1602管脚定义
sbit rs=P2^6;
sbit lcden=P2^7;
uchar a,b,c,d,e,f;
uchar code table0[]="DATE:";
uchar code table1[]="TIME:";

/*--------------------    函数声明-------------------------------------*/
void delayms(int x);
voidlcd_write(uchar com);//LCD写命令
voidlcd_date(uchardate);//LCD写数据
voidlcd_start();//LCD初始化
void writedat(uchar address,uchar dat);
uchar readdat(uchar address);
void ds1302_init();
void DS1302open();
//void DS1302close();
void getdisplay();

/*******************************主函数***********************************/

void main()
{   uint i;
      ds1302_init();
      lcd_start();//LCD和DS1302初始化
      lcd_write(0x80);
      for(i=0;i<5;i++)//写上标志
      lcd_date(table0);
      lcd_write(0x80+0x40);
      for(i=0;i<5;i++)
      lcd_date(table1);   
      
      while(1)
      {
          DS1302open();
          delayms(200);
          getdisplay();
      }
}
/**********************************************************************/

//****写有确切地址的一个字节函数******/////
void writedat(uchar address,uchar dat)
{   int i,j;                         //设置循环变量
   RST=0;                            //禁止读写,避免前面的字节读写的干扰
   SCLK=0;
   RST=1;                            //允许读写
   for(i=0;i<8;i++)                  //写地址
   {   
         DQ=address&0X01;
         SCLK=0;             //发送最低位
         SCLK=1;
         address=address>>1;    //右移,以便发送次低位S
      }                           
   for(j=0;j<8;j++)                  //连续写8bit
      {
                                    
                                    
         DQ=dat&0x01;               
         SCLK=0;                  
         SCLK=1;                  //拉高时钟信号,数据被写入
         dat=dat>>1;                //待发送的数据右移1位,,以便发送
      }
   SCLK=0;                        //写完一个字节,拉低时钟信号          
}

//读有确切单元地址的一个字节函数*//
uchar readdat(uchar address)
{   uchar rdata=0;                  //存放数据的变量
   int i,j;                        //设置循环变量
   RST=0;                            //禁止读写,避免前面的字节读写的干扰
   SCLK=0;
   RST=1;                            //允许读写
   for(i=0;i<8;i++)                  //写地址
   {   
          DQ=address&0X01;             //发送最低位
          SCLK=0;         
          SCLK=1;            
          address=address>>1; //右移,以便发送次低位
      }                              //设置循环变量       
   for(j=0;j<8;j++)                  //连续读取8bit       
      {
      if(DQ==1)                      //拉低时钟信号,读数据               
      rdata=rdata|0x80;            //把接收到的数据放到接收寄存器的最高位
      else
      rdata=rdata&0x7f;            //拉高时钟信号
      SCLK=1;
      SCLK=0;
      rdata=rdata>>1;                //接收寄存器右移1位,,新的最高位来存放高位数据
                  
      }
   SCLK=0;                           //拉低时钟信号,平时保持低电平信号,有利于编程
   return rdata;                     //返回读取到的数据   
}

//*DS1302初始化(同时是设置时间函数)**//
void ds1302_init()
{
   SCLK=0;                           //拉低时钟信号
   RST=0;                              //复位DS1302
   RST=1;                              //使能DS1302                  
                                       //发写保护寄存器命令 ,往写保护寄存器中写入0,以打开写保护
   writedat(0x8e,0x00);                //允许写DS1302
   writedat(0x82,0x00);                //设置分,00
   writedat(0x84,0x00);                //设置时.00
   writedat(0x86,0x25);                //设置日,15
   writedat(0x88,0x04);                //设置月份3
   writedat(0x8c,0x11);                //设置年2011
   writedat(0x80,0x80);                //设置秒,00,并禁止启动
   RST=0;                              //禁止写,只允许读
}
/*---------------------------------------------------------*/

void DS1302open()//开始函数
{ uchar val;
val=readdat(0x81);//读出秒
RST=1;
writedat(0x80,val&0x7f);//将秒寄存器第七位置零,开始晶振使能
RST=0;
}
/*void DS1302close()//关闭函数
{ uchar val;
val=readdat(0x81);//读出秒
RST=1;
writedat(0x80,val|0x80);//将秒寄存器第七位置零,开始晶振关闭
RST=0;
}*/
voidlcd_write(uchar com)//写命令
{   delayms(10);
    rs=0;
    lcden=0;
    delayms(1);
    P3=com;
    delayms(1);
    lcden=1;
    delayms(1);
    lcden=0;
}
voidlcd_date(uchardate)//写数据
{   delayms(10);
   rs=1;
   lcden=0;
   delayms(1);
   P3=date;
   delayms(1);
   lcden=1;
   delayms(1);
   lcden=0;
}
voidlcd_start()//初始化
{   
    lcden=0;
    lcd_write(0x38);
    lcd_write(0x0c);
    lcd_write(0x06);
    lcd_write(0x01);
    delayms(5);   
}

void delayms(int x)
{   int i,j;
    for(i=x;i>0;i--)
    for(j=110;j>0;j--);


}
/*************************读并显示函数****************************/
voidgetdisplay()
{

      a=readdat(0X81);//读秒、时、分、时、日、月、年
      b=readdat(0X83);
      c=readdat(0X85);
      d=readdat(0X87);
      e=readdat(0X89);
      f=readdat(0X8d);

      lcd_write(0x80+5);
      lcd_date(2+0x30);
          lcd_date(0+0x30); //写上20前缀
          lcd_date((f>>4)+0x30);
          lcd_date((f&0x0f)+0x30);//写年、月、日、时、分、秒
          lcd_date(0xb0);
          lcd_date((e>>4)+0x30);
          lcd_date((e&0x0f)+0x30);
          lcd_date(0xb0);
          lcd_date((d>>4)+0x30);
          lcd_date((d&0x0f)+0x30);
          lcd_write(0xc0+5);
          lcd_date((c>>4)+0x30);
          lcd_date((c&0x0f)+0x30);
          lcd_date(0xb0);
          lcd_date((b>>4)+0x30);
          lcd_date((b&0x0f)+0x30);
          lcd_date(0xb0);
          lcd_date(((a>>4)&0x07)+0x30);
          lcd_date((a&0x0f)+0x30);
}

是51单片机的,请路过的大侠看看啦,如果有该电路的大侠,可以下载下去试试,看我这程序对不对,然后记得抽空回复我下,小弟感激不尽

njlzzdh 发表于 2014-7-13 09:15:40

定义液晶1602引脚的时候,是不是少定义了一个wr引脚?
页: [1]
查看完整版本: 51读DS1302然后1602显示,不工作哦,求大侠指导