x
x

(连载1)吴鉴鹰单片机项目精讲(连载)之基于单片机的数字电子钟设计

发布时间:2014-6-12 10:53    发布者:吴鉴鹰
关键词: 吴鉴鹰 , 资深工程师 , 单片机项目 , 连载
(连载1)吴鉴鹰单片机项目精讲(连载)之基于单片机的数字电子钟设计


先关的原理图请点击下载:
吴鉴鹰基于单片机的数字电子钟.pdf (295.38 KB)
     现在来第一讲,详细解析如何制作基于单片机的数字时钟,提供详细的硬件原理图和软件程序。
开关K1:K1 = 0时,时钟正常运行,此时不允许调整时钟。数码管的高两位显示小时,后两位显示分钟,led每闪一次表示时钟运行一次,在调整的过程中,led是停止发亮的。
一、 按键、开关功能说明:
* 按键RESET:按下能复位程序。
* 按键PULSE:提供单脉冲,从而实现单片机对外部脉冲的计数,利用单脉冲实现相应的位加一。
* 开关K0:K0 = 0能调整分位,K0 = 1能调整时位。
* 开关K2:k2为高电平时,使单脉冲输入至INT1,通过外中断实现相应值的加一功能。

二、地址分配和链接
* P2.7: 和写信号一起组成字位口的片选信号,字位口的对应地址为8000H。
* P2.6: 和写信号一起组成字位口的片选信号,字位口的对应地址为4000H。
* D0~D7: 单片机的数据总线LED显示的内容通过D0~D7数据线从单片机传到LED。
* P2.0~P2.5:单片机的P2口,和2764的高位地址线相连,决定2764中的存储单元的地址。
* P1.4~P1.7: 单片机的P1端口,和发光二极管L1~L4相连,通过单片机的P1.4~P1.7控制,所以显示秒表和时钟的时间变化。
* P1.0: 和开关K0相连,决定时间调整的字位。
* P1.1 : 和开关K1相连,决定时间运行的模式。
* P1.2: 和开关K2相连,决定外中断的模式选择。

