单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2034|回复: 4
收起左侧

简易一小时定时器 数码管显示

[复制链接]
凌净清河 发表于 2018-10-8 22:50 | 显示全部楼层 |阅读模式
近些天图书馆收书,规定人离开座位不能超过15分钟不然就会把书收走,所以制作了一个计时器,用来指示人离开的时长,按照最简需求设计,计时时长为1小时,超出时间清零。
附带了一个按键,用于计时过程中的暂停,这样这个计时器可以当作秒表使用了,做个题什么的限制一下时间又不用占用手机。而且最关键的是小巧,看起来不会太蠢...

1539009750357.jpg

1539009807142.jpg


说明:
1.单片机使用STC15F104W,共有6个I/O
2.数码管为时钟样式的数码管,中间带有“:”的,焊接时按照最短路径焊接,移植程序请考虑修改smgduan[10]的段选值
3.程序定时器0初始值是在12MHz晶振下的初始值,移植程序时请注意修改
4.数码管采用74HC138+74HC595驱动,595典型连接方式到单片机普通I/O,138改为2-4线驱动,S2=0,Y0~Y3进行位选
5.清零操作就重新上电就好啦,毕竟是最简需求嘛
6.整个板子需要4根跳线,分别是
    74HC595的SRCLR'到VCC
    74HC138的S2到GND
    板子连接时138译码器GND到供电地的跳线
    板子背面使用较硬铁丝(剪下的元件引线)连接数码管第4位到138译码器Y3

