[51单片机] ds12c887 时间不更新

[复制链接]
1160|3
 楼主| jijif 发表于 2015-11-2 11:44 | 显示全部楼层 |阅读模式

  1. #include<reg52.h>
  2. sbit lcden=P3^4;
  3. sbit lcdrs=P3^5;
  4. sbit dscs=P1^4;
  5. sbit dsas=P1^5;
  6. sbit dsrw=P1^6;
  7. sbit dsds=P1^7;
  8. char filine[14]="2015-10-18 MON";
  9. char seline[10]=" 00:00:00 ";
  10. char sec,min,hor;
  11. int m,n;
  12. int num;
  13. void delay(int m)
  14. {
  15.         int n;
  16.         for(;m>=0;m--)
  17.         for(n=110;n>=0;n--);
  18. }

  19. void write_command(char com)
  20. {//液晶命令
  21.         lcdrs=0;
  22.         lcden=0;
  23.         P0=com;
  24.         delay(5);
  25.         lcden=1;
  26.         delay(5);
  27.         lcden=0;
  28. }
  29. void write_date(char date)
  30. {//液晶数据
  31.         lcdrs=1;
  32.         lcden=0;
  33.         P0=date;
  34.         delay(5);
  35.         lcden=1;
  36.         delay(5);
  37.         lcden=0;
  38. }
  39. /*void write_ds(char address,char date)
  40. {
  41.         dscs=0;
  42.         dsas=1;
  43.         dsds=1;
  44.         dsrw=0;
  45.         P0=address;
  46.         dsas=0;
  47.         dsrw=0;
  48.         P0=date;
  49.         dsrw=1;
  50.         dsas=1;
  51.         dscs=1;
  52.        
  53. }*/
  54. char read_ds(char address)
  55. {
  56.         char ds_date;
  57.         dsas=1;
  58.         dsds=1;
  59.         dsrw=1;
  60.         dscs=0;
  61.         P0=address;
  62.         dsas=0;
  63.         dsds=0;
  64.         P0=0xff;
  65.         ds_date=P0;
  66.         dsds=1;
  67.         dsas=1;
  68.         dscs=1;
  69.         return ds_date;       
  70. }

  71. void init()
  72. {
  73.         write_command(0x38);
  74.         write_command(0x0c);
  75.         write_command(0x06);
  76.         write_command(0x01);
  77.         write_command(0x80);

  78.         for(m=0;m<14;m++)
  79.         write_date(filine[m]);
  80.         write_command(0x80+0x40);
  81.         for(m=0;m<10;m++)
  82.         write_date(seline[m]);
  83. }
  84. void display_number(char address,char number)
  85. {
  86.         char ge,shi;
  87.         shi=number/10;
  88.         ge=number%10;
  89.         write_command(0x80+0x40+address);
  90.         write_date(0x30+shi);
  91.         write_date(0x30+ge);
  92. }


  93. void main()
  94. {
  95.         num=0;
  96.         init();
  97.         delay(50);
  98.         while(1)
  99.         {
  100.                 sec=read_ds(0);
  101.                 display_number(7,sec);
  102.                
  103.                        
  104.         }
  105. }

秒针不更新一直显示/0,配套的代码却可以更新,谁给分析分析,谢谢。
 楼主| jijif 发表于 2015-11-2 11:46 | 显示全部楼层
