找回密码
 立即注册

QQ登录

只需一步,快速开始

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

用51单片机设计小时候带的简易电子表(含源码)

  [复制链接]
跳转到指定楼层
楼主
ID:369060 发表于 2018-8-8 18:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
学了51,模仿了小时候电子手表的基本功能,可以在时钟和秒表两个功能间切换,用的是郭天祥的板子。采用四个独立按键,通过对四个键按下的次数不同,实现不同的功能,程序详注。(第一次尝试很多地方未免复杂冗余,希望大神指点)

/*使用1602作为电子表的显示屏,单片机上电后,首先通过按键设定当前时间,
完成初始化,同时该电子表还具有秒表功能,按下秒表键后,进入秒表界面。秒
表界面有开始,取次,停止,复位,返回时间,可以记录三次取时,每个按钮按
下都对应蜂鸣器短响一声进入秒表界面,时间继续运行,在时间界面,秒表处于
复位状态。*/

单片机源程序如下:
  1. /*......................................................................................*/
  2. #include<reg52.h>
  3. sbit lcden=P3^4;              //使能端                                                   
  4. sbit lcdrs=P3^5;              //RS                                                            
  5. sbit dula=P2^6;               //定义锁存器的锁存端         
  6. sbit wela=P2^7;
  7. sbit s1=P3^0;                 //定义按键----功能键
  8. sbit s2=P3^1;                                  //定义按键-----增加键
  9. sbit s3=P3^2;                                  //定义按键------计次键
  10. sbit s4=P3^3;                                  //定义按键------钟与秒表的切换键
  11. sbit rd=P3^7;                                  //初始化函数中使它接地从而使第四列矩阵键盘成为独立键盘                                                      
  12. sbit beep=P2^3;                                  //定义蜂鸣器
  13. char count,count1,s1num,s2num,s3num,s4num,stop, miao,shi,                               //stop保证在秒表工作模式下,定时器0的数值不会被送去lcd显示。      count,count1是用到定时器里面,   *num是用来计按键次数,miao*,shi*,fen*
  14. fen,miao1,shi1,fen1,miao3,fen3,shi3,miao4,fen4,shi4,miao5,                                   //是用来保持lcd上的显示的,结合下面应该可以看懂。
  15. fen5,shi5,miao6,fen6,shi6,miao7,fen7,shi7,miao8,fen8,shi8,
  16. miao9,fen9,shi9;                           //char表示的数据范围-127~128     
  17. void delay(int z)             //延时子函数
  18. {
  19.         int x,y;
  20.         for(x=z;x>0;x--)
  21.                 for(y=110;y>0;y--);
  22. }
  23. void xiang()                  //蜂鸣器发声函数
  24. {
  25.         beep=0;
  26.         delay(20);
  27.         beep=1;
  28. }
  29. void write_com(char com)      //写命令子函数
  30. {
  31.         lcdrs=0;
  32.         P0=com;
  33.         delay(5);
  34.         lcden=1;
  35.         delay(5);
  36.         lcden=0;
  37. }

  38. void write_date(char date)    //写数据子函数
  39. {
  40.         lcdrs=1;
  41.         P0=date;
  42.         delay(5);
  43.         lcden=1;
  44.         delay(5);
  45.         lcden=0;
  46. }
  47. void write_sfm(unsigned char add,unsigned char date)  //写时分秒函数
  48. {
  49.         unsigned char shi,ge;
  50.         shi=date/10;              //分解一个2位数的十位和个位
  51.         ge=date%10;
  52.         write_com(0x80+0x40+add); //设置显示位置
  53.         write_date(0x30+shi);     //送去液晶显示十位
  54.         write_date(0x30+ge);      //送去液晶显示个位
  55. }
  56. void init()                   //初始化函数
  57. {
  58.         rd=0;                     //软件将矩阵按键第四列一端置低用来分离出独立按键
  59.         dula=0;
  60.         wela=0;                          //关闭锁存器,防止数码管分流,影响1602的显示
  61.         lcden=0;
  62.         fen=0;                    //初始化钟变量值
  63.         miao=0;
  64.         shi=0;
  65.         count=0;
  66.         count1=0;
  67.         s1num=0;
  68.         s2num=0;
  69.         s3num=0;
  70.         s4num=0;
  71.         write_com(0x38);                 //设置16*2显示,5*7点阵,8位数据口
  72.         write_com(0x0c);                 //开显示,不开光标  00001100
  73.         write_com(0x06);                 //写字符后地址指针自动加一,不移动 00000110
  74.         write_com(0x01);                 //清除屏幕上原有的乱码
  75.         write_com(0x80+0x04);         //从第一行的第五个字符位开始显示
  76.         write_com(0x80+0x40+6);  //在第二行第第七个字符处写入 “ :”
  77.         write_date(':');
  78.         delay(5);
  79.         write_com(0x80+0x40+9);  //在第二行第第十个字符处写入 “ :”
  80.         write_date(':');
  81.         delay(5);
  82.         write_sfm(10,miao);
  83.         write_sfm(7,fen);
  84.         write_sfm(4,shi);
  85.         TMOD=0X11;                //设置定时器0的工作模式1;
  86.         TH0=(65536-50000)/256;    //装初值
  87.         TL0=(65536-50000)%256;
  88.         EA=1;                     //打开总中断
  89.         ET0=1;                    //开定时器0中断
  90.         TR0=1;                    //启动定时器0
  91. }
  92. void init_stopwatch()                  //初始化秒表
  93. {
  94.         write_com(0x01);
  95.         miao1=0;
  96.         fen1=0;
  97.         shi1=0;
  98.         write_com(0x80+0x40+6);  //在第二行第第七个字符处写入 “ :”
  99.         write_date(':');
  100.         delay(5);
  101.         write_com(0x80+0x40+9);  //在第二行第第十个字符处写入 “ :”
  102.         write_date(':');
  103.         delay(5);
  104.         write_sfm(10,miao1);
  105.         write_sfm(7,fen1);
  106.         write_sfm(4,shi1);                           //TMOD=0x10;错误处:采用两个定时器时,一次设置工作模式就行                                                  
  107.         TH1=(65536-50000)/256;
  108.         TL1=(65536-50000)%256;
  109.         EA=1;
  110.         ET1=1;
  111.         TR1=0;
  112. }
  113. void keyscan()                //键盘扫描函数
  114. {         
  115.         if(s1==0)                                  //判断s1是否被按下
  116.         {
  117.                 delay(5);
  118.                 if(s1==0)                          //确实被按下
  119.                 {

  120.                         while(!s1);                  //按键抬起,
  121.                         xiang();                  //蜂鸣器响
  122.                         s1num++;                  //功能键被按下次数
  123.                         if(s1num==1)          //第一次被按下时
  124.                         {

  125.                         }
  126.                         if(s1num==2)          //第二次被按下时
  127.                         {
  128.                                 TR0=0;                                           //关闭定时器
  129.                                 write_com(0x80+0x40+10);   //指针定到秒的地址  
  130.                                 write_com(0x0f);                   //指针开始闪烁
  131.                         }
  132.                         if(s1num==3)                                        //第三次被按下时
  133.                         {
  134.                                 write_com(0x80+0x40+7);                //指针定位到分的地址               
  135.                         }
  136.                         if(s1num==4)                                        //第四次被按下时
  137.                         {
  138.                                 write_com(0x80+0x40+4);                //指针定位到时的地址               
  139.                         }
  140.                         if(s1num==5)                                        //第五次被按下时
  141.                         {      
  142.                                 s1num=0;                                        //清零
  143.                                 write_com(0x0c);                        //关闭光标
  144.                                 TR0=1;                                                //打开定时器
  145.                         }                                                                                       
  146.                 }

  147.         }
  148.          if(s1num==1)
  149.          {
  150.                  if(s4==0)                                                   //切换到定时器模式
  151.                 {
  152.                         delay(5);                                       
  153.                         if(s4==0);
  154.                         s4num++;
  155.                         while(!s4);
  156.                         xiang();                                        //s4确实被按下
  157.                         if(s4num==1)
  158.                         {
  159.                                 stop=1;
  160.                                 init_stopwatch();               
  161.                         }
  162.                         if(s4num==2)
  163.                         {
  164.                                 TR1=0;
  165.                                 stop=0;
  166.                                 s4num=0;
  167.                                 write_sfm(10,(miao3+miao4));
  168.                                 write_sfm(7,(fen3+fen4));
  169.                                 write_sfm(4,(shi3+shi4));
  170.                               
  171.                         }
  172.                 }
  173.          }
  174.          if(s1num==1)
  175.          {
  176.                  if(s2==0)
  177.                 {
  178.                         delay(5);
  179.                         if(s2==0)
  180.                         {
  181.                                 while(!s2);
  182.                                 xiang();
  183.                                 s2num++;
  184.                                 if(s2num==1)
  185.                                 {
  186.                                         TR1=1;
  187.                                 }
  188.                                 if(s2num==2)
  189.                                 {
  190.                                         s2num=0;
  191.                                         TR1=0;
  192.                                 }
  193.                         }
  194.                 }
  195.          }
  196.          if(s2num==1&&s4num==1)
  197.        {      if(s3==0)
  198.                         {
  199.                                 delay(5);
  200.                                 if(s3==0)
  201.                                 {
  202.                                         s3num++;
  203.                                         while(!s3);
  204.                                     xiang();
  205.                                         if(s3num==1)
  206.                                         {
  207.                                                 shi6=shi5;
  208.                                                 fen6=fen5;
  209.                                                 miao6=miao5;      
  210.                                         }
  211.                                         if(s3num==2)
  212.                                         {
  213.                                                 shi7=shi5;
  214.                                                 fen7=fen5;
  215.                                                 miao7=miao5;
  216.                                         }
  217.                                         if(s3num==3)
  218.                                         {
  219.                                                 shi8=shi5;
  220.                                                 fen8=fen5;
  221.                                                 miao8=miao5;
  222.                                         }
  223.                                         if(s3num==4)
  224.                                         {
  225.                                                 miao1=0;
  226.                                                 fen1=0;
  227.                                                 shi1=0;
  228.                                                 write_sfm(10,miao1);
  229.                                                 write_sfm(7,fen1);
  230.                                                 write_sfm(4,shi1);
  231.                                                 TR1=0;
  232.                                         }
  233.                                         if(s3num==5)
  234.                                         {
  235.                                                 write_sfm(10,miao6);
  236.                                                 write_sfm(7,fen6);
  237.                                                 write_sfm(4,shi6);      
  238.                                         }
  239.                                         if(s3num==6)
  240.                                         {
  241.                                                 write_sfm(10,miao7);
  242.                                                 write_sfm(7,fen7);
  243.                                                 write_sfm(4,shi7);
  244.                                         }
  245.                                         if(s3num==7)
  246.                                         {
  247.                                                 write_sfm(10,miao8);
  248.                                                 write_sfm(7,fen8);
  249.                                                 write_sfm(4,shi8);
  250.                                         }
  251.                                         if(s3num==8)
  252.                                         {
  253.                                                 s3num=0;
  254.                                                 init_stopwatch();
  255.                                         }
  256.                                 }
  257.                         }
  258.                 }
  259.      if(s1num!=0)                                                         //若是s1被按过
  260.          {         
  261.                  if(s2==0)                                                         //s2被按下
  262.                 {
  263.                         delay(5);
  264.                         if(s2==0)                                                 //s2确实被按下
  265.                         {
  266.                                  while(!s2);                                         //如果s2抬起
  267.                             xiang();                                         //蜂鸣器响
  268.                                 if(s1num==2)                                 //此时若是s1被按了一次
  269.                                 {
  270.                                         miao++;                                         //秒加一
  271.                                         miao4=miao;
  272.                                         if(miao==60)                         //如果秒等于60
  273.                                         miao=0;
  274.                                         miao4=miao;                                 //清零
  275.                                         write_com(0x80+0x40+10);
  276.                                         write_sfm(10,miao);
  277.                                 }
  278.                                  if(s1num==3)
  279.                                  {
  280.                                           fen++;
  281.                                         fen4=fen;
  282.                                         if(fen==60)
  283.                                         fen=0;
  284.                                         fen4=fen;
  285.                                         write_com(0x80+0x40+7);
  286.                                         write_sfm(7,fen);
  287.                                  }
  288.                                  if(s1num==4)
  289.                                  {
  290.                                           shi++;
  291.                                         shi4=shi;
  292.                                         if(shi==24)
  293.                                         shi=0;
  294.                                         shi4=shi;
  295.                                         write_com(0x80+0x40+4);
  296.                                         write_sfm(4,shi);                                       
  297.                                  }
  298.                         }
  299.                 }
  300.                
  301.          }
  302. }
  303. void main()
  304. {
  305.         init();                                             //初始化1602
  306.         while(1)
  307.         {
  308.                 keyscan();                          //一直扫描键盘
  309.         }
  310. }
  311. void timer0() interrupt 1         //定时器0用于钟表
  312. {
  313.         TH0=(65536-50000)/256;         //装初值
  314.         TL0=(65536-50000)%256;
  315.         count++;                                  //计数,保证每20次中断一次,时长为一秒
  316.         if(count==20)
  317.         {
  318.                  count=0;
  319.                 miao++;
  320.                 miao3=miao;
  321.                 if(miao==60)                   //将更新的秒时分的值更新到1602
  322.                 {
  323.                          miao=0;
  324.                         miao3=miao;
  325.                         fen++;
  326.                         fen3=fen;
  327.                         if(fen==60)
  328.                         {      
  329.                             fen=0;
  330.                                 fen3=fen;
  331.                                 shi++;
  332.                                 shi3=shi;
  333.                                 if(shi==24)
  334.                                 {
  335.                                         shi=0;
  336.                                         shi3=shi;
  337.                                 }
  338.                                 if(stop==0)                                           //在秒表模式,钟表的时间不显示,但是任然计时
  339.                                 write_sfm(4,shi);
  340.                         }
  341.                         if(stop==0)
  342.                         write_sfm(7,fen);

  343.                 }   
  344.                 if(stop==0)               
  345.                 write_sfm(10,miao);
  346.         }               
  347. }
  348. void timer1() interrupt 3         //定时器1用于秒表计时
  349. {
  350.         TH1=(65536-50000)/256;
  351.         TL1=(65536-50000)%256;
  352.         count1++;
  353.         if(count1==20)
  354.         {
  355.                 count1=0;
  356.                 miao1++;
  357.                 miao5=miao1;
  358.                 if(miao1==60)
  359.                 {
  360.                         miao1=0;
  361.                         miao5=miao1;
  362.                         fen1++;
  363.                         fen5=fen1;
  364.                         if(fen1==60)
  365.                         {
  366.                                 fen1=0;
  367.                                 fen5=fen1;
  368.                                 shi1++;
  369.                                 shi5=shi1;
  370.                                 if(shi1==24)
  371.                                 {
  372.                                         shi1=0;
  373.                                         shi5=shi1;
  374.                                 }
  375.                                         write_sfm(4,shi1);
  376.                         }
  377.                         write_sfm(7,fen1);
  378.                 }
  379.                 write_sfm(10,miao1);
  380.         }                       
  381. }
