找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机定时器做普通时钟程序 可调

[复制链接]
跳转到指定楼层
楼主
ID:808634 发表于 2020-9-30 10:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. /*-----------------------------------------------
  2.      实验名称:基于定时器T0的可调时钟、
  3.                  接线说明:
  4.                                  LSA=>P2^2;
  5.                                  LSB=>P2^3;
  6.                                  LSC=>P2^4;
  7.                                  P0=>数码管位选
  8.                                  P3=>独立按键
  9. ------------------------------------------------*/
  10. #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

  11. #define KeyPort P3 //定义按键端口
  12. #define u8 unsigned char
  13. #define u16 unsigned int
  14. //#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换

  15. //sbit LATCH1=P2^2;//定义锁存使能端口 段锁存
  16. //sbit LATCH2=P2^3;//                 位锁存
  17. sbit LSA=P2^2;
  18. sbit LSB=P2^3;
  19. sbit LSC=P2^4;

  20. unsigned char hour,minute,second;//定义时分秒

  21. bit UpdateTimeFlag;//定义读时间标志

  22. unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9
  23. unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码

  24. u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  25.                                         0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值

  26. unsigned char TempData[8],Key_Num; //存储显示值的全局变量

  27. void DelayUs2x(unsigned char t);//us级延时函数声明
  28. void DelayMs(unsigned char t); //ms级延时
  29. void DigDisplay();//数码管显示函数
  30. unsigned char KeyScan(void);//键盘扫描
  31. void     Init_Timer0(void);//定时器初始化
  32. /*------------------------------------------------
  33.                     主函数
  34. ------------------------------------------------*/
  35. void delay(u16 i)
  36. {
  37.         while(i--);        
  38. }   
  39. /*--------------------------------------------------*/
  40. void main (void)
  41. {
  42. //unsigned char num;                  

  43. Init_Timer0();

  44. while (1)         //主循环
  45.   {

  46.                                         Key_Num=KeyScan();
  47.                                         switch(Key_Num)
  48.                                                 {
  49.                                                                         case 1:hour++;if(hour==24)hour=0;     //正常时间 小时 加1
  50.                                                                                          break;
  51.                                                                         case 2:hour--;if(hour==255)hour=23;   //正常时间 小时减1
  52.                                                                                  break;
  53.                                                                         case 3:minute++;if(minute==60)minute=0;     //分钟加1
  54.                                                                                  break;
  55.                                                                         case 4:minute--;if(minute==255)minute=59;   //分钟减1
  56.                                                                                  break;
  57.                                                                         default:break;
  58.                                                 }
  59. //                                        if(UpdateTimeFlag==1)
  60. //                                         {
  61. //                                                                UpdateTimeFlag=0;

  62.                                                          TempData[0]=dofly_DuanMa[hour/10]; //时                        //数据的转换,因我们采用数码管0~9的显示,将数据分开
  63.                                                          TempData[1]=dofly_DuanMa[hour%10];
  64.                                                          TempData[2]=0x40;                                                            //加入"-"
  65.                                                          TempData[3]=dofly_DuanMa[minute/10];//分
  66.                                                          TempData[4]=dofly_DuanMa[minute%10];
  67.                                                          TempData[5]=0x40;
  68.                                                          TempData[6]=dofly_DuanMa[second/10];//秒
  69.                                                          TempData[7]=dofly_DuanMa[second%10];        
  70.                                                    
  71.                                                         DigDisplay();
  72. //                                                }
  73.                                         // DigDisplay();
  74. }
  75. }
  76. /*------------------------------------------------
  77. uS延时函数,含有输入参数 unsigned char t,无返回值
  78. unsigned char   是定义无符号字符变量,其值的范围是
  79. 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
  80. 长度如下 T=tx2+5 uS
  81. ------------------------------------------------*/
  82. void DelayUs2x(unsigned char t)
  83. {   
  84. while(--t);
  85. }
  86. /*------------------------------------------------
  87. mS延时函数,含有输入参数 unsigned char t,无返回值
  88. unsigned char 是定义无符号字符变量,其值的范围是
  89. 0~255 这里使用晶振12M,精确延时请使用汇编
  90. ------------------------------------------------*/
  91. void DelayMs(unsigned char t)
  92. {

  93. while(t--)
  94. {
  95.      //大致延时1mS
  96.      DelayUs2x(245);
  97.            DelayUs2x(245);
  98. }
  99. }
  100. /*------------------------------------------------
  101. 显示函数,用于动态扫描数码管
  102. 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示
  103. 如输入0表示从第一个显示。
  104. Num表示需要显示的位数,如需要显示99两位数值则该值输入2
  105. ------------------------------------------------*/
  106. void DigDisplay()
  107. {
  108.         u8 i=0;
  109.         for(i=0;i<8;i++)
  110.         {
  111.                 switch(i)         //位选,选择点亮的数码管,
  112.                 {
  113.                         case(0):
  114.                                 LSA=0;LSB=0;LSC=0; break;//显示第0位
  115.                         case(1):
  116.                                 LSA=1;LSB=0;LSC=0; break;//显示第1位
  117.                         case(2):
  118.                                 LSA=0;LSB=1;LSC=0; break;//显示第2位
  119.                         case(3):
  120.                                 LSA=1;LSB=1;LSC=0; break;//显示第3位
  121.                         case(4):
  122.                                 LSA=0;LSB=0;LSC=1; break;//显示第4位
  123.                         case(5):
  124.                                 LSA=1;LSB=0;LSC=1; break;//显示第5位
  125.                         case(6):
  126.                                 LSA=0;LSB=1;LSC=1; break;//显示第6位
  127.                         case(7):
  128.                                 LSA=1;LSB=1;LSC=1; break;//显示第7位        
  129.                 }
  130.                 P0=TempData[i];//发送段码
  131.                 delay(100); //间隔一段时间扫描        
  132.                 P0=0x00;//消隐
  133.         //delay(1000);
  134.         }
  135. }
  136. /*------------------------------------------------
  137.                     定时器初始化子程序
  138. ------------------------------------------------*/
  139. void Init_Timer0(void)
  140. {
  141. TMOD |= 0x01;          //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响                     
  142. //TH0=0x00;              //给定初值
  143. //TL0=0x00;
  144. EA=1;            //总中断打开
  145. ET0=1;           //定时器中断打开
  146. TR0=1;           //定时器开关打开
  147. }
  148. /*------------------------------------------------
  149.                  定时器中断子程序
  150. ------------------------------------------------*/
  151. void Timer0_isr(void) interrupt 1
  152. {
  153. static unsigned int num,i;
  154. TH0=(65536-2000)/256;//重新赋值 2ms
  155. TL0=(65536-2000)%256;

  156. // DigDisplay();     // 调用数码管扫描
  157. i++;
  158. if(i==10)                  //20ms更新一次
  159.     {
  160.         i=0;
  161.         UpdateTimeFlag=1;         //更新时间志位置1
  162.         }
  163. num++;
  164. if(num==500)        //大致1s
  165.    {
  166.     num=0;
  167.         second++;
  168.         if(second==60)                  //秒到60,分钟加1
  169.          {
  170.           second=0;         
  171.           minute++;
  172.           if(minute==60)        //分钟到60,小时加1
  173.             {
  174.                  minute=0;
  175.                  hour++;
  176.                  if(hour==24)                //小时到24,回零
  177.                    hour=0;
  178.                 }
  179.          }

  180.   }
  181. }

  182. /*------------------------------------------------
  183. 按键扫描函数,返回扫描键值
  184. ----------------------------------------------*/
  185. unsigned char KeyScan(void)
  186. {
  187. unsigned char keyvalue;
  188. if(KeyPort!=0xff)
  189.    {
  190.     DelayMs(10);
  191.     if(KeyPort!=0xff)
  192.            {
  193.             keyvalue=KeyPort;
  194.             while(KeyPort!=0xff);
  195.                 switch(keyvalue)
  196.                 {
  197.                  case 0xfe:return 1;break;
  198.                  case 0xfd:return 2;break;
  199.                  case 0xfb:return 3;break;
  200.                  case 0xf7:return 4;break;
  201.                  case 0xef:return 5;break;
  202.                  case 0xdf:return 6;break;
  203.                  case 0xbf:return 7;break;
  204.                  case 0x7f:return 8;break;
  205.                  default:return   0;break;
  206.                 }
  207.           }
  208.    }
  209.    return 0;
  210. }
复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:328014 发表于 2020-9-30 15:51 | 只看该作者
能分享一下原理图吗?
回复

使用道具 举报

板凳
ID:988738 发表于 2021-12-12 19:02 | 只看该作者
有原理图吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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