找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机时钟另类调时法 个十位分开调节

[复制链接]
跳转到指定楼层
楼主
仿真 实物都通过.stc89c52  11.0592MHz晶振 ;具体电路见仿真图;仿真用5位数码管显示88-88的样式

一个按键调节时间:

1.长按key1,进入调时状态,小时十位开始闪烁,此时再短按key1,小时十位加加,
  小时十位在0-2之间变化;(key1可以是按钮,也可以用触摸开关)
2.调好后,过5秒自动跳到小时个位闪烁,此时再短按key1,小时个位加加,如果十位是0、1,
  小时个位再0-9之间变化;如果十位是2,小时个位在0-3之间变化;
3.小时个位调好后,过5秒,分钟十位开始闪烁,此时再短按key1,分钟十位加加,分钟十位在0-5
  之间变化;
4.分钟十位调好后,过5秒,分钟个位开始闪烁,此时再短按key1,分钟个位加加,分钟个位在0-9
  之间变化;
5.分钟个位调好后,过5秒,退出调时状态,时钟正常走时。

在非调时状态,短按key1,开关LED灯;

小时 、分钟的个位、十位分开调节,这样比常规的个位、十位在一起调时快;


单片机源程序如下:
  1. /*********************************************************************************

  2. 仿真 实物都通过.stc89c52  11.0592MHz晶振 ;具体电路见仿真图;仿真用5位数码管显示88-88的样式

  3. 一个按键调节时间:

  4. 1.长按key1,进入调时状态,小时十位开始闪烁,此时再短按key1,小时十位加加,
  5.   小时十位在0-2之间变化;(key1可以是按钮,也可以用触摸开关)
  6. 2.调好后,过5秒自动跳到小时个位闪烁,此时再短按key1,小时个位加加,如果十位是0、1,
  7.   小时个位再0-9之间变化;如果十位是2,小时个位在0-3之间变化;
  8. 3.小时个位调好后,过5秒,分钟十位开始闪烁,此时再短按key1,分钟十位加加,分钟十位在0-5
  9.   之间变化;
  10. 4.分钟十位调好后,过5秒,分钟个位开始闪烁,此时再短按key1,分钟个位加加,分钟个位在0-9
  11.   之间变化;
  12. 5.分钟个位调好后,过5秒,退出调时状态,时钟正常走时。

  13. 在非调时状态,短按key1,开关LED灯;

  14. 小时 、分钟的个位、十位分开调节,这样比常规的个位、十位在一起调时快;
  15. **********************************************************************************/
  16. #include<reg52.h>
  17. #include<intrins.h>
  18. #define uchar unsigned char
  19. #define uint unsigned int

  20. sbit sclk = P1^0;
  21. sbit dio = P1^1;
  22. sbit ce = P1^2;
  23. sbit wela = P2^7;
  24. sbit dula = P2^6;
  25. sbit led = P1^7;

  26. sbit key1=P3^0;                                                        //按键 多功能

  27. uchar knum=0,ssnum,fsnum,sgnum,fgnum;  //调时 位 闪烁变量

  28. uchar shi,fen,miao;

  29. uchar ss;        //秒点闪烁变量

  30. bit zdyw; //自动移位标志

  31. uchar count;//自动移位时间计数变量
  32. /***********写时分秒地址************/
  33. #define write_shi  0x84
  34. #define write_fen  0x82
  35. #define write_miao 0x80
  36. #define write_ram  0xc0
  37. /***********读时分秒地址************/
  38. #define read_shi  0x85
  39. #define read_fen  0x83
  40. #define read_miao 0x81
  41. #define read_ram  0xc1
  42.                   // 0     1    2    3    4     5    6    7    8   9
  43. uchar code d[]={ 0x3F,0x06,0x5B,0x4F,0x66, 0x6D,0x7D,0x07,0x7F,0x6F}; //共阴不带小数点
  44. uchar code dd[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//        共阴带小数点

  45. //uchar dd[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};                //共阳带小数点
  46. //uchar d[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90};                //共阳不带小数点

  47. void delay(uint z)
  48. {
  49.         uint x,y;
  50.         for(x=z;x>0;x--)
  51.                 for(y=120;y>0;y--);
  52. }


  53. void t0_init()  //定时50ms中断
  54. {
  55.    
  56.   TMOD=0X01;
  57.   TH0=(65536-46080)/256;
  58.   TL0=(65536-46080)%256;
  59.   EA=1;
  60.   ET0=1;
  61.   TR0=1;
  62.   ET1=1;

  63. }


  64. void display(uchar shi,uchar fen)                          //显示函数
  65. {
  66.         if(knum==0)
  67.         {
  68.                 ssnum=30;
  69.                 fsnum=30;
  70.                 sgnum=30;
  71.                 fgnum=30;
  72.         }
  73.         
  74.         if(knum==3)
  75.         {
  76.                 fsnum++;
  77.                 ssnum=30;
  78.                 fgnum=30;
  79.                 sgnum=30;
  80.         }
  81.         
  82.         if(knum==4)
  83.         {
  84.                 fgnum++;
  85.                 ssnum=30;
  86.                 fsnum=30;
  87.                 sgnum=30;
  88.         }

  89.         if(knum==1)
  90.         {
  91.                 ssnum++;
  92.                 sgnum=30;
  93.                 fgnum=30;
  94.                 fsnum=30;
  95.         }
  96.         
  97.         if(knum==2)
  98.         {
  99.                 sgnum++;
  100.                 ssnum=30;
  101.                 fsnum=30;
  102.                 fgnum=30;
  103.         }
  104.         
  105.         
  106.         if(ssnum>=30)
  107.         {        
  108. //                if((shi/10)<1)         //如果小时十位小于1,
  109. //                {
  110. //                        wela=1;
  111. //                        P0=0xfe;                //第1位
  112. //                        wela=0;
  113. //        
  114. //                        dula = 1;
  115. //                        P0=0xff;           // 小时十位就不显示
  116. //                        dula = 0;
  117. //                }
  118. //               
  119. //                else
  120.                 {
  121.                         wela=1;
  122.                         P0=0xfe;          //第1位
  123.                         wela=0;
  124.         
  125.                         dula=1;
  126.                         P0=d[shi/10];
  127.                         dula=0;
  128.                         P0=0xff;
  129.                         delay(2);
  130.                 }

  131.                 if(ssnum==60)
  132.                         ssnum=0;

  133.          }

  134.          if(sgnum>=30)
  135.          {
  136.                 wela=1;
  137.                 P0=0xfd;           //第2位
  138.                 wela=0;

  139.                 dula=1;
  140.                 P0=d[shi%10];                        //时的个位,P0=d[shi%10]时的个位小数点闪烁
  141.                 dula=0;                                        // 时的个位,P0=dd[shi%10]时的个位小数点不闪烁
  142.                 P0=0xff;
  143.                 delay(2);
  144.                
  145.         
  146.         
  147.                 if(sgnum==60)
  148.                         sgnum=0;
  149.         }               


  150.         //        if(miao%2==0)         //if(miao%2==0) 1秒闪烁1次
  151.                 if(ss>=10)                 //        这里写为ss>=10,闪烁频率可调
  152.                 {                                 
  153.                     wela=1;
  154.                         P0=0xfb;                //第3位
  155.                         wela=0;
  156.         
  157.                         dula=1;
  158.                         P0=0x40;          //第三位数码管显示“— ”
  159.                         
  160.                 //        P0=0x09;          //第三位数码管显示“= ”
  161.                         dula=0;
  162.                         P0=0xff;
  163.                         delay(2);
  164.         
  165.                 }

  166.                 else
  167.                 {
  168.                         wela=1;
  169.                         P0=0xfb;   //第3位
  170.                         wela=0;
  171.         
  172.                         dula=1;
  173.                         P0=0;          //第三位数码管不显示
  174.                         dula=0;
  175.                         P0=0xff;
  176.                         delay(2);        
  177.                 }
  178.         
  179.         
  180.         if(fsnum>=30)
  181.         {
  182.                 wela=1;
  183.                 P0=0xf7;         //第4位
  184.                 wela=0;

  185.                 dula=1;
  186.                 P0=d[fen/10];
  187.                 dula=0;
  188.                 P0=0xff;
  189.                 delay(2);
  190.                
  191.                
  192. //                wela=1;
  193. //                P0=0xef;         //第5位
  194. //                wela=0;
  195. //
  196. //                dula=1;
  197. //                P0=d[fen%10];
  198. //                dula=0;
  199. //                P0=0xff;
  200. //                delay(2);
  201.         
  202.                
  203.                 if(fsnum==60)
  204.                         fsnum=0;
  205.         }

  206.         if(fgnum>=30)
  207.         {
  208.                 wela=1;
  209.                 P0=0xef;         //第5位
  210.                 wela=0;

  211.                 dula=1;
  212.                 P0=d[fen%10];
  213.                 dula=0;
  214.                 P0=0xff;
  215.                 delay(2);

  216.                 if(fgnum==60)
  217.                         fgnum=0;

  218.          }
  219.                
  220.         //        if(miao%2==0)         //if(miao%2==0) 1秒闪烁1次
  221. //                if(ss>=10)                 //if(ss>=10)闪烁频率可调
  222. //                {
  223. //                        wela=1;
  224. //                        P0=0xdf;          //第6位
  225. //                        wela=0;
  226. //                        dula=1;
  227. //                        P0=0x40;          //第六位数码管显示“— ”
  228. //                        dula=0;
  229. //                        P0=0xff;
  230. //        
  231. //                        delay(2);
  232. //                }
  233. //
  234. //                else
  235. //                {
  236. //                        wela=1;
  237. //                        P0=0xdf;   //第6位
  238. //                        wela=0;
  239. //                        dula=1;
  240. //                        P0=0;          //第六位数码管不显示
  241. //                        dula=0;
  242. //                        P0=0xff;
  243. //        
  244. //                        delay(2);
  245. //                }
  246. //               
  247. //               
  248. //                wela=1;
  249. //                P0=0xbf;                //第7位
  250. //                wela=0;
  251. //
  252. //            dula=1;
  253. //                P0=d[miao/10];                           //秒十位
  254. //                dula=0;
  255. //                P0=0xff;
  256. //                delay(2);
  257. //        
  258. //
  259. //                wela=1;
  260. //                P0=0x7f;                          //第8位
  261. //                wela=0;
  262. //
  263. //                dula=1;
  264. //                P0=d[miao%10];                         //秒个位
  265. //                dula=0;
  266. //                P0=0xff;
  267. //                delay(2);               
  268.         
  269. }  



  270. void write_1302(uchar add,dat)                 //写1302函数  qx
  271. {
  272.         uchar i,temp;
  273.         temp=add;
  274.         ce=0;
  275.         _nop_();
  276.         sclk=0;
  277.         _nop_();
  278.         ce=1;
  279.         _nop_();
  280.         for(i=0;i<8;i++)
  281.         {
  282.                 sclk=0;
  283.                 _nop_();
  284.                 if((temp&0x01)==0x01)
  285.                         dio=1;
  286.                         else
  287.                         dio=0;
  288.                 temp>>=1;
  289.                 sclk=1;
  290.                 _nop_();
  291.         }
  292.         temp=dat;
  293.         for(i=0;i<8;i++)
  294.         {
  295.                 sclk=0;
  296.                 _nop_();
  297.                 if((temp&0x01)==0x01)
  298.                         dio=1;
  299.                         else
  300.                         dio=0;
  301.                 temp>>=1;
  302.                 sclk=1;
  303.                 _nop_();
  304.         }
  305.         ce=0;
  306.         sclk=0;
  307. }
  308. uchar read_1302(uchar add)                                   //读1302函数                qx
  309. {
  310.         uchar dat,dat1,i,temp;
  311.         temp=add;
  312.         ce=0;
  313.         _nop_();
  314.         sclk=0;
  315.         _nop_();
  316.         ce=1;
  317.         for(i=0;i<8;i++)
  318.         {
  319.                 sclk=0;
  320.                 _nop_();
  321.                 if((temp&0x01)==0x01)
  322.                         dio=1;
  323.                         else
  324.                         dio=0;
  325.                 temp>>=1;
  326.                 sclk=1;
  327.                 _nop_();
  328.         }
  329.         for(i=0;i<8;i++)
  330.         {
  331.                 sclk=0;
  332.                 _nop_();
  333.                 if(dio)
  334.                     dat|=0x80;
  335.                 if(i<7)
  336.                         dat>>=1;
  337.                 sclk=1;
  338.         }
  339.         dat1=dat/16;         //读出的数值转为10进制
  340.         dat=dat%16;
  341.         dat=dat1*10+dat;  
  342.         ce=0;
  343.         sclk=0;
  344.         return dat;
  345. }                        


  346. void init_1302()                                                        //初始化函数 设置第一次上电时显示的时间值
  347. {        
  348.         write_1302(0x8e,0x00);                                        //保护取消,可以进行写操作
  349.         write_1302(write_miao,0x57);                        //写秒57
  350.         write_1302(write_fen,0x30);                                //写分30
  351.         write_1302(write_shi,0x12);                                //写时12
  352.         write_1302(0x8e,0x80);                                        //保护启动,不能进行写操作
  353. }         

  354. void read_sf()                           //读时分秒
  355. {
  356.         shi=read_1302(read_shi);
  357.         fen=read_1302(read_fen);
  358.         miao=read_1302(read_miao);
  359.         display(shi,fen);

  360. }



  361. void keyscan()                                                                   //按键扫描函数
  362. {        
  363.         uchar fs,fg,shs,shg;                                   //分钟十位、个位 ,小时十位、个位
  364.         static uint a;                                                   //按键延时变量
  365.         fs = fen/10; fg=fen%10;                                   //分钟十位、个位
  366.         shs = shi/10; shg=shi%10;                       //小时十位、个位

  367.         if(key1==0)
  368.         {
  369.                 a++;
  370.                 if(a>50)
  371.                 while(!key1)
  372.                 {
  373.                         display(shi,fen);
  374.                         a=0;
  375.                         zdyw=1;
  376.                 }
  377.         }

  378.         else
  379.         {
  380.                 if(a>10 && a<50)
  381.                 {
  382.                         count=0;                //每次按下,count都要清零,松手后,count都是从0开始计数,这句很重要
  383.                         a=0;

  384.                         if(knum==1)                                                //小时十位调节
  385.                         {
  386.                                 shs++;
  387.                                 if(shs>2) shs=0;
  388.                                 shi=shs*16+shg;
  389.                                 write_1302(write_shi,shi);        //写入1302
  390.                                 read_sf();                                        //读出时间,然后显示
  391.                         }
  392.         /*********************/
  393.                         if(knum==2)                                                //小时个位调节
  394.                         {
  395.                
  396.                                 shg++;
  397.                                 if(shs==0 || shs==1)   //如果小时十位为0、1
  398.                                 {
  399.                                         if(shg>9) shg=0;   //小时个位可以在0-9变化
  400.                                 }
  401.                                 else                                   //否则,小时个位可以在0-3变化
  402.                                 {
  403.                                         if(shg>3) shg=0;   
  404.                                 }
  405.                                 shi=shs*16+shg;                   //10进制转为16进制
  406.                                 write_1302(write_shi,shi);        //写入1302
  407.                                 read_sf();                                        //读出时间,然后显示
  408.                         }
  409. /************************/

  410.                         if(knum==3)                                                //分钟十位调节
  411.                         {
  412.                                 fs++;
  413.                                 if(fs>5) fs=0;
  414.                                 fen=fs*16+fg;
  415.                                 write_1302(write_fen,fen);        //写入1302
  416.                                 read_sf();                                        //读出时间,然后显示
  417.                         }
  418.         /*******************/
  419.                          if(knum==4)                                        //分钟个位调节
  420.                          {
  421.                                 fg++;
  422.                                 if(fg>9) fg=0;
  423.                                 fen=fs*16+fg;
  424.                                 write_1302(write_fen,fen);        //写入1302
  425.                                 read_sf();                                        //读出时间,然后显示
  426.                          }
  427.         
  428.         /***********************/

  429.                         if(knum==0)                                                //非调时状态,短按key1,开关LED
  430.                         {
  431.                                 led=~led;
  432.                         }
  433.                 }
  434.         }           
  435. }

  436. /************************/

  437. void main()
  438. {
  439.         t0_init();
  440.         init_1302();                          
  441.         while(1)
  442.         {
  443.             read_sf();
  444.             keyscan();
  445.         }
  446. }

  447. void temer1() interrupt 1
  448. {
  449.         TH0=(65536-46080)/256;
  450.         TL0=(65536-46080)%256;
  451.         ss++;
  452.         if(ss==20)          //1秒时间到
  453.         {
  454.                 ss=0;
  455.                 if(zdyw)
  456.                 {
  457.                         count++;
  458.                         if(count==5) //调时的时候,自动移位快慢调这里,要快就把count的值减小,反之亦然。
  459.                         {
  460.                                 count=0;
  461.                                 knum++;
  462.                                 if(knum==1)
  463.                                 {
  464.                                          write_1302(0x8e,0x00);                //写保护取消
  465. //                                        write_1302(write_miao,0x80); //  写秒80,时钟停止走时;                        
  466.                                 }
  467.                                 if(knum>4)
  468.                                 {
  469.                                         knum=0;
  470.                                         zdyw=0;
  471.                                         write_1302(write_miao,0x00);
  472.                                         write_1302(0x8e,0x80);                //写保护启动
  473.                                 }
  474.                         }        
  475.                 }                        
  476.         }
  477. }         
复制代码
全部资料51hei下载地址:
时钟个十位分开调节 -1键调节.rar (181.79 KB, 下载次数: 14)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:768299 发表于 2020-6-3 12:12 | 只看该作者
膜拜大佬
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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