复制代码

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:292119 发表于 2018-8-10 14:16 | 只看该作者
怎么没有图,没有真相呀
回复

使用道具 举报

板凳
ID:369060 发表于 2018-8-14 11:47 | 只看该作者
songyuan 发表于 2018-8-10 14:16
怎么没有图,没有真相呀

忘记拍照了,要想尝试的话可以发给你
回复

使用道具 举报

地板
ID:386147 发表于 2018-8-14 12:56 来自手机 | 只看该作者
就是没有图
回复

使用道具 举报

5#
ID:444232 发表于 2018-12-11 16:52 | 只看该作者
楼主,这个程序对应的图可以发给我么,自己画了张图但就是用不了
回复

使用道具 举报

6#
ID:444232 发表于 2018-12-11 16:55 | 只看该作者
楼主,你那个电子表程序的图可以发给我么,自己画了张图不能用
回复

使用道具 举报

7#
ID:591211 发表于 2019-12-7 15:48 | 只看该作者
求图,/流泪
回复

使用道具 举报

8#
ID:702219 发表于 2020-3-4 12:19 | 只看该作者
手表的可以发个图吗。。我想试试
回复

使用道具 举报

9#
ID:669286 发表于 2020-12-28 20:28 | 只看该作者
可以发个图吗
回复

使用道具 举报

10#
ID:872086 发表于 2021-1-2 12:35 | 只看该作者
sbit lcden=P3^4;              //使能端                                                   
sbit lcdrs=P3^5;              //RS                                                            
sbit dula=P2^6;               //定义锁存器的锁存端         
sbit wela=P2^7;
请问这几句命令是什么意思,比如这是什么使能端
回复

使用道具 举报

11#
ID:822201 发表于 2021-1-3 12:44 | 只看该作者
lmyuan 发表于 2021-1-2 12:35
sbit lcden=P3^4;              //使能端                                                   
sbit lcdr ...

这是定义锁存器吧
回复

使用道具 举报

12#
ID:589491 发表于 2021-1-3 16:47 | 只看该作者
lmyuan 发表于 2021-1-2 12:35
sbit lcden=P3^4;              //使能端                                                   
sbit lcdr ...

lcd1602的使能
lcdd1602的rs端
下面2局就是数码管的锁存,因数码管与LCD1602共用P0端口
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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