搜索
查看: 436|回复: 0

ADuC841的例程——TIC的应用:电子钟

[复制链接]

177

主题

458

帖子

5871

积分

论坛元老

Rank: 8Rank: 8

积分
5871
发表于 2016-3-1 16:25:45 | 显示全部楼层 |阅读模式
  1. 实验6-3:TIC的应用:电子钟

  2. 利用TIC可以很容易地实现电子钟,一个简单的电子钟程序如下。

  3.                    $MOD841                              ; ADuC841的预定义函数库。每个ADuC841的程序必须有。

  4.       SP0    EQU   50H                ; 定义堆栈的初始指针

  5.       CLK81  EQU   P3.5               ; 键盘显示芯片WH8281串行口的时钟线接P3.5

  6.       DAT81  EQU   P3.3               ; 键盘显示芯片WH8281串行口的数据线接P3.3

  7.       SHUZHI EQU   30H                ; 定义数据缓冲器的指针

  8.       KEY    EQU   P3.2               ; 键盘显示芯片WH8281的中断申请线接P3.2

  9. ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

  10. ORG  0000H                       ; 开始执行的第一条指令所处的地址

  11.                             LJMP  MAIN                     ; 跳转到主程序

  12.               ORG  0053H                       ; TIC中断复位子程序入口地址

  13.                       LJMP  SERVE                    ; 跳到TIC中断服务子程序

  14. ;----------------------------------- --------------------主程序入口,初始化ADuC841

  15. MAIN:               MOV  R0, #0FFH               ; 清除片内RAM,从0FFH开始向下清除

  16.                      CLR  A                                ; 清除累加器A

  17. QING:                MOV  @R0, A                    ; 清除片内RAM,

  18.                       DJNZ  R0, QING               ; 没有到00H,继续

  19.                       MOV  SP, #SP0                  ; 设置堆栈起始地址

  20. ;----------------------------------- --------------------

  21. SETB  EA                           ; 开启中断

  22.                       MOV  IEIP2, #04H             ; 允许TIC中断

  23.                       MOV  TIMECON, #53H   ; 设置TIC为24小时、秒寄存器输出、TIC使能和时钟使能

  24.                       MOV  INTVAL, #01H    ; 每秒中断一次

  25. HERE:                LJMP  $                              ; 等待中断

  26. PP:                   LCALL  INI8281                ; 初始化WH8281。这是模块化编程的方法。

  27. ;----------------------------------- --------------------分隔程序,以下为TIC中断服务子程序

  28. SERVE:               LCALL  XIANSHI             ; 在中断服务子程序中只需显示,所以调用显示子程序

  29.                       RETI                                               ; 中断返回

  30. ;----------------------------------- --------------------分隔程序,以下为初始化WH8281子程序

  31. INI8281:             SETB  CLK81                     ; 该子程序用模拟串口的方式送数到WH8281并初始化

  32.                     SETB  DAT81                    ; 对时钟线和数据线置1,准备送数

  33.                     MOV  A, #12H                            ; 准备送往WH8281的初始化数据

  34.                     LCALL  WTO81                 ; 调用写入WH8281的子程序

  35.                     MOV  A, #80H                            ; 准备送往WH8281的初始化数据

  36.                     LCALL  WTO81                 ; 调用写入WH8281的子程序

  37.                     RET                                       ; 返回

  38. ;----------------------------------- --------------------分隔程序,以下为WH8281显示子程序

  39. XIANSHI:          MOV  A, #02H          ; 在时、分、秒之间显示“-”

  40.                             LCALL  WTO81                 ;

  41.                             MOV  A, #0BFH                ;

  42.                             LCALL  WTO81                 ;

  43.                            MOV  A, #05H                            ;

  44.                             LCALL  WTO81                 ;

  45.                             MOV  A, #0BFH                ;

  46.                             LCALL  WTO81                 ;

  47. ;---------------------------------------------            

  48.                     MOV  A, SEC                     ; 从TIV中读出秒数据

  49.                     LCALL  CHULI                  ; 把十六进制数据转换成压缩BCD码

  50.                     MOV  R0, #60H                 ; 秒显示在第6位(十位)

  51.                      MOV  R1, #70H                 ; 和第7位(个位)

  52.                     LCALL  ZHU_XIANSHI   ; 调用送数到WH8281的子程序

  53. ;---------------------------------------------              

  54.                     MOV  A, MIN                    ; 从TIV中读出分数据

  55.                     LCALL  CHULI                  ; 把十六进制数据转换成压缩BCD码

  56.                     MOV  R0, #30H                 ; 分显示在第3位(十位)

  57.                     MOV  R1, #40H                 ; 和第4位(个位)

  58.                     LCALL  ZHU_XIANSHI   ; 调用送数到WH8281的子程序

  59. ;---------------------------------------------              

  60.                     MOV  A, HOUR                ; 从TIV中读出时数据

  61.                     LCALL  CHULI                  ; 把十六进制数据转换成压缩BCD码

  62.                     MOV  R0, #00H                 ; 时显示在第0位(十位)

  63.                     MOV  R1, #10H                 ; 和第1位(个位)

  64.                     LCALL  ZHU_XIANSHI   ; 调用送数到WH8281的子程序

  65. ;---------------------------------------------              

  66.                     RET                                       ; 返回

  67. ;===================分隔程序,以下为送数到WH8281显示子程序

  68. ZHU_XIANSHI:         MOV  A,#14H                    ; 送控制字

  69.                 LCALL  WTO81                 ;

  70.                 MOV  A, SHUZHI             ; 读显示数据

  71.                 ANL  A, #0F0H                           ; 分离十位和个位

  72.                 SWAP  A                             ;

  73.                 ORL  A, R0                         ; 合成显示位置和显示数

  74.                 LCALL  WTO81                 ; 送数

  75.                 MOV  A, #14H                            ;

  76.                 LCALL  WTO81                 ;

  77.                 MOV  A, SHUZHI             ;

  78.                 ANL  A, #0FH                    ;

  79.               ORL  A,R1                          ;

  80.                 LCALL  WTO81                 ;

  81.                 RET                                       ;

  82. ;===================分隔程序,以下为把十六进制数据转换成压缩BCD码的子程序

  83. CHULI:               MOV  B, #10                      ; 把需变换的数除10,商为十位数,余数为个位数

  84.                       DIV  AB                              ;

  85.                       SWAP  A                             ;

  86.                       ADD  A, B                          ;

  87.                       MOV  SHUZHI, A            ;

  88.                       RET                                       ;

  89. ;===================分隔程序,以下模拟串口送数到WH8281子程序

  90. WTO81:             MOV  R6, #08H                 ; 送8位(一个字节的)数

  91. WAT:               CLR  CLK81                         ; 产生宽度为“DELAY”的低电平脉冲

  92.                             LCALL  DELAY                 ;

  93.                             SETB  CLK81                     ;

  94.                             JB  DAT81, WAT              ; 判断数据数据线(WH8281的响应)

  95.                             CLR  CLK81                         ; 产生宽度为“DELAY”的低电平脉冲

  96.                             LCALL  DELAY                 ;

  97.                             SETB  CLK81                     ;

  98.                             JNB  DAT81, $                            ;

  99. WTB81:              RLC  A                                ; 经过C送数

  100.                             MOV  DAT81, C                ;

  101.                     CLR  CLK81                       ;

  102.                           LCALL  DELAY                 ;

  103.                             SETB  CLK81                     ;

  104.                             LCALL  DELAY                 ;

  105.                             LCALL  DELAY                 ;

  106.                             DJNZ  R6, WTB81             ; 共送8位数

  107.                             SETB  DAT81                    ;

  108.               RET                                       ;

  109. ;===================分隔程序,以下为短延时子程序

  110. DELAY:                     NOP                                      ;

  111.                     NOP                                      ;

  112.                     NOP                                      ;

  113.                     NOP                                      ;

  114.                     NOP                                      ;

  115.                     NOP                                      ;

  116.                     NOP                                      ;

  117.                     NOP                                      ;

  118.                     NOP                                      ;

  119.                     NOP                                      ;

  120.                     NOP                                      ;

  121.                     NOP                                      ;

  122.                     RET                                       ;

  123. ;===================分隔程序,以下为长延时子程序

  124. YS:                       MOV  R5, #00H                 ;

  125.                             MOV  R4, #50H                 ;

  126. YS1:                     DJNZ  R5, $                        ;

  127.                             DJNZ  R4, YS1                            ;

  128.                             RET                                       ;

  129.                             END                                      ; 全部程序结束

  130. 附:作为对比,下面给出标准8052采用定时器实现的电子钟的部分代码。重点注意实现软件时钟的部分。

  131.          ORG  0000H                       ; 实验板开始执行的第一条指令所处的地址

  132.                    LJMP  MAIN                     ; 跳转到主程序

  133.                    ORG  000BH                      ; 定时器0中断入口地址

  134. LJMP  TINT0                    ; 跳转到定时器0中断服务子程序

  135.          ORG  0100H                       ; 主程序开始的地址;避开中断入口地址

  136. MAIN:      MOV  SP, #0D0H                     ; 设置堆栈起始地址

  137.            LCALL  INT8255               ; 初始化CPU,注意用不同的子程序完成一定的功能,这是模块化

  138.                                                         ; 编程技术之一,方便程序的开发、管理和维护

  139.                    MOV  R3, #00H                       ; 时计数存储单元

  140.                    MOV  3FH, #50                 ; 装入中断次数

  141.          MOV  40H, #00H                     ; 秒低位存储单元

  142.          MOV  41H, #00H                     ; 秒高位存储单元

  143.            MOV  42H, #0FFH                    ; 分、秒间显示符号"-"

  144.                    MOV  43H, #00H                     ; 分低位

  145.          MOV  44H, #00H                     ; 分高低位

  146.          MOV  45H, #0FFH                    ; 时、分间显示符号"-"

  147.                    MOV  46H, #00H                     ; 时低位

  148.          MOV  47H, #00H                     ; 时高位

  149.      

  150.          SETB  ET0                  ; T0开中断

  151.                    SETB  EA                            ; CPU开中断

  152.          ORL  TMOD,  #01H                 ; 设置定时器0工作在模式1

  153.          MOV  TH0,  #0B8H                  ; 设定定时器初值,定时时间为20ms。赋TH0初值为0B8H

  154.          MOV  TL0,  #00H            ; 赋TL0初值为00H(假定12MHz时钟)

  155.          SETB  TR0                   ; 启动T0

  156. L1:         LCALL  LED               ; 调LED子程序

  157.                    LJMP  L1

  158.                            

  159. INT8255:   MOV  P2, #58H               ; 使ADuC841P2指向8255PA的控制寄存器接口结构,ADuC841P0口地址应与低8位无关

  160. MOV  A, #82H                       ; 8255A的控制字(82H),8255PC口输出PB口输入,PA口输出

  161.          MOVX  @ R0, A                ; 送8255A控制字

  162.          RET         



  163. TINT0:            MOV  TH0, #0B8H            ; 重赋定时器初值

  164.          MOV  TL0, #00H

  165.         PUSH  PSW                ; 保护现场

  166.             PUSH  ACC

  167.                    DJNZ  3FH, RETURN      ; 1S未到返回

  168.                    MOV  3FH, #50             ; 重置中断次数

  169.                    INC  40H                    ; 秒低位加1

  170.                    MOV  A, 40H      

  171.                    CJNE  A, #0AH, RETURN         ; 未满10S返回

  172.                    MOV  40H, #00H           ; 计满10S,秒低位清0

  173.                    INC  41H                    ; 秒高位加1

  174.                    MOV  A, 41H      

  175.                    CJNE  A, #06H, RETURN ; 未满60S返回

  176.                    MOV  41H, #00H           ; 计满60S,秒高位清0

  177.                    INC  43H                    ; 分低位加1

  178.           MOV  A, 43H      

  179.                    CJNE  A, #0AH, RETURN         ; 未满10分返回

  180.                    MOV  43H, #00H           ; 计满10分,分低位清0

  181.                    INC  44H                    ; 分高位加1

  182.                    MOV  A, 44H

  183.          CJNE  A, #06H, RETURN ; 未满60分返回

  184.                    MOV  44H, #00H           ; 计满60分,分高位清0

  185.                    INC  46H

  186.                    INC  R3

  187.                    CJNE  R3, #24, H1                     ; 未满24小时跳转

  188.                    MOV  47H, #00H   

  189.                    MOV  46H, #00H

  190.          LJMP  RETURN           ; 满24小时,时高低位均清0

  191. H1:            MOV  A, 46H      

  192.           CJNE  A, #0AH, RETURN ; 未满10小时返回

  193.                    MOV  46H, #00H           ; 计满10小时,时低位清0

  194.          INC  47H                    ; 时高位加1

  195. RETURN: POP  ACC                          ; 恢复现场

  196.              POP  PSW         

  197.                    RETI



  198. LED:      MOV  R2, #04H             ; 从右到左LED的位码依次为7F,BF,DF,EF,FE,FD,FB,F7            

  199.               MOV  R5, #07FH          ; R5作为位选寄存器  

  200.          MOV  R1, #40H

  201. DISPLAY1:MOV  36H, @R1

  202.           LCALL  LED1            

  203.           MOV  A, R5

  204.           MOV  P2, #50H                        

  205.           MOVX  @R0, A              ; 送位选码入PC口

  206.           LCALL  TMS                            ; 延时1.024ms

  207.           INC  R1        

  208.           MOV  A, R5

  209.           RR  A

  210.           MOV  R5, A

  211.           DJNZ  R2, DISPLAY1

  212.           MOV  R2, #04H

  213.           MOV  R5, #0FEH            ; 使左四位LED亮

  214.           MOV  R1, #44H

  215. DISPLAY2:MOV  36H, @R1

  216.          LCALL  LED1

  217.               MOV  A, R5  

  218.          MOV  P2, #050H

  219.          MOVX  @R0, A

  220.          LCALL  TMS

  221.          MOV  A, R5

  222.          RL  A

  223.          MOV  R5, A

  224.          INC  R1

  225.          DJNZ  R2, DISPLAY2

  226. OU1:    RET

  227.       

  228. LED1:   MOV  P2, #040H                ; 送段码子程序

  229.               MOV  DPTR, #TAB

  230.          MOV  A, 36H

  231. AAA:      CJNE  A, #0FFH, BBB

  232. MOVX  A, @DPTR

  233. MOVX @R0,A

  234. RET

  235. BBB:     DEC A

  236. INC DPTR

  237. LJMP AAA   

  238.            

  239. TMS:     MOV  R6, #0FFH              ; 给R6和R6赋初值,在12Hz晶振时延时时间为2(R7循环次数)

  240. MOV  R7, #02H                 ; 256(R6循环次数)×2×10--6(DJNZ指令耗时)1.024MS

  241. DELAY01: DJNZ  R6, $                       ; R6单元减1,非0继续执行当前指令,"$"指当前指令地址

  242. DJNZ  R7, DELAY01        ; R7减1,非0跳转到标号DELAY01处执行

  243.          RET                    

  244.         

  245. TAB:                  DB 0BFH, 0C0H, 0F9H, 0A4H, 0B0H, 99H, 92H, 82H, 0F8H, 80H, 90H         

  246. END
复制代码


回复

使用道具 举报

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

本版积分规则

小黑屋|手机版|Archiver|EEFOCUS

论坛已做迁移,有相关技术资料和问题讨论可以到电路城对应版块(“模拟/电源”)
X

GMT+8, 2019-12-10 18:33 , Processed in 0.143732 second(s), 10 queries , MemCache On.

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

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