NE5532 发表于 2015-11-2 12:45 | 显示全部楼层
“配套的”代码是什么?比照着看一下时序,你输入给FF的地方是不是太晚了,应该在数据上线以前就置输入,另外既然是用51,为何不用外部总线,要用模拟时序??
 楼主| jijif 发表于 2015-11-2 16:19 | 显示全部楼层
  1. #include<reg52.h>
  2. #include<define.h>

  3. void delay(uint z)//延时函数
  4. {
  5.         uint x,y;
  6.         for(x=z;x>0;x--)
  7.                 for(y=110;y>0;y--);
  8. }
  9. void di() //蜂鸣器报警声音
  10. {
  11.         beep=0;
  12.         delay(100);
  13.         beep=1;
  14. }
  15. void write_com(uchar com)
  16. {//写液晶命令函数
  17.         rs=0;
  18.         lcden=0;
  19.         P0=com;
  20.         delay(3);
  21.         lcden=1;
  22.         delay(3);
  23.         lcden=0;       
  24. }
  25. void write_date(uchar date)
  26. {//写液晶数据函数
  27.         rs=1;
  28.         lcden=0;
  29.         P0=date;
  30.         delay(3);
  31.         lcden=1;
  32.         delay(3);
  33.         lcden=0;       
  34. }
  35. void init()
  36. {//初始化函数
  37.         uchar num;
  38.         EA=1;//打开总中断
  39.         EX1=1;//开外部中断1
  40.         IT1=1;//设置负跳变沿触发中断
  41.         flag1=0;//变量初始化
  42.         t0_num=0;
  43.         s1num=0;
  44.         week=1;
  45.         dula=0;//关闭数码管显示
  46.         wela=0;
  47.         lcden=0;
  48.         rd=0;
  49. /*以下几行在首次设置DS12C887时使用,以后不必再写入*/
  50.         write_ds(0x0A,0x20);//打开振荡器
  51.         write_ds(0x0B,0x26);//设置24小时模式,数据二进制格式
  52.                                                 //开启闹铃中断
  53.         set_time();//设置上电默认时间
  54. //-----------------------------------------------------
  55.         write_com(0x38);//1602液晶初始化
  56.         write_com(0x0c);
  57.         write_com(0x06);
  58.         write_com(0x01);
  59.         write_com(0x80);
  60.         for(num=0;num<15;num++)//写入液晶固定部分显示
  61.                 {
  62.                         write_date(table[num]);
  63.                         delay(1);
  64.                 }
  65.         write_com(0x80+0x40);
  66.         for(num=0;num<11;num++)
  67.                 {
  68.                         write_date(table1[num]);
  69.                         delay(1);
  70.                 }
  71. }
  72. void write_sfm(uchar add,char date)
  73. {//1602液晶刷新时分秒函数4为时,7为分,10为秒
  74.         char shi,ge;
  75.         shi=date/10;
  76.         ge=date%10;
  77.         write_com(0x80+0x40+add);
  78.         write_date(0x30+shi);
  79.         write_date(0x30+ge);
  80. }
  81. void write_nyr(uchar add,char date)
  82. {//1602液晶刷新年月日函数3为年,6为分,9为秒
  83.         char shi,ge;
  84.         shi=date/10;
  85.         ge=date%10;
  86.         write_com(0x80+add);
  87.         write_date(0x30+shi);
  88.         write_date(0x30+ge);
  89. }
  90. void write_week(char we)
  91. {//写液晶星期显示函数
  92.         write_com(0x80+12);
  93.         switch(we)
  94.         {
  95.                 case 1:        write_date('M');delay(5);
  96.                                 write_date('O');delay(5);
  97.                                 write_date('N');
  98.                                 break;
  99.                 case 2:        write_date('T');delay(5);
  100.                                 write_date('U');delay(5);
  101.                                 write_date('E');
  102.                                 break;
  103.                 case 3:        write_date('W');delay(5);
  104.                                 write_date('E');delay(5);
  105.                                 write_date('D');
  106.                                 break;
  107.                 case 4:        write_date('T');delay(5);
  108.                                 write_date('H');delay(5);
  109.                                 write_date('U');
  110.                                 break;
  111.                 case 5:        write_date('F');delay(5);
  112.                                 write_date('R');delay(5);
  113.                                 write_date('I');
  114.                                 break;
  115.                 case 6:        write_date('S');delay(5);
  116.                                 write_date('A');delay(5);
  117.                                 write_date('T');
  118.                                 break;
  119.                 case 7:        write_date('S');delay(5);
  120.                                 write_date('U');delay(5);
  121.                                 write_date('N');
  122.                                 break;
  123.         }
  124. }
  125. void keyscan()
  126. {
  127.         if(flag_ri==1)
  128.         {//这里用来取消闹钟报警,任一键取消报警
  129.                 if((s1==0)||(s2==0)||(s3==0)||(s4==0))
  130.                 {       
  131.                         delay(5);
  132.                         if((s1==0)||(s2==0)||(s3==0)||(s4==0))
  133.                         {
  134.                                 while(!(s1&&s2&&s3&&s4));
  135.                 di();
  136.                                 flag_ri=0;//清除报警标志
  137.                         }                
  138.                 }
  139.         }       
  140.         if(s1==0)//检测S1
  141.         {
  142.                 delay(5);
  143.                 if(s1==0)
  144.                 {       
  145.                         s1num++;//记录按下次数
  146.                         if(flag1==1)
  147.                                 if(s1num==4)
  148.                                         s1num=1;
  149.                         flag=1;
  150.                         while(!s1);di();
  151.                         switch(s1num)
  152.                         {//光标闪烁点定位
  153.                                 case 1: write_com(0x80+0x40+10);
  154.                                             write_com(0x0f);
  155.                                                 break;
  156.                                 case 2: write_com(0x80+0x40+7);
  157.                                                 break;
  158.                                 case 3: write_com(0x80+0x40+4);
  159.                                                 break;
  160.                                 case 4: write_com(0x80+12);
  161.                                                 break;
  162.                                 case 5: write_com(0x80+9);
  163.                                                 break;
  164.                                 case 6: write_com(0x80+6);
  165.                                                 break;
  166.                                 case 7: write_com(0x80+3);
  167.                                                 break;
  168.                                 case 8: s1num=0;
  169.                                                 write_com(0x0c);
  170.                                                 flag=0;
  171.                                                 write_ds(0,miao);
  172.                                                 write_ds(2,fen);
  173.                                                 write_ds(4,shi);
  174.                                                 write_ds(6,week);
  175.                                                 write_ds(7,day);
  176.                                                 write_ds(8,month);
  177.                                                 write_ds(9,year);
  178.                                                 break;
  179.                         }       
  180.                 }
  181.         }
  182.         if(s1num!=0)//只有当S1按下后,才检测S2和S3
  183.         {
  184.                 if(s2==0)
  185.                 {
  186.                         delay(1);
  187.                         if(s2==0)
  188.                         {
  189.                                 while(!s2);di();
  190.                                 switch(s1num)
  191.                                 {//根据功能键次数调节相应数值
  192.                                         case 1:        miao++;
  193.                                                         if(miao==60)
  194.                                                                 miao=0;
  195.                                                         write_sfm(10,miao);
  196.                                                         write_com(0x80+0x40+10);
  197.                                                         break;
  198.                                         case 2:        fen++;
  199.                                                         if(fen==60)
  200.                                                                 fen=0;
  201.                                                         write_sfm(7,fen);
  202.                                                         write_com(0x80+0x40+7);
  203.                                                         break;
  204.                                         case 3:        shi++;
  205.                                                         if(shi==24)
  206.                                                                 shi=0;
  207.                                                         write_sfm(4,shi);
  208.                                                         write_com(0x80+0x40+4);
  209.                                                         break;
  210.                                         case 4:        week++;
  211.                                                         if(week==8)
  212.                                                                 week=1;
  213.                                                         write_week(week);
  214.                                                         write_com(0x80+12);
  215.                                                         break;
  216.                                         case 5:        day++;
  217.                                                         if(day==32)
  218.                                                                 day=1;
  219.                                                         write_nyr(9,day);
  220.                                                         write_com(0x80+9);
  221.                                                         break;
  222.                                         case 6:        month++;
  223.                                                         if(month==13)
  224.                                                                 month=1;
  225.                                                         write_nyr(6,month);
  226.                                                         write_com(0x80+6);
  227.                                                         break;
  228.                                         case 7:        year++;
  229.                                                         if(year==100)
  230.                                                                 year=0;
  231.                                                         write_nyr(3,year);
  232.                                                         write_com(0x80+3);
  233.                                                         break;
  234.                                 }
  235.                         }
  236.                 }
  237.                 if(s3==0)
  238.                 {
  239.                         delay(1);
  240.                         if(s3==0)
  241.                         {
  242.                                 while(!s3);di();
  243.                                 switch(s1num)
  244.                                 {//根据功能键次数调节相应数值
  245.                                         case 1:        miao--;
  246.                                                         if(miao==-1)
  247.                                                                 miao=59;
  248.                                                         write_sfm(10,miao);
  249.                                                         write_com(0x80+0x40+10);
  250.                                                         break;
  251.                                         case 2:        fen--;
  252.                                                         if(fen==-1)
  253.                                                                 fen=59;
  254.                                                         write_sfm(7,fen);
  255.                                                         write_com(0x80+0x40+7);
  256.                                                         break;
  257.                                         case 3:        shi--;
  258.                                                         if(shi==-1)
  259.                                                                 shi=23;
  260.                                                         write_sfm(4,shi);
  261.                                                         write_com(0x80+0x40+4);
  262.                                                         break;
  263.                                         case 4:        week--;
  264.                                                         if(week==0)
  265.                                                                 week=7;
  266.                                                         write_week(week);
  267.                                                         write_com(0x80+12);
  268.                                                         break;
  269.                                         case 5:        day--;
  270.                                                         if(day==0)
  271.                                                                 day=31;
  272.                                                         write_nyr(9,day);
  273.                                                         write_com(0x80+9);
  274.                                                         break;
  275.                                         case 6:        month--;
  276.                                                         if(month==0)
  277.                                                                 month=12;
  278.                                                         write_nyr(6,month);
  279.                                                         write_com(0x80+6);
  280.                                                         break;
  281.                                         case 7:        year--;
  282.                                                         if(year==-1)
  283.                                                                 year=99;
  284.                                                         write_nyr(3,year);
  285.                                                         write_com(0x80+3);
  286.                                                         break;
  287.                                 }
  288.                         }
  289.                 }
  290.         }
  291.         if(s4==0)//检测S4
  292.         {
  293.                 delay(5);
  294.                 if(s4==0)
  295.                 {       
  296.                         flag1=~flag1;
  297.                         while(!s4);di();
  298.                         if(flag1==0)
  299.                         {//退出闹钟设置时保存数值
  300.                                 flag=0;
  301.                                 write_com(0x80+0x40);
  302.                                 write_date(' ');
  303.                                 write_date(' ');
  304.                                 write_com(0x0c);
  305.                                 write_ds(1,miao);
  306.                                 write_ds(3,fen);
  307.                                 write_ds(5,shi);                               
  308.                         }
  309.                         else
  310.                         {//进入闹钟设置
  311.                                 read_alarm();//读取原始数据
  312.                                 miao=amiao;//重新赋值用以按键调节
  313.                                 fen=afen;
  314.                                 shi=ashi;
  315.                                 write_com(0x80+0x40);
  316.                                 write_date('R');//显示标志
  317.                                 write_date('i');
  318.                                 write_com(0x80+0x40+3);
  319.                                 write_sfm(4,ashi);//送液晶显示闹钟时间
  320.                                 write_sfm(7,afen);
  321.                                 write_sfm(10,amiao);
  322.                         }                       
  323.                 }
  324.         }
  325. }

  326. void write_ds(uchar add,uchar date)
  327. {//写12C887函数
  328.         dscs=0;
  329.         dsas=1;
  330.         dsds=1;
  331.         dsrw=1;
  332.         P0=add;//先写地址
  333.         dsas=0;
  334.         dsrw=0;
  335.         P0=date;//再写数据
  336.         dsrw=1;
  337.         dsas=1;
  338.         dscs=1;                               
  339. }

  340. uchar read_ds(uchar add)
  341. {//读12C887函数
  342.         uchar ds_date;
  343.         dsas=1;
  344.         dsds=1;
  345.         dsrw=1;
  346.         dscs=0;
  347.         P0=add;//先写地址
  348.         dsas=0;
  349.         dsds=0;
  350.         P0=0xff;
  351.         ds_date=P0;//再读数据
  352.         dsds=1;
  353.         dsas=1;
  354.         dscs=1;
  355.         return ds_date;       
  356. }
  357. /*---首次操作12C887时给予寄存器初始化---*/
  358. void set_time()
  359. {//首次上电初始化时间函数
  360.         write_ds(0,0);
  361.         write_ds(1,0);
  362.         write_ds(2,0);
  363.         write_ds(3,0);
  364.         write_ds(4,0);
  365.         write_ds(5,0);
  366.         write_ds(6,0);
  367.         write_ds(7,0);
  368.         write_ds(8,0);
  369.         write_ds(9,0);       
  370. }
  371. //----------------------------------------
  372. void read_alarm()
  373. {//读取12C887闹钟值
  374.         amiao=read_ds(1);
  375.         afen=read_ds(3);
  376.         ashi=read_ds(5);
  377. }
  378. void main()//主函数
  379. {
  380.         init();//调用初始化函数
  381.         while(1)
  382.         {
  383.                 keyscan();//按键扫描
  384.                 if(flag_ri==1)//当闹钟中断时进入这里
  385.                 {
  386.                         di();
  387.                         delay(100);
  388.                         di();
  389.                         delay(500);
  390.                 }       
  391.                 if(flag==0&&flag1==0)//正常工作时进入这里
  392.                 {
  393.                         keyscan();//按键扫描
  394.                         year=read_ds(9);//读取12C887数据
  395.                         month=read_ds(8);       
  396.                         day=read_ds(7);
  397.                         week=read_ds(6);
  398.                         shi=read_ds(4);
  399.                         fen=read_ds(2);
  400.                         miao=read_ds(0);       
  401.                         write_sfm(10,miao);//送液晶显示
  402.                         write_sfm(7,fen);
  403.                         write_sfm(4,shi);
  404.                         write_week(week);
  405.                         write_nyr(3,year);
  406.                         write_nyr(6,month);
  407.                         write_nyr(9,day);
  408.                 }
  409.         }
  410. }

  411. void exter() interrupt 2//外部中断1服务程序
  412. {        uchar c; //进入中断表示闹钟时间到,
  413.         flag_ri=1; //设置标志位,用以大程序中报警提示
  414.         c=read_ds(0x0c);//读取12C887的C寄存器表示响应了中断
  415. }
  1. #define uchar unsigned char
  2. #define uint unsigned int
  3. sbit dula=P2^6;
  4. sbit wela=P2^7;
  5. sbit rs=P3^5;
  6. sbit lcden=P3^4;
  7. sbit s1=P3^0;//功能键
  8. sbit s2=P3^1;//增加键
  9. sbit s3=P3^2;//减小键
  10. sbit s4=P3^6;//闹钟查看键
  11. sbit rd=P3^7;
  12. sbit beep=P2^3;//蜂鸣器
  13. sbit dscs=P1^4;
  14. sbit dsas=P1^5;
  15. sbit dsrw=P1^6;
  16. sbit dsds=P1^7;
  17. sbit dsirq=P3^3;
  18. bit flag1,flag_ri;//定义两个位变量
  19. uchar count,s1num,flag,t0_num;//其它变量定义
  20. char miao,shi,fen,year,month,day,week,amiao,afen,ashi;
  21. uchar code table[]=" 20  -  -      ";//液晶固定显示内容
  22. uchar code table1[]="      :  :  ";
  23. void write_ds(uchar,uchar);//函数申明
  24. void set_alarm(uchar,uchar,uchar);void read_alarm();
  25. uchar read_ds(uchar);void set_time();
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

3

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部