找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2347|回复: 6
打印 上一主题 下一主题
收起左侧

小白求帮助 我试着用单片机和DS12C887和LCD1602做一个时钟但是LCD没有显示,硬件图.

[复制链接]
跳转到指定楼层
楼主
ID:149324 发表于 2016-11-21 23:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg52.h>          //头文件  
#define uchar unsigned char   //数据格式宏定义
#define uint unsigned int     //数据格式宏定义   s
bit rs=P3^5;           //lcd寄存器选择
sbit lcden=P3^4;        //lcd使能端
sbit s1=P3^0;           //开关s1
sbit s2=P3^1;           //开关s2
sbit s3=P3^2;           //开关s3
sbit beep=P1^2;         //蜂鸣器  
sbit dscs=P1^4;         //ds12c887片选  
sbit dsas=P1^5;         // ds12c887地址选通输入脚
sbit dsrw=P1^6;         // ds12c887读/写输入端  
sbit dsds=P1^7;         // ds12c887数据选择或读输入脚
sbit dsirq=P3^3;         // ds12c887中断请求输入  
uchar count,s1num,flag,flag1;                          //状态变量 char miao,shi,fen,nian,yue,ri,xingqi,amiao,afen,ashi;        //数据变量  
uchar code table[]=" 20  -  -";                         //年月日显示格式
uchar code table1[]="      :  :  ";                     //时间显示格式  
uchar code table2[]="MONTHUWENTHRFRISTASUN";    //星期表,每3位为一个
uchar code table3[]="   ALARM   ON   ";             //开闹钟提示
uchar code table4[]="   ALARM   OFF  ";             //关闹钟提示  
uchar code table5[]="SET ALARM PUSH  ";             //闹钟状态选择提示
void write_ds(uchar,uchar);                             //函数声明
void set_alarm(uchar,uchar,uchar); uchar read_ds(uchar);   
void delay(uint z)       //延时子函数
{
uint x,y;  for(x=z;x>0;x--)   
for(y=110;y>0;y--);
}   
void beezzer()         //蜂鸣器发声控制函数(闹钟响铃),beep=0发声
{  
  beep=0;  
  delay(50);  
  beep=1;  
  delay(100);  
  beep=0;
  delay(50);  
  beep=1;
}  
void write_com(uchar com) //向lcd写入控制字com,根据lcd1602时序图进行操作,rs为寄存器选择
{  
  rs=0;  
  lcden=0;  
  P0=com;  
  delay(5);  
  lcden=1;  
  delay(5);  
  lcden=0;  
}   
void write_date(uchar date)    //向lcd写入数据date,根据lcd1602时序图进行操作
{  
  rs=1;  
  lcden=0;  
  P0=date;  
  delay(5);  
  lcden=1;  
  delay(5);  
  lcden=0;  
}   
void init()                //初始化单片机
{  
  uchar num;  
    EA=1;               //开总中断
    EX1=1;              //允许外部中断1  
    IT1=1;               //低电平触发
    beep=1;  
    flag1=0;  
    lcden=0;  
write_ds(0x0A,0x20);   //向ds12c887控制寄存器A发送初始化控制字,启动振荡器  
write_ds(0x0B,0x06);   //向ds12c887控制寄存器B发送初始化控制字,设定工作模式bcd,24 小时制  read_ds(0x0c);         //读芯片时间数据
write_com(0x38);  
write_com(0x0c);       //初始化lcd  
write_com(0x06);  
write_com(0x01);  
write_com(0x80);        //在第一行显示数据  
for(num=0;num<15;num++)
{   
   write_date(table[num]);   
      delay(5);   
}  
write_com(0x80+0x40);       //在第二行显示数据  
for(num=0;num<12;num++)   
{   
    write_date(table1[num]);   
        delay(5);   
  }  
}   
void write_sfm(uchar add,uchar date)   //向lcd写入时分秒数据
{  
  uchar shi,ge;                  //shi:待发数据十位;ge:待发数据个位  
  shi=date/10;  
  ge=date%10;  
  write_com(0x80+0x40+add);  
  write_date(0x30+shi);  
  write_date(0x30+ge);
}   
void write_nyr(uchar add,uchar date)    //向lcd写入年月日数据
{
  uchar shi,ge;                  //shi:待发数据十位;ge:待发数据个位  
  shi=date/10;  
  ge=date%10;  
  write_com(0x80+add);
  write_date(0x30+shi);  
  write_date(0x30+ge);
}   
void write_xingqi(uchar add,uchar date)      //向lcd写入星期数据
{
  write_com(0x80+add);  
  date=(date-1)*3;          //如星期一读表123个字母MON显示,星期二读456字母THU等等    write_date(table2[date]);
  write_date(table2[++date]);  
  write_date(table2[++date]);
}   
void keyscan()                         //键盘扫描子程序
{
if(flag1==1)
{   
if(s2==0)                 //“加”键   
{   
delay(5);   
if(s2==0)   
{     
while(!s2);     
flag1=0;   
}  
}   
if(s3==0)                 //“减”键  
{   
  delay(5);  
  if(s3==0)  
  {   
  while(!s3);     
  flag1=0;   
    }         
   }
}  
if(s1==0)                    //功能选择键,统计按下次数在s1num中  
{   
   delay(5);  
   if(s1==0)  
{   
   s1num++;   
   flag=1;   
   flag1=0;   
   while(!s1);   
   if(s1num==1)  
{     
    TR0=0;     
    write_com(0x80+0x40+11);   
    write_com(0x0f);  
    }  
}   
    if(s1num==2)                      //以下if语句是使光标在对应位置闪烁  
{   
       write_com(0x80+0x40+8);  
}   
if(s1num==3)  
{   
       write_com(0x80+0x40+5);
   }
       if(s1num==4)  
{   
       write_com(0x80+14);
  }   
       if(s1num==5)
  {   
       write_com(0x80+10);
   }   
       if(s1num==6)   
{   
       write_com(0x80+7);   
}   
       if(s1num==7)   
{   
       write_com(0x80+4);
  }   
       if(s1num==8)           //此判断语句显示table5表内容,闹钟状态显示   
{   
    uchar n;   
     write_com(0x80);   
      for(n=0;n<15;n++)
    {     
write_date(table5[n]);   
   }   
write_com(0x80+14);   
}   
if(s1num==9)  
{   
    write_com(0x80+0x40+11);
  }   
    if(s1num==10)
  {   
    write_com(0x80+0x40+8);
  }   
    if(s1num==11)  
{   
    write_com(0x80+0x40+5);  
}   
    if(s1num==12)              //执行时间写入ds12c887芯片操作   
{   
    uchar num;   
    s1num=0;   
    write_com(0x0c);         //设置控制寄存器,状态设置为写   
    flag=0;      
    write_ds(0,miao);
    write_ds(2,fen);   
    write_ds(4,shi);   
    write_ds(6,xingqi);   
    write_ds(7,ri);   
    write_ds(8,yue);   
    write_ds(9,nian);   
    set_alarm(ashi,afen,amiao);   
    write_com(0x80);   
    for(num=0;num<15;num++)   
{   
       write_date(table[num]);   
       delay(5);   
}   
   write_com(0x80+0x40);   
   for(num=0;num<12;num++)   
{   
  write_date(table1[num]);   
delay(5);   
}   
}  
}   
if(s1num!=0)                         //根据s1num按下次数执行相应的数据设置
{  
        if(s2==0)                     //当s2按下时,如果
  {   
          delay(1);   
          if(s2==0)   
{     
while(!s2);   
   if(s1num==1)             //按s1按键1次改秒     
{      
      miao++;      
      if(miao==60)      
      miao=0;     
      write_sfm(10,miao);     
      write_com(0x80+0x40+11);   
  }   
      if(s1num==2)            //按s1按键2次改分     
{      
      fen++;      
      if(fen==60)      
      fen=0;      
      write_sfm(7,fen);     
      write_com(0x80+0x40+8);     
}
          if(s1num==3)           //按s1按键3次改时     
{      
           shi++;      
           if(shi==24)      
           shi=0;      
           write_sfm(4,shi);      
           write_com(0x80+0x40+5);   
}      
          if(s1num==4)           //按s1按键4次改星期     
{      
              xingqi++;     
              if(xingqi==8)      
              xingqi=1;     
              write_xingqi(12,xingqi);     
              write_com(0x80+14);     
}     
          if(s1num==5)            //按s1按键5次改日期  
   {     
              ri++;      
              if(ri==32)      
              ri=1;      
              write_nyr(9,ri);     
              write_com(0x80+10);  
   }     
          if(s1num==6)              //按s1按键6次改月   
  {  
              yue++;   
              if(yue==13)   
              yue=1;   
              write_nyr(6,yue);   
              write_com(0x80+7);   
}   
           if(s1num==7)              //按s1按键7次改年   
  {   
              nian++;   
              if(nian==100)  
              nian=0;   
              write_nyr(3,nian);  
              write_com(0x80+4);  
   }   
           if(s1num==8)            //按s1按键8次改闹钟状态开还是关  
   {   
              uchar n;     
              write_ds(0x0B,0x26);    //向B控制寄存器写入控制字         
              write_com(0x80);
              for(n=0;n<15;n++)      
{      
              write_date(table3[n]);      
}      
           write_com(0x80+14);   
}      
           if(s1num==9)          //按s1按键9次改闹钟时间秒     
{      
              amiao++;     
              if(amiao==60)      
              amiao=0;     
              write_sfm(10,amiao);     
              write_com(0x80+0x40+11);   
   }     
           if(s1num==10)           //按s1按键10次改闹钟时间分     
{   
              afen++;      
              if(afen==60)      
              afen=0;      
              write_sfm(7,afen);     
              write_com(0x80+0x40+8);
    }     
            if(s1num==11)           //按s1按键11次改闹钟时间时   
{     
               ashi++;     
               if(ashi==24)   
               ashi=0;     
               write_sfm(4,ashi);     
               write_com(0x80+0x40+5);   
       }  
     }
   }      
      if(s3==0)  
  {  
        delay(1);
        if(s3==0)                 //当s3按下时,如果:   
{   
while(!s3);   
if(s1num==1)         //按s1按键1次改秒   
{   
   miao--;     
   if(miao==-1)      
   miao=59;      
   write_sfm(10,miao);         
   write_com(0x80+0x40+11);
}     
if(s1num==2)             //按s1按键2次改分     
{   
   fen--;   
   if(fen==-1)     
   fen=59;   
   write_sfm(7,fen);   
   write_com(0x80+0x40+8);   
  }   
  if(s1num==3)              //按s1按键3次改时   
{   
   shi--;     
   if(shi==-1)   
   shi=23;   
   write_sfm(4,shi);  
   write_com(0x80+0x40+5);
    }   
  if(s1num==4)              //按s1按键4次改星期   
{   
   xingqi--;     
   if(xingqi==0)      
   xingqi=7;   
   write_xingqi(12,xingqi);     
   write_com(0x80+14);   
}     
if(s1num==5)             //按s1按键5次改日期   
  {   
    ri--;     
    if(ri==0)      
    ri=31;     
    write_nyr(9,ri);   
    write_com(0x80+10);
       }   
   if(s1num==6)              //按s1按键6次改月   
  {   
   yue--;     
   if(yue==0)   
   yue=12;   
   write_nyr(6,yue);  
   write_com(0x80+7);  
   }   
  if(s1num==7)             //按s1按键7次改年   
  {   
   nian--;      
   if(nian==-1)
   nian=99;     
   write_nyr(3,nian);   
   write_com(0x80+4);  
   }   
  if(s1num==8)            //按s1按键8次改闹钟状态   
{  
    uchar n;     
    write_ds(0x0B,0x06);      
    write_com(0x80);      
    for(n=0;n<15;n++)      
{        
write_date(table4[n]);     
   }   
    write_com(0x80+14);
    }  
   if(s1num==9)             //按s1按键9次改闹钟秒     
{     
     amiao--;     
     if(amiao==-1)   
     amiao=59;   
     write_sfm(10,amiao);
     write_com(0x80+0x40+11);   
  }  
   if(s1num==10)             //按s1按键10次改闹钟分  
   {   
    afen--;   
    if(afen==-1)      
    afen=59;  
    write_sfm(7,afen);  
    write_com(0x80+0x40+8);   
}   
  if(s1num==11)            //按s1按键11次改闹钟时   
  {   
     ashi--;     
     if(ashi==-1)   
     ashi=23;     
     write_sfm(4,ashi);
     write_com(0x80+0x40+5);   
}
    }
   }
}
}   
void write_ds(uchar add,uchar date)     //向DS12c887写入数据子函数
{
dscs=0;
dsas=1;  
dsds=1;
dsrw=1;
P2=add;
dsas=0;
dsrw=0;
P2=date;
dsrw=1;
dsas=1;  
dscs=1;   
  }   