程序设计思路:
初始化一个5ms的定时器,每计数200次为1s,每秒将时间值变量加一,在主程序中循环处理这个数据,对60取模得到分钟数,取余得到秒数。
将所取到的分钟和秒按位取出,得到待显示的每一位数据,存放在Display_time[4]数组中。调用数码管显示函数进行显示。
在循环中加入一个按键检测,如果按键按下,就将定时器运行位取反,实现暂停效果。
设定一个标志位point,每秒的前一半令其为1,后一半令其为0,在显示函数中对这一位进行判断,决定数码管小数点位是否亮。
注意:时钟数码管的中间“:”是第二位小数点,但是为了简便,将所有小数点全部点亮了。

  1. #include<STC15.H>
  2. #include<intrins.h>
  3. sbit S1=P3^0;
  4. sbit S2=P3^5;
  5. sbit SER=P3^1;
  6. sbit RCLK=P3^2;
  7. sbit SRCLK=P3^3;//74HC595管脚定义
  8. sbit KEY=P3^4;

  9. //全局变量表
  10. unsigned char code smgduan[10]={0xf5,0x05,0xb3,0x97,0x47,0xd6,0xf6,0x85,0xf7,0xd7};//给74HC595的段选值
  11. unsigned char Display_Time[4]={0,0,0,0};
  12. unsigned int time=0;
  13. unsigned char cnt=0;//定时器周期计数
  14. bit point=1;
  15. /*##############################################################################################
  16. 设计名称:简易一小时计时器
  17. 设计者:清河

  18. 平台:STC15F104W
  19. 硬件部分
  20. 数码管显示:位选使用74HC138改为2-4线译码、段选使用74HC595减少IO口使用
  21.         使用4位共阴极数码管,时钟数码管,显示无符号位

  22. 注意:为尽可能保证精度,晶振选取12MHz
  23. ##############################################################################################*/
  24. void delay(unsigned int cnt)//调用该函数进行一段时间的延时
  25. {
  26.         while(cnt--);
  27. }

  28. void Timer0Init(void)                //5毫秒@12.000MHz
  29. {
  30.         EA=1;
  31.         ET0=1;
  32.         AUXR |= 0x80;                //定时器时钟1T模式
  33.         TMOD &= 0xF0;                //设置定时器模式
  34.         TL0 = 0xA0;                //设置定时初值
  35.         TH0 = 0x15;                //设置定时初值
  36.         TF0 = 0;                //清除TF0标志
  37.         TR0 = 1;                //定时器0开始计时
  38. }

  39. void hc595send(unsigned char dat)//使用SPI向74HC595发送一个字节的数据                                
  40. {  
  41.         unsigned char a;
  42.         SRCLK=0;
  43.         RCLK=0;
  44.         for(a=0;a<8;a++)
  45.         {
  46.                 SER=dat>>7;
  47.                 dat<<=1;
  48.                 SRCLK=1;
  49.                 _nop_();
  50.                 _nop_();
  51.                 SRCLK=0;       
  52.         }
  53.         RCLK=1;
  54.         _nop_();
  55.         _nop_();
  56.         RCLK=0;
  57. }

  58. void smgdisplay()//数码管显示函数,参数为需要显示的数组
  59. {
  60.         unsigned char i;
  61.         for(i=0;i<4;i++)
  62.         {
  63.                 switch(i)//位选,选择点亮的数码管
  64.                 {
  65.                         case(0):
  66.                                 S1=0;S2=1; break;
  67.                         case(1):
  68.                                 S1=1;S2=0; break;
  69.                         case(2):
  70.                                 S1=0;S2=0; break;
  71.                         case(3):
  72.                                 S1=1;S2=1; break;
  73.                 }
  74.                 if(point)
  75.                 {
  76.                         hc595send(smgduan[Display_Time[i]]|0x08);
  77.                 }
  78.                 else
  79.                 {
  80.                         hc595send(smgduan[Display_Time[i]]);
  81.                 }
  82.                 delay(10); //间隔一段时间扫描
  83.                 hc595send(0x00);//消隐
  84.         }
  85. }

  86. void main()
  87. {
  88.         Timer0Init();
  89.         while(1)
  90.         {
  91.                 Display_Time[0]=(time/60)/10;
  92.                 Display_Time[1]=(time/60)%10;
  93.                 Display_Time[2]=(time%60)/10;
  94.                 Display_Time[3]=(time%60)%10;
  95.                 smgdisplay();
  96.                
  97.                 if(KEY==0)
  98.                 {
  99.                         delay(5000);
  100.                         if(KEY==0)
  101.                         {
  102.                                 TR0=!TR0;
  103.                                 point=1;
  104.                         }
  105.                         while(!KEY);
  106.                 }
  107.         }
  108. }

  109. void Timer0() interrupt 1
  110. {
  111.         TL0 = 0xA0;                //设置定时初值
  112.         TH0 = 0x15;                //设置定时初值
  113.        
  114.         if(cnt==200)//计数到1s
  115.         {
  116.                 cnt=0;//清空
  117.                 point=1;//秒闪烁:亮
  118.                 time++;//时间加1秒
  119.         }
  120.         else
  121.         {
  122.                 if(cnt==100)//当计数半秒
  123.                 {
  124.                         point=0;//秒闪烁:灭
  125.                 }
  126.                 cnt++;
  127.         }
  128.        
  129.         if(time==3600)//满值清空
  130.         {
  131.                 time=0;
  132.         }
  133. }
复制代码
插入的代码似乎格式有问题,复制应该不影响编译,但建议下载源代码。



备注:由于该作品的耗电量很小,故使用“充满自停”的移动电源供电时,可能会出现一段时间后自动停止供电的情况,解决办法是使用无充电保护的移动电源或者增加作品负载(加几个灯什么的...)

凌净清河

虽然程序很简单,不用回帖就可以下载,但是还是很期待大家的评论呢!
简易一小时计时器 凌净清河.zip (23.53 KB, 下载次数: 18)

评分

参与人数 1黑币 +15 收起 理由
杨雪飞 + 15 洞洞板焊得不是一般了得,感谢分享,跳线在.

查看全部评分

回复

使用道具 举报

文凤轩 发表于 2018-10-9 09:35 来自手机 | 显示全部楼层
谢谢分享,非常适合我们菜鸟学习!

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15

查看全部评分

回复

使用道具 举报

杨雪飞 发表于 2018-10-9 11:39 | 显示全部楼层
洞洞板焊得不是一般了得,感谢分享,那根飞线在元件面跳过去就更美观了,看着很舒适。

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 感谢建议,以后会注意的!

查看全部评分

回复

使用道具 举报

gjt159 发表于 2018-10-9 22:56 | 显示全部楼层
有点意思哦,弄来看看先

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15

查看全部评分

回复

使用道具 举报

51单片机1234 发表于 2018-10-10 01:02 | 显示全部楼层
看起来不错哦~

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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