三、整体功能简介
LED显示模块与单片机的链接中,对LED显示模块的读写和字位、段码的选择通过口P2.6\P2.7完成的。
外部存储器2764是通过锁存器373和单片机相连,并且通过P2端口的相关信号线进行地址的分配。地址范围是0000H~1FFFH。
四、程序设计
  1. /******************************************************
  2. *程序:吴鉴鹰数字电子钟的设计                                                           
  3. ** 这一讲的主要内容: 数字电子钟的设计原理和程序                                                                                
  4. ** 功能描述:  
  5. ** 输 入:         
  6. ** 内容:     
  7. ** 输 出:
  8. **         
  9. ** 全局变量:
  10. ** 调用模块:
  11. **
  12. ** 作 者:    吴鉴鹰
  13. ** 日 期:     14.02.17

  14. 备注:有什么错误的地方,欢迎各大烧友指正

  15. O(∩_∩)O~
  16. *******************************************************/
  17. //变量定义和头文件的调用
  18. //定义头文件和各个输入管脚以及变量声明
  19. #include
  20. #include
  21. #define  uint unsigned int
  22. #define  uchar  unsigned char


  23. /*定义字型字位口*/
  24. #define  DIGPORT  XBYTE  [0X8000]
  25. #define  WORDPORT  XBYTE [0X4000]

  26. /*定义P1口各管脚*/
  27. sbit  K0 = P1^0;
  28. sbit  K1 = P1^1;
  29. sbit  K2 = P1^2;
  30. sbit  BEEP = P1^3;
  31. sbit  L0 = P1^4;
  32. sbit  L1 = P1^5
  33. sbit  L2 = P1^6;
  34. sbit  L3 = P1^7;

  35. uchar  data  BUFFER[2]  = {0,0};  //显示的缓存数组,依次为低位、高位
  36. uchar  data  CLOCK[4] = {0,0,0,0};
  37. uchar  data  SECOND[2] = {0,0};

  38. /*定义运行状态*/
  39. uchar  data  STATE = 0;
  40. /*STATE = 0;秒表*/
  41. /*STATE = 4,或者7,时钟运行*/
  42. /* STATE = 6,时钟时调整 */

  43. bit  bdata  SND = 0;    /*  秒表START(开始)  */
  44. bit  bdata  RST = 0;     /*秒表RESET(复位)*/

  45. /*数码管显示编码“0”-“9”,"A","-"*/
  46. uchar  code  TABLE[] = {0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F,0X77,0X40};

  47. /******************************************************
  48. *程序:主程序                                                                                                                        
  49. ** 功能描述: 主干程序
  50. ** 输 入:         
  51. ** 内容:     
  52. ** 输 出:
  53. **         
  54. ** 全局变量:
  55. ** 调用模块:
  56. **
  57. ** 作 者:    吴鉴鹰
  58. ** 日 期:     14.02.17

  59. 备注:有什么错误的地方,欢迎各大烧友指正

  60. O(∩_∩)O~
  61. *******************************************************/
  62. void  main()
  63. {
  64.       uchar   stabak;
  65.           P1 = 0X0F;
  66.       EA = 1;
  67.       IT1 = 1;
  68.       ET0 = 1;
  69.       TMOD = 0X61;
  70.       TH0 = -5000/256;
  71.       TL0 = -5000%256;
  72.       TH1 = 0XFF;
  73.       TL1 = 0XFF;
  74.       T2CON = 0;
  75.       TH2 = -5000/256;
  76.       TL2 = -5000%256;

  77.        K0 = 1;
  78.        K1 = 1;
  79.        K2 = 1;
  80.        STATE = P1&0X07;
  81.        stabak = STATE;

  82.       for(;;)
  83.     {
  84.            switch()
  85.         {
  86.                 case 0:
  87.                 {
  88.                     EX1 = 0;
  89.                     ET1 = 1;
  90.                     ET2 = 1;
  91.                     TR1 = 1;
  92.                     SND = 1;
  93.                     L1 = 1;   
  94.                     L0 = 0;
  95.                     L2 = 0;
  96.                     SECOND[0] = 0;
  97.                     SECOND[1] = 0;
  98.                 }break;

  99.                  case   5:
  100.                 {
  101.                           IE1 = 0;
  102.                           EX1 = 1;
  103.                           ET1 = 0;
  104.                           ET2 = 0;
  105.                           TR0 = 0;
  106.                           L0 = 1;
  107.                           L1 = 0;
  108.                           L2 = 0;
  109.                 }break;

  110.                 case  6:
  111.                {
  112.                     IE1 = 0;
  113.                     EX1 = 1;
  114.                     ET1 = 0;
  115.                     ET2 = 1;
  116.                     TR0 = 0;
  117.                }break;

  118.                   default:
  119.                {
  120.                    EX1 = 0;
  121.                    ET1 = 0;
  122.                    ET2 = 1;
  123.                    L1 = 0;
  124.                                    L2 = 0;
  125.                }

  126.         }
  127.          while(STATE == stabak)
  128.      {
  129.          switch(STATE)
  130.       {
  131.          case 0:
  132.       {
  133.          BUFFER[0] = SECOND[0];
  134.          BUFFER[1] = SECOND[1];
  135.       }break;
  136.       
  137.       case 5:
  138.       {
  139.           BUFFER[0] = CLOCK[2];
  140.           BUFFER[1] = 101;/*A-*/
  141.       }break;
  142.       
  143.       case 6:
  144.       {
  145.           BUFFER[0] = 110;/*A-*/
  146.           BUFFER[1] = CLOCK[3];
  147.       }break;
  148.       
  149.       default:
  150.       {
  151.           BUFFER[0] = CLOCK[2];
  152.           BUFFER[1] = CLOCK[3];
  153.       }break;
  154.       
  155.       default:
  156.       {
  157.           BUFFER[0] = CLOCK[2];
  158.           BUFFER[1] = CLOCK[3];
  159.       }
  160.       
  161.       }
  162.       
  163.      //显示函数
  164.      display();
  165.      K0 = 1;
  166.      K1 = 1;
  167.      K2 = 1;
  168.      STATE = P1&0X07;   
  169.      }
  170.      stabak = STATE;
  171.     }
  172. }

  173. /******************************************************
  174. *程序:子函数(1):timer0(void)                                                                                                                        
  175. ** 功能描述:  用定时器0实现24小时的时钟显示
  176. ** 输 入:         
  177. ** 内容:     
  178. ** 输 出:
  179. **         
  180. ** 全局变量:
  181. ** 调用模块:
  182. **
  183. ** 作 者:    吴鉴鹰
  184. ** 日 期:     14.02.17

  185. 备注:有什么错误的地方,欢迎各大烧友指正

  186. O(∩_∩)O~
  187. *******************************************************/
  188. void  timer0(void)   interrupt  1  using 1
  189. {
  190.     /*重置定时器初值*/
  191. TH0 = -5000/256;
  192. TL0 = -5000%256;


  193. /*定时器处理*/
  194. CLOCK[0] = CLOCK[0]+1;
  195. if((CLOCK[0] == 50) && (STATE >= 4))
  196. {
  197.     L0 = !L0;
  198. }

  199. if(CLOCK[0] == 100)
  200. {
  201.     if(STATE >= 4)  L0 = !L0;
  202.     CLOCK[0] = 0;
  203.     CLOCK[1] = CLOCK[1] + 1;
  204.    
  205.     if(CLOCK[1] == 60)
  206.     {
  207.        CLOCK[1] = 0;
  208.     CLOCK[2] = CLOCK[2] + 1;
  209.     if(CLOCK[2] == 60)
  210.     {
  211.         CLOCK[2] == 0;
  212.      CLOCK[3] == CLOCK[3] + 1;
  213.      if(CLOCK[3] == 24)
  214.      {
  215.         CLOCK[3] = 0;
  216.      }
  217.     }
  218.     }
  219. }
  220. }

  221. /******************************************************
  222. *程序:子函数(2):intsvr1(void)                                                                                                                        
  223. ** 功能描述:  对外中断1的按键脉冲进行判断和计数,并完成对应的时间调整功能。
  224. ** 输 入:         
  225. ** 内容:     
  226. ** 输 出:
  227. **         
  228. ** 全局变量:
  229. ** 调用模块:
  230. **
  231. ** 作 者:    吴鉴鹰
  232. ** 日 期:     14.02.17

  233. 备注:有什么错误的地方,欢迎各大烧友指正

  234. O(∩_∩)O~
  235. *******************************************************/
  236. void intsvr1(void) interrupt  2  using 2  
  237. {
  238.    if(STATE == 5)
  239.    {
  240.        CLOCK[2] == CLOCK[2] + 1;
  241.     if(CLOCK[2] == 60)  CLOCK[2] == 0;
  242.    }
  243.    if(STATE == 6)
  244.    {
  245.        CLOCK[3] == CLOCK[3] + 1;
  246.     if(CLOCK[3] == 24)  CLOCK[3] = 0;
  247.    }
  248. }

  249. /******************************************************
  250. *程序:子函数(3):display(void)                                                                                                                        
  251. ** 功能描述:  用动态显示的方法,将当前的时间或秒表内容通过数码管显示。
  252. ** 输 入:         
  253. ** 内容:     
  254. ** 输 出:
  255. **         
  256. ** 全局变量:
  257. ** 调用模块:
  258. **
  259. ** 作 者:    吴鉴鹰
  260. ** 日 期:     14.02.17

  261. 备注:有什么错误的地方,欢迎各大烧友指正

  262. O(∩_∩)O~
  263. *******************************************************/
  264. void diplay(void)
  265. {
  266.    uchar i;
  267.    uchar delay;
  268.    uchar disp;
  269.    uchar digit;
  270.    digit = 0x08;
  271.    for(i = 0;i < 2; i++)
  272.    {
  273.       if(BUFFET> 100)  
  274. {
  275.    disp = BUFFER%10 + 10;
  276. }
  277.    else  disp = BUFFER%10;
  278.    
  279.    DIGPORT = digit;
  280.    WORDPORT = TABLE[disp];
  281.    
  282.    for(delay = 0;delay <= 200;delay ++);
  283.    digit = digit >> 1;
  284.    disp = BUFFER/10;
  285.    
  286.    DIGPORT = digit;
  287.    WORDPORT = TABLE[disp];
  288.    
  289.    for(delay = 0;delay <= 200;delay ++);
  290.    digit = digit >> 1;
  291.    }
  292. }
复制代码




本文地址:https://www.eechina.com/thread-130009-1-1.html     【打印本页】

本站部分文章为转载或网友发布,目的在于传递和分享信息,并不代表本网赞同其观点和对其真实性负责;文章版权归原作者及原出处所有,如涉及作品内容、版权和其它问题,我们将根据著作权人的要求,第一时间更正或删除。
liyong7818 发表于 2014-7-11 09:01:36
先谢谢分享,看后在发表意见
您需要登录后才可以发表评论 登录 | 立即注册

厂商推荐

  • Microchip视频专区
  • EtherCAT®和Microchip LAN925x从站控制器介绍培训教程
  • MPLAB®模拟设计器——在线电源解决方案,加速设计
  • 让您的模拟设计灵感,化为触手可及的现实
  • 深度体验Microchip自动辅助驾驶应用方案——2025巡展开启报名!
  • 贸泽电子(Mouser)专区
关于我们  -  服务条款  -  使用指南  -  站点地图  -  友情链接  -  联系我们
电子工程网 © 版权所有   京ICP备16069177号 | 京公网安备11010502021702
快速回复 返回顶部 返回列表