uchar read_ds(uchar add)           //读DS12C887芯片数据,add为寄存器地址,详见表格
{  
  uchar ds_date;  
dsas=1;  
dsds=1;  
dsrw=1;
dscs=0;
P2=add;
dsas=0;
dsds=0;
P2=0xff;
ds_date=P2;  
dsds=1;
dsas=1;  
dscs=1;
return ds_date;
}   
void set_alarm(uchar ashi,uchar afen,uchar amiao)   //向ds12c887写入设置闹钟定时时间子函数 {  
write_ds(1,amiao);  
write_ds(3,afen);  
write_ds(5,ashi);
}  
void main()                            //主函数
{  
init();                             //初始化函数  
while(1)
  {  
    keyscan();
    if(flag1==1)
    beezzer();   
    if(flag==0)  
{
    amiao=read_ds(0);   
    afen=read_ds(2);   
    ashi=read_ds(4);   
    miao=read_ds(0);     
    fen=read_ds(2);   
    shi=read_ds(4);   
    xingqi=read_ds(6);   
    ri=read_ds(7);   
    yue=read_ds(8);   
    nian=read_ds(9);   
    write_sfm(10,miao);   
    write_sfm(7,fen);         
    write_sfm(4,shi);   
    write_xingqi(12,xingqi);      
    write_nyr(9,ri);   
    write_nyr(6,yue);   
    write_nyr(3,nian);  
}
}
}   
void exter() interrupt 2                //外部中断1响应处理函数(改变flag值使蜂鸣器发声)
{
  uchar c;  
  flag1=1;  
  c=read_ds(0x0c);
}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:111634 发表于 2016-11-22 11:06 | 只看该作者
为什么没人解答?如此冗长又无注释的程序,谁有空或耐心看?叫人猜谜揣摩吗???
回复

