找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2530|回复: 3
收起左侧

自己写的ds1302时钟程序 数码管调节时间一个暗一个亮的

[复制链接]
ID:282981 发表于 2018-3-5 12:40 | 显示全部楼层 |阅读模式
//有些地方没删除,是调试的时候用的。请专家帮看看,为什么我写到开发板上,数码管调节时间一个暗一个亮的,
功能:显示时钟
          显示日期
         调节时钟日期
四位数码管显示

  1. #include<reg52.h>
  2. #include<intrins.h>
  3. sbit Ge=P0^0 ;  //数码管段
  4. sbit Shi=P0^1 ;
  5. sbit Bai=P0^2 ;
  6. sbit Qian = P0^3;

  7. sbit SCK = P1^0; //DS1302模块
  8. sbit DS = P1^1;
  9. sbit CE = P1^2;

  10. sbit KEY1=P1^3;  //按键
  11. sbit KEY2=P1^4;

  12. void configTime0(unsigned int ms);//配置定时器0配置中断
  13. void configUART(unsigned int begin);//配置UART串口通信设置波特率

  14. void Shownum();  //扫描函数
  15. void display(); //数码管刷新函数

  16. void Write_ds1302(unsigned char dat); //写1302函数1字节
  17. void Write_ds1302_CE(unsigned char cmd,unsigned char dat); //读取1302函数1字节 对命令处理
  18. //void read_ds1302_burst(unsigned char *dat); //burst模式读取8个字节 突发模式
  19. void initds1302();//初始化ds1302
  20. void keyset();
  21. void keycan();
  22. unsigned char Read_ds1302_CE(unsigned char cmd); //1302函数1字节 对命令处理
  23. unsigned char Read_ds1302(); //读取1302函数1字节

  24. unsigned char Smg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//真值表 123456789abcdefg
  25. unsigned char SmgI[] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};//带标点的真值表1.2.3.4.5.6.7.8.9.
  26. unsigned char SmgTmp[8];//数码管缓存


  27. unsigned char Time[8]; //时间缓存
  28. unsigned char Tmp[4]; //调节时间的数组//0~分钟 1~小时 2~天 3~月
  29. unsigned char flg = 1;//决定显示日期还是时间
  30. unsigned char T0RL,T0RH;//重装定时器时间

  31. unsigned char flg0,flg1,set0,set1;
  32. bit backup0,backup1;

  33. bit gb;
  34. void main()
  35. {
  36.         EA = 1;
  37.         configTime0(500);
  38.         configUART(9600);
  39.         initds1302();
  40.         while(1)
  41.         {
  42.                 Shownum();
  43.                 keyset();
  44.         }
  45. }

  46. void Shownum()  //扫描函数
  47. {
  48.         static unsigned char i;
  49. if(flg0==0){
  50.         for(i=0;i<7;i++)
  51.                 {
  52.                         Time[i]=Read_ds1302_CE(i);
  53.                 }
  54.                         
  55.                 gb = (bit)(Read_ds1302_CE(0)&0x01);//将ds1302秒寄存器最低位取出用于数码管中间的两个点闪烁
  56.                  SmgTmp[0]=(Time[1]&0x0F);     //显示分钟,小时
  57.            SmgTmp[1]=(Time[1]>>4);
  58.            SmgTmp[2]=(Time[2]&0x0F);
  59.            SmgTmp[3]=(Time[2]>>4);
  60.         
  61.            SmgTmp[4]=Time[3]&0x0F;    //显示日期,月份
  62.            SmgTmp[5]=Time[3]>>4;
  63.            SmgTmp[6]=Time[4]&0x0F;
  64.            SmgTmp[7]=Time[4]>>4;


  65.         }
  66.         
  67. }

  68. void configTime0(unsigned int m)  //配置定时器0配置中断
  69. {
  70.         
  71.         T0RH =(65536-m)/256;
  72.         T0RL =(65536-m)%256;
  73.         
  74.         TMOD &=0xF0;
  75.         TMOD |=0x01;
  76.         TH0=T0RH;
  77.         TL0=T0RL;
  78.         ET0 = 1;
  79.         TR0 = 1;
  80. }
  81. void configUART(unsigned int begin)  //配置UART串口通信设置波特率
  82. {
  83.         SCON = 0x50;
  84.         TMOD &=0x0F;
  85.         TMOD |=0x20;
  86.         TH1=256-(11059200/12/32)/begin;
  87.         TL1=TH1;
  88.         ET1 = 0;
  89.         ES = 1;
  90.         TR1 = 1;
  91. }
  92. void Write_ds1302(unsigned char dat) //写1302函数1字节
  93. {
  94.         unsigned char mask;

  95.     for (mask=0x01; mask!=0; mask<<=1)  //低位在前,逐位移出
  96.     {
  97.         if ((mask&dat) != 0) //首先输出该位数据
  98.             DS = 1;
  99.         else
  100.             DS = 0;
  101.         SCK = 1;       //然后拉高时钟
  102.         SCK = 0;       //再拉低时钟,完成一个位的操作
  103.     }
  104.     DS = 1;
  105.         }                //最后确保释放IO引脚
  106. unsigned char Read_ds1302() //读取1302函数1字节
  107. {
  108.           unsigned char mask;
  109.     unsigned char dat = 0;

  110.     for (mask=0x01; mask!=0; mask<<=1)  //低位在前,逐位读取
  111.     {
  112.         if (DS!= 0)  //首先读取此时的IO引脚,并设置dat中的对应位
  113.         {
  114.             dat |= mask;
  115.         }
  116.         SCK = 1;       //然后拉高时钟
  117.         SCK = 0;       //再拉低时钟,完成一个位的操作
  118.     }
  119.     return dat;              //最后返回读到的字节数据
  120. }

  121. void Write_ds1302_CE(unsigned char cmd,unsigned char dat) //读取1302函数1字节 对命令处理
  122. {
  123.         CE = 1;
  124.         Write_ds1302((cmd<<1)|0x80);
  125.         Write_ds1302(dat);
  126.         CE = 0;
  127. }
  128. unsigned char Read_ds1302_CE(unsigned char cmd) //1302函数1字节 对命令处理
  129. {
  130.         unsigned char dat;
  131.         CE = 1;
  132.         Write_ds1302((cmd<<1)|0x81);
  133.         dat=Read_ds1302();
  134.         CE = 0;
  135.         
  136.         return dat;
  137. }
  138. /*void write_ds1302_burst(unsigned char *dat)  //burst模式写8个字节 突发模式
  139. {
  140.         unsigned char i;
  141.         
  142.         CE = 1;
  143.         Write_ds1302(0xBE);
  144.         for(i=0;i<8;i++)
  145.         {
  146.     Write_ds1302(dat[i]);

  147.         }
  148.         CE = 0;
  149. }
  150. void read_ds1302_burst(unsigned char *dat)  //burst模式读取8个字节 突发模式
  151. {
  152.         unsigned char i;
  153.         
  154.         CE = 1;
  155.         Write_ds1302(0xBF);
  156.         for(i=0;i<8;i++)
  157.         {
  158.                 dat[i]=Read_ds1302;
  159.         }
  160.         CE = 0;
  161. }*/
  162. void initds1302()
  163. {
  164.         unsigned char dat ;
  165.         unsigned char code init[]={0x00,0x56,0x20,0x28,0x02,0x05,0x18};  //2018 2 16 20 20 00
  166.   CE = 0;
  167.   SCK = 0;
  168.         dat=Read_ds1302_CE(0);
  169.         if((dat&0x80)!=0)
  170.         {
  171.                 Write_ds1302_CE(7,0x00);
  172.                 for(dat=0;dat<8;dat++)
  173.                 {
  174.                         Write_ds1302_CE(dat,init[dat]);
  175.                 }
  176.                 Write_ds1302_CE(7,0x80);
  177.         }
  178. }
  179.         void display(unsigned char a,unsigned char b,unsigned char c,unsigned char d) //数码管刷新函数
  180. {
  181.         static unsigned char i = 0;

  182.         
  183.                   P2 = 0xFF;
  184.             switch(i)//调用不带标点的数组
  185.             {
  186.                   case 0:Qian = 1;Bai = 1;Shi = 1;Ge = 0;i++;P2 = Smg[a];break;
  187.                   case 1:Qian = 1;Bai = 1;Shi = 0;Ge = 1;i++;P2 = Smg[b];break;
  188.                   case 2:Qian = 1;Bai = 0;Shi = 1;Ge = 1;i++;P2 = Smg[c];break;
  189.                   case 3:Qian = 0;Bai = 1;Shi = 1;Ge = 1;i=0;P2 = Smg[d];break;
  190.                   default:break;
  191.             }
  192.           }
  193. void displayI(unsigned char a,unsigned char b,unsigned char c,unsigned char d) //数码管刷新函数代表点
  194. {
  195.         static unsigned char i = 0;

  196.         
  197.                   P2 = 0xFF;
  198.             switch(i)//调用不带标点的数组
  199.             {
  200.                   case 0:Qian = 1;Bai = 1;Shi = 1;Ge = 0;i++;P2 = Smg[a];break;
  201.                   case 1:Qian = 1;Bai = 1;Shi = 0;Ge = 1;i++;P2 = SmgI[b];break;
  202.                   case 2:Qian = 1;Bai = 0;Shi = 1;Ge = 1;i++;P2 = SmgI[c];break;
  203.                   case 3:Qian = 0;Bai = 1;Shi = 1;Ge = 1;i=0;P2 = Smg[d];break;
  204.                   default:break;
  205.             }
  206.           }
  207. void keycan()
  208. {
  209.         static unsigned char keybuf[]={0xFF,0xFF};

  210.                 keybuf[0]=(keybuf[0]<<1)|KEY1;
  211.           keybuf[1]=(keybuf[1]<<1)|KEY2;

  212. if(keybuf[0]==0xFF)
  213. {
  214.         set0 = 1;
  215. }
  216. else if(keybuf[0]==0x00)
  217. {
  218.         set0 = 0;
  219. }
  220. else
  221. {}
  222.         if(keybuf[1]==0xFF)
  223. {
  224.         set1 = 1;
  225. }
  226. else if(keybuf[1]==0x00)
  227. {
  228.         set1 = 0;
  229. }
  230. else
  231. {}
  232. }
  233. void keyset()
  234. {
  235.         if(set0!=backup0)
  236.         {
  237.                 backup0 = set0;
  238.                 if(set0==0)
  239.                 {
  240.                         flg0++;
  241.                         if(flg0>5)
  242.                         {
  243.                                 flg0=0;
  244.                         }
  245.                 }
  246.   }
  247.         
  248.         switch(flg0)
  249.         {
  250.                

  251.           case 1: P2 = 0xFF;Qian = 1;Bai = 1;Shi = 1;Ge = 0;P2 = Smg[SmgTmp[0]];//小时的个位
  252.                         P2 = 0xFF;Qian = 1;Bai = 1;Shi = 0;Ge = 1;P2 = SmgI[SmgTmp[1]];break; //小时的十位
  253.                
  254.                 case 2: P2 = 0xFF;Qian = 1;Bai = 0;Shi = 1;Ge = 1;P2 = SmgI[SmgTmp[2]];//分钟的个  位
  255.                         P2 = 0xFF;Qian = 0;Bai = 1;Shi = 1;Ge = 1;P2 = Smg[SmgTmp[3]];break;//分钟的十位
  256.                
  257.                 case 3: P2 = 0xFF;Qian = 1;Bai = 1;Shi = 1;Ge = 0;P2 = Smg[SmgTmp[4]];//月份的个位
  258.                               P2 = 0xFF;Qian = 1;Bai = 1;Shi = 0;Ge = 1;P2 = Smg[SmgTmp[5]];break;//月份的十位
  259.                
  260.                 case 4: P2 = 0xFF;Qian = 1;Bai = 0;Shi = 1;Ge = 1;P2 = Smg[SmgTmp[6]];//日期的个位
  261.                               P2 = 0xFF;Qian = 0;Bai = 1;Shi = 1;Ge = 1;P2 = Smg[SmgTmp[7]];break;//日期十位
  262.                 case 5:  Write_ds1302_CE(7,0x00);
  263.                          Write_ds1302_CE(1,SmgTmp[1]<<4|SmgTmp[0]);
  264.                          Write_ds1302_CE(2,SmgTmp[3]<<4|SmgTmp[2]);
  265.                          Write_ds1302_CE(3,SmgTmp[5]<<4|SmgTmp[4]);
  266.                    Write_ds1302_CE(4,SmgTmp[7]<<4|SmgTmp[6]);
  267.                                Write_ds1302_CE(7,0x80);
  268.                          flg0 = 0;
  269.                 default:break;
  270. }   
  271.         
  272. if(flg0!=0)
  273. {
  274.         if(set1!=backup1)
  275.         {
  276.                 backup1 = set1;
  277.           if(set1==0)
  278.                 {
  279.                 switch(flg0)
  280.         {
  281.                 case 1: Tmp[0]=(SmgTmp[1]*10)+SmgTmp[0];Tmp[0]++;if(Tmp[0]>=60)Tmp[0]=0;SmgTmp[0]=Tmp[0]%10;SmgTmp[1]=Tmp[0]/10;break;
  282.                 case 2: Tmp[1]=(SmgTmp[3]*10)+SmgTmp[2];Tmp[1]++;if(Tmp[1]>=24)Tmp[1]=0;SmgTmp[2]=Tmp[1]%10;SmgTmp[3]=Tmp[1]/10;break;
  283.                 case 3: Tmp[2]=(SmgTmp[5]*10)+SmgTmp[4];Tmp[2]++;if(Tmp[2]>=31)Tmp[2]=0;SmgTmp[4]=Tmp[2]%10;SmgTmp[5]=Tmp[2]/10;break;
  284.                 case 4: Tmp[3]=(SmgTmp[7]*10)+SmgTmp[6];Tmp[3]++;if(Tmp[3]>=12)Tmp[3]=0;SmgTmp[6]=Tmp[3]%10;SmgTmp[7]=Tmp[3]/10;break;
  285.                 default:break;
  286.           }
  287.         }
  288. }
  289. }
  290. }


  291. void interruptTime() interrupt 1 //定时器0
  292. {
  293.         static unsigned int i;
  294.         
  295.         TH0=T0RH;
  296.         TL0=T0RL;
  297.         
  298.         i++;
  299.         if(i==6000)
  300.         {
  301.                 i=0;
  302.                 flg=~flg;
  303.         }
  304.         if(flg0==0)
  305.         {
  306.         if(flg == 1)
  307.         {
  308.                 if(gb==0)
  309.                   {
  310.         display(SmgTmp[0],SmgTmp[1],SmgTmp[2],SmgTmp[3]);
  311.       }
  312.           else
  313.             {
  314.                 displayI(SmgTmp[0],SmgTmp[1],SmgTmp[2],SmgTmp[3]);
  315.             }
  316.         }
  317.         else
  318.   {
  319.                 display(SmgTmp[4],SmgTmp[5],SmgTmp[6],SmgTmp[7]);
  320.   }
  321. }
  322. keycan();

  323. }




  324. void interruptUART() interrupt 4  //串口
  325. {
  326.         static unsigned char i;
  327.         if(RI)
  328.         {
  329.                 RI = 0;
  330.                 i = SBUF;
  331.                 SBUF = SmgTmp[i];
  332.                
  333.         }
  334.         if(TI)
  335.         {
  336.                 TI = 0;
  337.         }
  338. }
复制代码
回复

使用道具 举报

ID:287818 发表于 2018-3-5 16:24 | 显示全部楼层
按键扫描或者数码管显示时间,,,,找一找

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:287854 发表于 2018-3-5 17:43 | 显示全部楼层
第一:数码管调节时间一个暗一个亮的  这句话是什么意思?  是你调节的时候一个数码管亮,一个数码管暗。还是调节的时候闪烁。
第二 :是不是在调节的时候就会这样,其他使用的时候会吗?
硬件如果没有问题, 就查找延时 可是我没发现
格式我就不多说了
unsigned char flg = 1;//决定显示日期还是时间
这个是什么意思 !
主程序最好设置轮询机制不然, 万一卡死怎么办。

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:282981 发表于 2018-3-6 13:11 来自手机 | 显示全部楼层
创太#铭 发表于 2018-3-5 17:43
第一:数码管调节时间一个暗一个亮的  这句话是什么意思?  是你调节的时候一个数码管亮,一个数码管暗。还 ...

初学者,抱歉。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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