使用道具 举报

板凳
ID:111634 发表于 2016-11-22 16:02 | 只看该作者
!“大神”门,快来吧!
回复

使用道具 举报

地板
ID:85726 发表于 2016-11-22 17:19 | 只看该作者
其他的先不看,一个模块一个模块的去排查!首先是LCD1602的驱动代码有没有问题,先不要让其显示从C887中读取的数据!可以让他显示简单的东西,如数字!如没问题,接着就是C887的驱动了,多部分问题都是出在这里!特别是写指令和写数据函数,时序一定要严格按照数据手册上的来,(注意你自己写的延时函数),写指令和写数据函数没问题的话,接着就是读取函数了,不要把寄存器的地址搞错了!当然了,以上的这些都要基于硬件100%没问题的基础上进行,如果硬件有问题,那一切免谈!有问题先自己一步一步来排查,养成习惯,对你只有好处,没有坏处!
回复

使用道具 举报

5#
ID:149513 发表于 2016-11-22 17:23 | 只看该作者
放那么长
回复

使用道具 举报

6#
ID:70330 发表于 2016-11-23 10:43 | 只看该作者
先排查硬件问题,没有的话,去掉时钟电路,让1602只显示一个字符串,看是否好用,好用的话,就检查时钟部分的程序。软件问题一般都是延时时序不对
回复

使用道具 举报

7#
ID:149324 发表于 2016-11-23 12:42 | 只看该作者
xsynet 发表于 2016-11-23 10:43
先排查硬件问题,没有的话,去掉时钟电路,让1602只显示一个字符串,看是否好用,好用的话,就检查时钟部分 ...

谢谢。已经解决了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表