免电源的电话使用计时器
下面为您介绍一款 DIY制作「免电源电话使用计时器」供您避免
上述现象之产生,总共才用了 12个元件(单片机 1个,LED七字显示数码管 2个,电容 3
个,电阻 1个,桥式整流子 1个,电感 1个,石英晶体 1个,稳压二极管 1个,按键 1个
),相信只需要 20多元及 1个休息日即可组装完成做出一个前所未有的趣味电子产品了。
特点说明: DIY制作基本上要有着三个特点: 一看就懂:指电路简单明了。 一买就
有:指电路容易取得。 一做就成:指制作成功率高。 当您看完本篇文章之后一定会有种跃
跃欲试的感觉,那么请跟着感觉走是不会错的。整个 DIY制作虽然小小的,不过特点倒是
挺多项。 免用外部电源,整个 DIY电子产品是利用电话线电压来工作的,故可免除
许多烦人的事(指怕停电,浪费电,体积大,成本高,配线难),在使用上没有任何不适的
感觉,也不须担心电信局测试。 对通话品质无影响,所谓的无影响其实有着二个含
意,一为无杂讯干扰,一为通话音量不增减。大家都知道多位数的 LED七段显示得用扫描
方式,如此一来会有脉冲电流杂讯产生,这点对听觉灵敏的耳朵而言是不可忽视的。另外
整个电路的 AC阻抗得非常的低,以免除声音的衰减。针对这二个要求,这里介绍一个简
单又实用的电源取得电路供您参考。 LED七段显示,非常适合夜晚来使用,同时由于亮
度很够,即使在白天也是清清楚楚,这点就是 LCD显示望尘莫及的。 LED显示不但
能做使用时间的显示之外,也能表示电话线正被使用中,故可当未挂好话筒之提醒指示之
用。 LED显示采用最省元件的互补式,即一个 LED七段显示器为共阴,另一为共阳,
如此即可直接用单片机四个 I/O直接推动而得到最高亮度了。 利用 OTP型单片机
EM78P156来做核心控制,整个程序小小的,若您想更改或增加功能都是非常容易的。
功能说明: 当您的电话使用后没有放置好,或者是打电话聊长天的时候给您显示通话使用
时间给予心理压力。基本上可算是有提醒指示及显示二大功能。 提醒指示: 只要
LED七段显示器点亮则表示电话线正被使用,此时不是您正在打电话就是话筒未被放置好
。 显示: 只要话筒一被拿起,电话回路被建立后单片机开始做计时及显示动作,以
分为单位,最大可显示 99分,之后又从 0开始。若您要有精准的计时时可在电话通之后
按 CLR键,此时单片机清除计数从新开始计数显示。 线路图: 图 1线路说明:
G OF ZERO FC == 00 ;FLAG OF CARRY P5 == 0X05
;PORT 5 P6 == 0X06 ;PORT 6 DL == 0X10 ;DELAY LOOP MIN
== 0X11 ;MINUTE SEC == 0X12 ;SECOND DD == 0X13
;DISPLAY DIGIT DDH == 0X14 ;DISPLAY DIGIT HIGH AB
== 0X15 ;A BACK_UP RFB == 0X16 ;RF BACK_UP ORG
0 0000 JMP INIT ;PROGRAM START ORG 8 ;TCC INTERRUPT----------
----------------------------------- TCCI: 0008 MOV AB,A ;AB <-
A 0009 SWAP AB ;AB <- BA 000A SWAPA RF 000B MOV
RFB,A ;RFB<- FR 000C INC SEC CHECK: 000D MOV A,SEC 000E
SUB A,@59 ;59-SEC=A 000F JBC RF,FC 0010 JMP C_MIN 0011
CLR SEC 0012 INC MIN C_MIN: 0013 MOV A,MIN 0014 SUB
A,@99 ;99-MIN=A 0015 JBS RF,FC 0016 CLR MIN TCCE: 0017
SWAPA RFB 0018 MOV RF,A ;RF<- RFB 0019 SWAPA AB ;A
<- BA 001A BC 0X0F,0 ;CLEAR TCC_INT 001B RETI ;TABLE 7
SEGEMENT------------------------------------------------------ T7: 001C
ADD PC,A ; GFE DCBA 001D RETL @0B01000000 ;0 0100
0000 001E RETL @0B01111001 ;1 0111 1001 001F RETL
@0B00100100 ;2 0010 0100 0020 RETL @0B00110000 ;3 0011
0000 0021 RETL @0B00011001 ;4 0001 1001 0022 RETL
@0B00010010 ;5 0001 0010 0023 RETL @0B00000010 ;6 0000
0010 0024 RETL @0B01011000 ;7 0101 1000 0025 RETL
@0B00000000 ;8 0000 0000 0026 RETL @0B00010000 ;9 0001
0000 ;DELAY ----------------------------------------------------------
-------------- DELAY: 0027MOV P5,A 0028 MOV A,@20 0029 MOV DL,A
D_1: 002A DJZ DL 002B JMP D_1 002C MOV A,@0XFF 002D IOW
P6 002E RET ;INIT ---------------------------------------------
--------------------------------- INIT: 002F MOV A,@0X00 0030 MOV MIN,A
0031 MOV SEC,A 0032 IOW 0X0E ;DISABLE WDT 0033 IOW P5
;PORT 5 OUTPUT 0034 IOW P6 ;PORT 6 OUTPUT 0035 MOV
A,@0X01 0036 IOW 0X0F ;ENABLE TCC_INT 0037 MOV A,@0X05
;1/64 0038 CONTW 0039 ENI ;SCAN --------------------------------
------------------------------------------- SCAN: 003A MOV A,MIN HTD:
003B CLR DDH H_H: 003CADD A,@246 ;A=A-10 003D JBS RF,FC 003E JMP
H_L 003F INC DDH 0040 JMP H_H H_L: 0041 ADD A,@10
0042 CALL T7 0043 IOW P6 0044 MOV P6,A 0045 MOV A,@255
;DISPLAY DIGIT 0 0046 CALL DELAY 0047 MOV A,DDH 0048 CALL
T7 0049 IOW P6 004A XOR A,@0XFF 004B MOV P6,A 004C
MOV A,@00 ;DISPLAY DIGIT 1 004D CALL DELAY 004E JMP SCAN
程序说明: 程序就像日常说话一样,只要能够表达清楚意思,那么,愈短愈受人欢迎(当
然得在保证有正常功能的情况下而言)。此次 DIY制作的软件程序长度仅有 78个指令,够
短了吧,相信看懂也不难。整个程序可以分成 5个段落来做说明,寄存器使用说明: DL
----- 子程序用寄存器 MIN ----- 存放分钟资料寄存器 SEC ----- 存放秒
钟资料寄存器 DD ----- 存放显示位数资料寄存器 DDH----- 存放显示资料寄存器
AB ----- 存放 ACC的副本 RFB ----- 存放 STATUS的副本 TCC中断子程序:
从 0000--001B行为每秒发生一次的 TCC中断子程序,其中 0008--000B及 0017--
0019行为进入及离开中断子程序的 ACC及 STATUS保留动作。其中 000C为每进入一次中断
子程序就将 SEC这寄存器予以进位。其中 000D--0012为判断 SEC寄存
器是否大于 59,是则将 MIN寄存器予以进位并清除 SEC寄存器。其中 0013--0016为判
断 MIN寄存器是否大于 99,是则将 MIN寄存器予以清除,其中 001A为清除 TCC中断旗标
。 LED字型转换程序: 从 001C--0026行存放了字型转换表,可将 0--9的数
字转成相对的 LED七字显示器的资料。 显示时间长度延迟程序: 从 0028--002B延
迟程序,而 0027及 002C--002D为启动显示及关掉显示之指令。 微控制器启始设定程
序: 从 002F--0039行对微控制器内部相关硬件做了必要性的设定动作。值得特别一
提的是 0035--0039行对 TCC中断记数器予以设定成每秒中断一次。计算式如下: 系统
时基/(2周期模式×1秒×256进位)而得预除数为 64。 七字显示器扫描主程序:
从 003A--004E行为本软件程序之主程序部份,又可分三部份。003C--0040行为取得
MIN的拾位数之值。0042--0046行显示 MIN的个位数资料到共阳极的 LED七字显示器上
。0047--004D行为显示 MIN的拾位数资料到共阴极的 LED七字显示器上。希望这短短的
程序难不倒您才是。 程序撰写步骤: 许多人习惯上撰写程序的过程是依照「先小而大」
,「先难后繁」,「边测边写」等三项原则来从事的,底下便将电话使用计时器程序分成
八个段落来完成。 1.先给予心跳: 一般撰写程序碰到计时的工作时不外乎三个
方式来解决: 「用 TIMER计数器来产生中断来计时」「用 POLLING TIMER计数器来计时」
「用计算程序指令个数来计时」 这三个方式中以方式一最为简单也最为准确,故这里打
算最重要之秒的进位问题就交给 TIMER计数器中断方式来解决了。 ; ; FILE
NAME: ; DATE :1999,5,5 ; BY :HWANG JYN_GUO
; ; FUNCTION DESCRIPTION: ; USING TCC TO GET 1 SEC
INTERRUPT ; 32768/(2*64*256)= 1 SEC ; CRYSTAL
MODE 32768 Hz ; 2 CYCLE AND 2 CLOCK MODE ; P5
== 0X05 ;PORT 5 P6 == 0X06 ;PORT 6 ORG 0 0000 JMP INIT
;PROGRAM START ORG 8 ;TCC INTERRUPT------------------------------
------------------------- TCCI: 0008 COM P6 TCCE: 0009BC 0X0F,0 ;CLEAR
TCC_INT 000A RETI ;INIT ---------------------------------------------
---------------------------- INIT: 000BMOV A,@0X00 000C MOV P6,A ;PORT
6 = 0 000D IOW 0X0E ;DISABLE WDT 000E IOW P5
;PORT 5 OUTPUT 000F IOW P6 ;PORT 6 OUTPUT 0010 MOV
A,@0X01 0011 IOW 0X0F ;ENABLE TCC_INT 0012 MOV A,@0X05
;1/64 0013 CONTW 0014 ENI ;SCAN --------------------------------
--------------------------------------- SCAN: 0015 JMP SCAN 这程序的目的是
欲了解 TCC中断能否满足秒的进位问题。 程序说明: 中断子程序: 从 0008--
000A行为简单的中断子程序,每做一次就将 PORT6反向一次,离开前顺便清除中断 FLAG
。 微控制器起始设定程序: 起始设定是每个程序一开始必须做的,主要功能是将一些
会用到的硬件部份做一起始状态的设定以发挥充分的掌控能力。 从 000B~0013行为起始
设定程序 000BMOV A, @0x00 ;将 A内放置零 000C MOV P6, A ;将 P6
内放置零 000DIOW 0x0E ;将 WDT功能除能 000E IOW P5 ;将 P5设为
OUTPUT 000F IOW P6 ;将 P6设为 OUTPUT 在 EM78系列中有所谓的 MEMORY及 I/O
两大空间,一些 MEMORY空间的寄存器处理时可用 MOV、BS、BC、XOR、OR……等指令,而
另一些 I/O空间的控制寄存器处理时可用 IOW、IOR等指令,这点不要弄混了才是。 0010
MOV A, @0x01 ;将 A内放置 1 0011 IOW 0x0F ;仅致能 TCC中断能力
在 EM78156中原本能有 WDT中断、外部中断及 TCC中断等三种能力,如今我们只保留 TCC
中断来使用。 0012 MOV A, @0x05 ;将 A内放置 5 0013 CONTW ;设定 TCC控制
寄存器 0014 ENI ;启动中断能力 TCC是一个很好用也很复杂的硬件线路,下面仅列
出局部有关的地方于附录供大家参考。由于系统时基是采用 32768Hz的石英晶体,故本制
作之准确度应该不被怀疑才是。当选用 2 CYCLE及 2 CLOCK的状态时,若再将 TCC
设成除以 64,那刚好每一秒钟 TCC发生溢位中断一次。 扫描程序: 从 0015--
0015行,总共 1行,仅做跳跃自身之用。 效果观察: 程序写到此时,倘若您手上
的线路没焊错的话,那么您将会看到七字显示屏幕显示 8并且以 1秒亮 1秒灭的速度亮灭
着。 到此总共用 315个指令,恭喜您的宝宝已经有心跳产生了。 2.具有七段显示能力:
有了秒的心跳之后,接下来就是加强扫描能力,使它有着正确的显示数字的能力。
;
; FILE NAME: ; DATE :1999,5,5 ; BY :HWANG
JYN_GUO ; ; FUNCTION DESCRIPTION: ; USING TCC TO
GET 1 SEC INTERRUPT ; 32768/(2*64*256)= 1 SEC
; CRYSTAL MODE 32768 Hz ; 2 CYCLE AND 2 CLOCK
MODE ; PC == 02 RF == 03 ;STATUS FZ == 02 ;FLAG
OF ZERO FC == 00 ;FLAG OF CARRY P5 == 0X05
;PORT 5 P6 == 0X06 ;PORT 6 SEC == 0X10 ;SECOND ORG 0 0000
JMP INIT ;PROGRAM START ORG 8 ;TCC INTERRUPT-----------------
----------------------------- TCCI: 0008 INC SEC TCCE: 0009 BC
0X0F,0 ;CLEAR TCC_INT 000A RETI ;TABLE 7 SEGEMENT------------------
------------------------- T7: 000B ADD PC,A ; GFE DCBA 000C
RETL @0B01000000 ;0 0100 0000 000D RETL @0B01111001 ;1
0111 1001 000E RETL @0B00100100 ;2 0010 0100 000F RETL
@0B00110000 ;3 0011 0000 0010 RETL @0B00011001 ;4 0001
1001 0011 RETL @0B00010010 ;5 0001 0010 0012 RETL
@0B00000010 ;6 0000 0010 0013 RETL @0B01011000 ;7 0101
1000 0014 RETL @0B00000000 ;8 0000 0000 0015 RETL
@0B00010000 ;9 0001 0000 ;INIT --------------------------------
--------------------------------- INIT: 0016 MOV A,@0X00 0017 MOV SEC,A
0018 IOW 0X0E ;DISABLE WDT 0019 IOW P5 ;PORT 5 OUTPUT
001A IOW P6 PORT 6 OUTPUT 001B MOV A,@0X01 001C IOW 0X0F
;ENABLE TCC_INT 001D MOV A,@0X05 ;1/64 001E CONTW 001F
ENI ;SCAN ----------------------------------------------------------
----- SCAN: 0020 MOV A,SEC 0021 CALL T7 0022 IOW P6 0023
MOV P6,A 0024 MOV A,@255 ;DISPLAY DIGIT 0 0025 MOV P5,A
0026 JMP SCAN 整个程序与 最大的差异就是增加了 SEC计数的显示能力,故
有三处改动: 中断子程序中有了 INC SEC指令来做每秒进位的动作。 增加
了 LED显示屏幕七段转换表,从 000B--0015行即为 0到 9的转换表。 扫描程序功能
加强: 从 0020--0026行所做之事为重覆的将 SEC数字经过查表后丢到 P6上。为了方
便了解,此时仅对数字 0有做显示动作。 效果观察: 程序到此时您会看到个位数
的七字显示屏幕从 0→9每秒进位一次。到 9以后程序将会错乱(?Why?)。 3.具有二位数
的显示能力: 能够做七段显示之后,各位最想看到的当然是二位数字的显示了,由于这
里采用一共阴、一共阳的七段显示器,故处理起来还得稍费脑筋。 ; ; FILE
NAME: ; DATE :1999,5,5 ; BY :HWANG JYN_GUO
; ; FUNCTION DESCRIPTION: ; USING TCC TO GET 1 SEC
INTERRUPT ; 32768/(2*64*256)= 1 SEC ; CRYSTAL
MODE 32768 Hz ; 2 CYCLE AND 2 CLOCK MODE ; PC
== 02 P5 == 0X05 ;PORT 5 P6 == 0X06 ;PORT 6 SEC ==
0X10 ;SECOND ORG 0 0000 JMP INIT ;PROGRAM START ORG 8 ;TCC
INTERRUPT------------------------------------------------- TCCI: 0008
INC SEC TCCE: 0009 BC 0X0F,0 ;CLEAR TCC_INT 000A RETI ;TABLE
7 SEGEMENT----------------------------------------- T7: 000B ADD
PC,A ; GFE DCBA 000C RETL @0B01000000 ;0 0100 0000
000D RETL @0B01111001 ;1 0111 1001 000E RETL @0B00100100 ;2
0010 0100 000F RETL @0B00110000 ;3 0011 0000 0010 RETL
@0B00011001 ;4 0001 1001 0011 RETL @0B00010010 ;5 0001
0010 0012 RETL @0B00000010 ;6 0000 0010 0013 RETL
@0B01011000 ;7 0101 1000 0014 RETL @0B00000000 ;8 00
00 0000 0015 RETL @0B00010000 ;9 0001 0000 ;INIT -------------
---------------------------------------------------- INIT: 0016 MOV
A,@0X00 0017 MOV SEC,A 0018 IOW 0X0E ;DISABLE WDT 0019
IOW P5 ;PORT 5 OUTPUT 001A IOW P6 ;PORT 6 OUTPUT
001B MOV A,@0X01 001C IOW 0X0F ;ENABLE TCC_INT 001D MOV
A,@0X05 ;1/64 001E CONTW 001F ENI ;SCAN -------------------
------------------------------------------- SCAN: 0020 MOV A,SEC 0021
CALL T7 0022 IOW P6 0023 MOV P6,A 0024 MOV A,@255
;DISPLAY DIGIT 0 0025 MOV P5,A 0026 MOV A,SEC 0027 CALL
T7 0028 IOW P6 0029 XOR A,@0XFF 002A MOV P6,A 002B
MOV A,@00 ;DISPLAY DIGIT 1 002C MOV P5,A 002D JMP SCAN
程序与 差异之处仅在扫描动作上不同罢了。 若要扫共阳的位数时,必须
将 PORT5外设为高电位输出,而要亮的字划,在 PORT6外设为低电位输入即可。若要扫共
阴的位数 1时,必须将 PORT5外设为低电位输出即可,而要亮的字划,在 PORT6外设为高
电位输出即可。故有了 0020--0025行,位数 0的显示处理及 0026--002C行,位数 1
的显示处理。 效果观察: 程序到此时您会看到二位数的七字显示屏幕,同时从 0→9
每秒进位一次,到 9以后程序将会错乱(?Why?)。 具有限数能力: 以上的程序对 SEC(秒
)都不予限数,当然会造成 CALL TABLE RETEW错误发生,故底下增加 MIN(分)并对
SEC、MIN做 59及 99的限数动作。 ; ; FILE NAME: ; DATE
:1999,5,5 ; BY :HWANG JYN_GUO ; ; FUNCTION
DESCRIPTION: ; USING TCC TO GET 1 SEC INTERRUPT
; 32768/(2*64*256)= 1 SEC ; CRYSTAL MODE 32768 Hz
; 2 CYCLE AND 2 CLOCK MODE ; PC == 02 RF == 03
;STATUS FZ == 02 ;FLAG OF ZERO FC == 00 ;FLAG
OF CARRY P5 == 0X05 ;PORT 5 P6 == 0X06 ;PORT 6 MIN
== 0X10 ;MINUTE SEC == 0X11 ;SECOND DD == 0X12
;DISPLAY DIGIT DDH == 0X13 ;DISPLAY DIGIT HIGH AB
== 0X14 ;A BACK_UP RFB == 0X15 ;RF BACK_UP ORG 0 0000
JMP INIT ;PROGRAM START ORG 8 ;TCC INTERRUPT-----------------
---------------------- TCCI: 0008 MOV AB,A ;AB <- A 0009 MOV
A,RF ;A <- RF 000A MOV RFB,A ;RFB<- RF 000B INC
SEC CHECK: 000C MOV A,SEC ;比较 59秒 000D SUB A,@59 ;59-
SEC=A 000E JBC RF,FC 000F JMP C_MIN 0010 CLR SEC 0011 INC
MIN C_MIN: 0012 MOV A,MIN ;比较 99分 0013 SUB A,@99 ;99-
MIN=A 0014 JBS RF,FC 0015 CLR MIN TCCE: 0016 MOV A,RFB ;A
<- RFB 0017 MOV RF,A ;RF<- RFB 0018 MOV A,AB ;A
<- AB 0019 BC 0X0F,0 ;CLEAR TCC_INT 001A RETI ;TABLE 7
SEGEMENT----------------------------------- T7: 001B ADD PC,A ;
GFE DCBA 001C RETL @0B01000000 ;0 0100 0000 001D RETL
@0B01111001 ;1 0111 1001 001E RETL @0B00100100 ;2 0010
0100 001F RETL @0B00110000 ;3 0011 0000 0020 RETL
@0B00011001 ;4 0001 1001 0021 RETL @0B00010010 ;5 0001
0010 0022 RETL @0B00000010 ;6 0000 0010 0023 RETL
@0B01011000 ;7 0101 1000 0024 RETL @0B00000000 ;8 0000
0000 0025 RETL @0B00010000 ;9 0001 0000 ;INIT -------------
---------------------------------- INIT: 0026 MOV A,@0X00 0027 MOV MIN,A
0028 MOV SEC,A 0029 IOW 0X0E ;DISABLE WDT 002A IOW P5
;PORT 5 OUTPUT 002B IOW P6 ;PORT 6 OUTPUT 002C MOV
A
,@0X01 002D IOW 0X0F ;ENABLE TCC_INT 002E MOV A,@0X05 ;1/64
002F CONTW 0030 ENI ;SCAN ---------------------------------------------
-- SCAN: 0031MOV A,MIN HTD: 0032 CLR DDH H_H: 0033ADD A,@246 ;A=A-
10 16进制转 10进制 0034 JBS RF,FC 0035 JMP H_L 0036 INC
DDH 0037 JMP H_H H_L: 0038ADD A,@10 0039 CALL T7 ;显示
个位 003A IOW P6 003B MOV P6,A 003C MOV A,@255 ;DISPLAY
DIGIT 0 003D MOV P5,A 003E MOV A,DDH ;显示十位 003F CALL
T7 0040 IOW P6 0041 XOR A,@0XFF 0042 MOV P6,A 0043
MOV A,@00 ;DISPLAY DIGIT 1 0044 MOV P5,A 0045 JMP SCAN
程序与 差异之处有下: TCC中断子程序部份增加了 A,R3的暂存动作及
SEC、MIN的限数动作。0008--000A及 0016--0018行系对 A及 R3做暂存及复原的动
作。 000C--0011行系对秒做 59的比较动作,SEC比 59大则 SEC=0,MIN=MIN+1。
0012--0015行系对分做 99的比较动作,若 MIN比 99大则 MIN=0。 此处为何要对中断
子程序做 A及 R3的暂存及复原的动作呢?这是因为在主程序(SCAN)内时时会用到 A及 R3,
及中断子程序中也会用到 A及 R3之故,若不在中断前后将 A及 R3的数值维持不变,那么
主程序将会有错乱的情形产生。 在扫描程序部份增加了 16进制变成 10进制的动作。纵
然二位数字来显示 MIN(分)的讯息是可行的,然将 16进制变成 10进制才能符合人类的习
性。0033--0038行即在做 16进制转 10进制的动作,将 MIN的数值拆成个位数及拾位数
,并在 0039--003D时显示个位数,而在 003E--0044时显示拾位数。 效果观察:
程序到此为止,理论上已做完该完成的所有行为了。但执行起来….为何….为何….忽好
忽坏呢??? 完成正确功能: 将 程序左看右看,上看下看,怎么看也看不出破
绽出来,但为何程序跑起来很不稳定,忽好忽坏的呢?是 ICE不稳呢?还是程序错误呢?答
案当然是程序错误。 ; ; FILE NAME: ; DATE :1999,5,5
; BY :HWANG JYN_GUO ; ; FUNCTION DESCRIPTION: ; USING
TCC TO GET 1 SEC INTERRUPT ; 32768/(2*64*256)=
1 SEC ; CRYSTAL MODE 32768 Hz ; 2 CYCLE
AND 2 CLOCK MODE ; PC == 02 RF == 03 ;STATUS FZ
== 02 ;FLAG OF ZERO FC == 00 ;FLAG OF CARRY
P5 == 0X05 ;PORT 5 P6 == 0X06 ;PORT 6 MIN == 0X10
;MINUTE SEC == 0X11 ;SECOND DD == 0X12 ;DISPLAY DIGIT
DDH == 0X13 ;DISPLAY DIGIT HIGH AB == 0X14 ;A
BACK_UP RFB == 0X15 ;RF BACK_UP ORG 0 0000 JMP INIT
;PROGRAM START ORG 8 ;TCC INTERRUPT------------------------------
------------------------------- TCCI: 0008 MOV AB,A ;AB <- A 0009
SWAP AB ;AB <- BA 000A SWAPA RF 000B MOV RFB,A
;RFB<- FR 000C INC SEC CHECK: 000D MOV A,SEC 000E SUB
A,@59 ;59-SEC=A 000F JBC RF,FC 0010 JMP C_MIN 0011 CLR
SEC 0012 INC MIN C_MIN: 0013 MOV A,MIN 0014 SUB A,@99
;99-MIN=A 0015 JBS RF,FC 0016 CLR MIN TCCE: 0017 SWAPA
RFB 0018 MOV RF,A ;RF<- RFB 0019 SWAPA AB ;A <-
BA 001A BC 0X0F,0 ;CLEAR TCC_INT 001B RETI ;TABLE 7
SEGEMENT----------------------------------------------------- T7: 001C
ADD PC,A ; GFE DCBA 001D RETL @0B01000000 ;0 0100
0000 001E RETL @0B01111001 ;1 0111 1001 001F RETL
@0B00100100 ;2 0010 0100 0020 RETL @0B00110000 ;3 0011
0000 0021 RETL @0B00011001 ;4 0001 1001 0022 RETL
@0B00010010 ;5 0001 0010 0023 RETL @0B00000010 ;6 0000
0010 0024 RETL @0B01011000 ;7 0101 1000 0025 RETL
@0B00000000 ;8 0000 0000 0026 RETL @0B00010000 ;9 0001
0000 ;INIT ------------------------------
--------------------------------------------- INIT: 0027 MOV A,@0X00 0028
MOV MIN,A 0029 MOV SEC,A 002A IOW 0X0E ;DISABLE WDT
002B IOW P5 ;PORT 5 OUTPUT 002C IOW P6 ;PORT 6 OUTPUT
002D MOV A,@0X01 002E IOW 0X0F ;ENABLE TCC_INT 002F MOV
A,@0X05 ;1/64 0030 CONTW 0031 ENI ;SCAN -------------------
------------------------------------------------------ SCAN: 0032 MOV A,MIN
HTD: 0033 CLR DDH H_H: 0034ADD A,@246 ;A=A-10 0035 JBS RF,FC 0036
JMP H_L 0037 INC DDH 0038 JMP H_H H_L: 0039ADD A,@10
003A CALL T7 003B IOW P6 003C MOV P6,A 003D MOV A,@255
;DISPLAY DIGIT 0 003E MOV P5,A 003F MOV A,DDH 0040 CALL
T7 0041 IOW P6 0042 XOR A,@0XFF 0043 MOV P6,A 0044
MOV A,@00 ;DISPLAY DIGIT 1 0045 MOV P5,A 0046 JMP SCAN
原来问题就在中断子程序的 A及 R3暂存及复原这部份。 原来程序在 A及 R3的暂存部
份: 0008 MOV AB, A ;AB←A 0009 MOV A, RF ;A←RF 000A
MOV RFB, A ;RFB←RF 错就错在 0009时 MOV A, RF指令会破坏
ZERO FLAG的资料。故改变指令的用法即可恢复正常,新的程序在 A及 R3的暂存部份:
0008 MOV AB, A ;AB←A 0009 SWAP AB 000A SWAPA RF 000B
MOV RFB, A ;RFB←FR 新的程序在 A及 R3的复原部份: 0017 SWAPA
RFB 0018 MOV RF, A ;RF←RFB 0019SWAPA AB ;A←BA 动作有
点别扭,但是好用得很,请尽量用。 效果观察: 此时此刻的您一定是欢喜异常,眼
睛看着分钟一分一分的增加又不死机,刚才紧绷的心情顿时得到解脱,一切的心血总算有
了回报了。 增加花招: 拿着半成品把玩半天总觉得有些不够完美的,原来是一分
钟才变化一次会让人觉得成品好像没在正常工作,总是怀疑成品是死的,好吧,再动些手
脚将秒的闪烁呈现在七段的小数点上以满足动感要求。 ; ; FILE
NAME: ; DATE :1999,5,5 ; BY :HWANG JYN_GUO
; ; FUNCTION DESCRIPTION: ; USING TCC TO GET 1 SEC
INTERRUPT ; 32768/(2*64*256)= 1 SEC ; CRYSTAL
MODE 32768 Hz ; 2 CYCLE AND 2 CLOCK MODE ; PC
== 02 RF == 03 ;STATUS FZ == 02 ;FLAG OF ZERO
FC == 00 ;FLAG OF CARRY P5 == 0X05 ;PORT 5 P6 ==
0X06 ;PORT 6 DL == 0X10 ;DELAY LOOP MIN == 0X11
;MINUTE SEC == 0X12 ;SECOND DD == 0X13 ;DISPLAY DIGIT
DDH == 0X14 ;DISPLAY DIGIT HIGH AB == 0X15 ;A
BACK_UP RFB == 0X16 ;RF BACK_UP FG == 0X17 ;FLAG ORG
0 0000 JMP INIT ;PROGRAM START ORG 8 ;TCC INTERRUPT----------
----------------------------------------------------- TCCI: 0008 MOV AB,A
;AB <- A 0009 SWAP AB ;AB <- BA 000A SWAPA RF
000B MOV RFB,A ;RFB<- FR 000C COM FG 000D INC SEC CHECK:
000E MOV A,SEC 000F SUB A,@59 ;59-SEC=A 0010 JBC RF,FC 0011
JMP C_MIN 0012 CLR SEC 0013 INC MIN C_MIN: 0014 MOV
A,MIN 0015 SUB A,@99 ;99-MIN=A 0016 JBS RF,FC 0017 CLR
MIN TCCE: 0018 SWAPA RFB 0019 MOV RF,A ;RF<- RFB 001A
SWAPA AB ;A <- BA 001B BC 0X0F,0 ;CLEAR TCC_INT 001C
RETI ;TABLE 7 SEGEMENT--------------------------------------------
---------- T7: 001D CALL TABLE ;用来增加小数点闪烁 001E JBC FG,00 001F
XOR A,@0X80 0020 RET ;TABLE ---------------------------------------
---------------------------------- TABLE: 0021 ADD PC,A ; GFE
DC
BA 0022 RETL @0B01000000 ;0 0100 0000 0023 RETL @0B01111001
;1 0111 1001 0024 RETL @0B00100100 ;2 0010 0100 0025
RETL @0B00110000 ;3 0011 0000 0026 RETL @0B00011001 ;4
0001 1001 0027 RETL @0B00010010 ;5 0001 0010 0028 RETL
@0B00000010 ;6 0000 0010 0029 RETL @0B01011000 ;7 0101
1000 002A RETL @0B00000000 ;8 0000 0000 002B RETL
@0B00010000 ;9 0001 0000 ;INIT --------------------------------
--------------------------------------------- INIT: 002C MOV A,@0X00 002D
MOV MIN,A 002E MOV SEC,A 002F IOW 0X0E ;DISABLE WDT
0030 IOW P5 ;PORT 5 OUTPUT 0031 IOW P6 ;PORT 6 OUTPUT
0032 MOV A,@0X01 0033 IOW 0X0F ;ENABLE TCC_INT 0034 MOV
A,@0X05 ;1/64 0035 CONTW 0036 ENI ;SCAN -------------------
----------------------------------------------------------- SCAN: 0037 MOV
A,MIN HTD: 0038 CLR DDH H_H: 0039ADD A,@246 ;A=A-10 003A JBS
RF,FC 003B JMP H_L 003C INC DDH 003D JMP H_H H_L: 003E
ADD A,@10 003F CALL T7 0040 IOW P6 0041 MOV P6,A
0042 MOV A,@255 ;DISPLAY DIGIT 0 0043 MOV P5,A 0044 MOV A,DDH
0045 CALL T7 0046 IOW P6 0047 XOR A,@0XFF 0048 MOV P6,A
0049 MOV A,@00 ;DISPLAY DIGIT 1 004A MOV P5,A 004B JMP SCAN
要如何增加小数点秒的闪烁呢?其实看结果一点也不困难(话虽如此却也着实的伤了好几条
的脑筋)。 增加 001D~0020这四行程序就可迎刃而解了。 效果观察: 看着
一秒亮一秒灭的成品,此时此刻仅可用一个”爽”字来形容心情,愈来愈觉得其实单片机
制作并不是高不可及啊! 7.好上加好: 如果用示波器来看看制作成果的良好程度时
,可以看到显示周期比才近 50%左右,让人总觉得可惜,倘若能够让显示周期比接近 100%
不亦快哉! 再动手改吧. ; ; FILE NAME: ; DATE
:1999,5,5 ; BY :HWANG JYN_GUO ; ; FUNCTION
DESCRIPTION: ; USING TCC TO GET 1 SEC INTERRUPT
; 32768/(2*64*256)= 1 SEC ; CRYSTAL MODE 32768 Hz
; 2 CYCLE AND 2 CLOCK MODE ; PC == 02 RF == 03
;STATUS FZ == 02 ;FLAG OF ZERO FC == 00 ;FLAG
OF CARRY P5 == 0X05 ;PORT 5 P6 == 0X06 ;PORT 6 DL
== 0X10 ;DELAY LOOP MIN == 0X11 ;MINUTE SEC == 0X12
;SECOND DD == 0X13 ;DISPLAY DIGIT DDH == 0X14
;DISPLAY DIGIT HIGH AB == 0X15 ;A BACK_UP RFB ==
0X16 ;RF BACK_UP FG == 0X17 ;FLAG ORG 0 0000 JMP INIT
;PROGRAM START ORG 8 ;TCC INTERRUPT------------------------------
----------------------------------- TCCI: 0008 MOV AB,A ;AB <-
A 0009 SWAP AB ;AB <- BA 000A SWAPA RF 000B MOV
RFB,A ;RFB<- FR 000C COM FG 000D INC SEC CHECK: 000E
MOV A,SEC 000F SUB A,@59 ;59-SEC=A 0010 JBC RF,FC 0011
JMP C_MIN 0012 CLR SEC 0013 INC MIN C_MIN: 0014 MOV
A,MIN 0015 SUB A,@99 ;99-MIN=A 0016 JBS RF,FC 0017 CLR
MIN TCCE: 0018 SWAPA RFB 0019 MOV RF,A ;RF<- RFB 001A
SWAPA AB ;A <- BA 001B BC 0X0F,0 ;CLEAR TCC_INT 001C
RETI ;TABLE 7 SEGEMENT--------------------------------------------
------------ T7: 001D CALL TABLE 001E JBC FG,00 001F XOR
A,@0X80 0020 RET ;TABLE ------------------
---------------------------------------------------------- TABLE: 0021 ADD
PC,A ; GFE DCBA 0022 RETL @0B01000000 ;0 0100 0000
0023 RETL @0B01111001 ;1 0111 1001 0024 RETL @0B00100100 ;2
0010 0100 0025 RETL @0B00110000 ;3 0011 0000 0026 RETL
@0B00011001 ;4 0001 1001 0027 RETL @0B00010010 ;5 0001
0010 0028 RETL @0B00000010 ;6 0000 0010 0029 RETL
@0B01011000 ;7 0101 1000 002A RETL @0B00000000 ;8 0000
0000 002B RETL @0B00010000 ;9 0001 0000 ;DELAY -------------
--------------------------------------------------------------- DELAY: 002C
MOV P5,A ;增加显示时间之比 002D MOV A,@20 002E MOV DL,A
D_1: 002F DJZ DL 0030 JMP D_1 0031 MOV A,@0XFF 0032 IOW
P6 0033 RET ;INIT ---------------------------------------------
----------------------------------- INIT: 0034 MOV A,@0X00 0035 MOV
MIN,A 0036 MOV SEC,A 0037 IOW 0X0E ;DISABLE WDT 0038
IOW P5 ;PORT 5 OUTPUT 0039 IOW P6 ;PORT 6 OUTPUT
003A MOV A,@0X01 003B IOW 0X0F ;ENABLE TCC_INT 003C MOV
A,@0X05 ;1/64 003D CONTW 003E ENI ;SCAN -------------------
---------------------------------------------------------- SCAN: 003F MOV
A,MIN HTD: 0040 CLR DDH H_H: 0041ADD A,@246 ;A=A-10 0042 JBS
RF,FC 0043 JMP H_L 0044 INC DDH 0045 JMP H_H H_L: 0046
ADD A,@10 0047 CALL T7 0048 IOW P6 0049 MOV P6,A
004A MOV A,@255 ;DISPLAY DIGIT 0 004B CALL DELAY 004C MOV A,DDH
004D CALL T7 004E IOW P6 004F XOR A,@0XFF 0050 MOV P6,A
0051 MOV A,@00 ;DISPLAY DIGIT 1 0052 CALL DELAY 0053 JMP SCAN
人的眼眼睛实在很容易被欺骗,只要扫描频率大于 30Hz其实已经看不到闪烁的现象,故
在不产生闪烁的现象中如何增加显示周期比呢? 增加显示时之时间,故这里增加了
一个 DELAY子程序(002C--0033行所示)供扫描显示时呼叫之用。固定的在个位数及拾位
数显示时各呼叫一次来增加显示周期比。 效果观察: 增加了 DELAY子程序之后约
可提升亮度一倍左右。 8.要善始善终-----永不死机: 正当要关掉 ICE准备烧写
OTP的时候,仔细想想程序才那么小小的,留那么多的空白做什么?不妨拿来「增加稳定度
」之用。 还要动手.? ; ; FILE NAME: ; DATE :1999,5,5
; BY :HWANG JYN_GUO ; ; FUNCTION DESCRIPTION: ; USING
TCC TO GET 1 SEC INTERRUPT ; 32768/(2*64*256)=
1 SEC ; CRYSTAL MODE 32768 Hz ; 2 CYCLE
AND 2 CLOCK MODE ; IAR == 00 ;INDIRECT AR PC ==
02 RF == 03 ;STATUS RSR == 04 ;RAM SELECTOR FZ ==
02 ;FLAG OF ZERO FC == 00 ;FLAG OF CARRY P5
== 0X05 ;PORT 5 P6 == 0X06 ;PORT 6 DL == 0X10 ;DELAY
LOOP MIN == 0X11 ;MINUTE SEC == 0X12 ;SECOND DD ==
0X13 ;DISPLAY DIGIT DG == 0X14 ;DISPLAY DIGIT HIGH
DG=DD=DDH AB == 0X15 ;A BACK_UP RFB == 0X16 ;RF
BACK_UP FG == 0X17 ;FLAG ORG 0 0000 JMP INIT ;PROGRAM
START // // // // 0007 JMP INIT ;PROGRAM START
;TCC INTERRUPT-------------------------------------------------------------
TCCI: 0008 MOV AB,A ;AB <- A 0009 SWAP AB ;AB <- BA
000A SWAPA RF 000B MOV RFB,A ;RFB<- FR 000C COM FG 000D
INC SEC CHECK: 000E MOV A,SEC 000F SUB A,@59 ;5
9-SEC=A 0010 JBC RF,FC 0011 JMP C_MIN 0012 CLR SEC 0013 INC
MIN C_MIN: 0014 MOV A,MIN 0015 SUB A,@99 ;99-MIN=A 0016
JBS RF,FC 0017 CLR MIN TCCE: 0018 SWAPA RFB 0019 MOV
RF,A ;RF<- RFB 001A SWAPA AB ;A <- BA 001B BC
0X0F,0 ;CLEAR TCC_INT 001C RETI 001D JMP INIT ;PROGRAM START
// // // // 0028 JMP INIT ;PROGRAM START ;TABLE 7
SEGEMENT------------------------------------------------------- T7: 0029
CALL TABLE 002A JBC FG,00 002B XOR A,@0X80 002C RET 002D
JMP INIT ;PROGRAM START // // // // 003B JMP
INIT ;PROGRAM START ;TABLE ---------------------------------------
------------------------------------ TABLE: 003C ADD PC,A ; GFE
DCBA 003D RETL @0B01000000 ;0 0100 0000 003E RETL
@0B01111001 ;1 0111 1001 003F RETL @0B00100100 ;2 0010
0100 0040 RETL @0B00110000 ;3 0011 0000 0041 RETL
@0B00011001 ;4 0001 1001 0042 RETL @0B00010010 ;5 0001
0010 0043 RETL @0B00000010 ;6 0000 0010 0044 RETL
@0B01011000 ;7 0101 1000 0045 RETL @0B00000000 ;8 0000
0000 0046 RETL @0B00010000 ;9 0001 0000 0047 JMP INIT
;PROGRAM START // // // // 0055 JMP INIT
;PROGRAM START ;DELAY ---------------------------------------------
------------------------------ DELAY: 0056 WDTC 0057 MOV P5,A 0058
MOV A,@00 0059 IOW P5 005A MOV A,@0X3F 005B MOV RSR,A
005C MOV A,@0X1F 005D MOV DL,A 005E CLRA DELAY1: 005F ADD A,IAR
0060 DEC RSR 0061 DJZ DL 0062 JMP DELAY1 0063 OR A,@00
0064 JBS RF,FZ 0065 JMP INIT ;PROGRAM START 0066 MOV
A,@0XFF 0067 IOW P6 0068 RET 0069 JMP INIT ;PROGRAM
START // // // // 007F JMP INIT ;PROGRAM START
;INIT ------------------------------------------------------------------------
------- INIT: 0080 MOV A,@0X3F 0081 MOV RSR,A 0082 MOV A,@0X2F 0083
MOV DL,A INIT1: 0084 CLR IAR 0085 DEC RSR 0086 DJZ
DL 0087 JMP INIT1 0088 MOV A,@0X00 0089 IOW P5 ;PORT
5 OUTPUT 008A IOW P6 ;PORT 6 OUTPUT 008B MOV
A,@0X80 008C IOW 0X0E ;ENABLE WDT 008D MOV A,@0X01 008E
IOW 0X0F ;ENABLE TCC_INT 008F MOV A,@0X05 ;1/64 0090
CONTW 0091 ENI 0092 JMP SCAN 0093 JMP INIT ;PROGRAM
START // // // // 00B8 JMP INIT ;PROGRAM START
;SCAN ------------------------------------------------------------------------
----- SCAN: 00B9 MOV A,MIN HTD: 00BA CLR DG H_H: 00BB ADD A,@246
;A=A-10 00BC JBS RF,FC 00BD JMP H_L 00BE INC DDH 00BF
JMP H_H H_L: 00C0ADD A,@10 00C1 CALL T7 00C2 IOW P6
00C3 MOV P6,A 00C4 MOV A,@255 ;DISPLAY DIGIT 0 00C5 CALL DELAY
00C6 MOV A,DG 00C7 CALL T7 00C8 IOW P6 00C9 XOR
A,@0XFF 00CA MOV P6,A 00CB MOV A,@00 ;DISPLAY DIGIT 1 00CC
CALL DELAY 00CD JMP SCAN 00CE JMP INIT ;PROGRAM START
// // // // 03FF JMP INIT ;PR
OGRAM START 与 程序的差异之处: 在每个程序的段落「加入 JMP INIT」
指令。 在程序节结尾以后「加入 JMP INIT」指令。 如此一来,不论 IC何时死机
错乱都会跳到开始来执行了。 加入 WATCH DOG TIMER: 来避免程序的错误而
造成死 LOOP现象。 加入错误侦测能力: 利用剩余的寄存器来做引子,随时去读取这
些寄存器,若和不为零则代表错误发生了,应该重新开始。 效果观察: 不论如何故意
的去弄死机都会从头开始正常执行程序了,大功告成。可以加上您认为漂亮合适的外壳,
投入使用了。 附源程序: ; ; FILE NAME: ; DATE
:1999,5,5 ; BY :HWANG JYN_GUO ; ; FUNCTION
DESCRIPTION: ; USING TCC TO GET 1 SEC INTERRUPT
; 32768/(2*64*256)= 1 SEC ; CRYSTAL MODE 32768 Hz
; 2 CYCLE AND 2 CLOCK MODE ; IAR == 00 ;INDIRECT
AR PC == 02 RF == 03 ;STATUS RSR == 04 ;RAM
SELECTOR FZ == 02 ;FLAG OF ZERO FC == 00 ;FLAG
OF CARRY P5 == 0X05 ;PORT 5 P6 == 0X06 ;PORT 6 DL
== 0X10 ;DELAY LOOP MIN == 0X11 ;MINUTE SEC == 0X12
;SECOND DD == 0X13 ;DISPLAY DIGIT DG == 0X14
;DISPLAY DIGIT HIGH DG=DD=DDH AB == 0X15 ;A BACK_UP RFB
== 0X16 ;RF BACK_UP FG == 0X17 ;FLAG ORG 0000 JMP
INIT ;PROGRAM START JMP INIT ;PROGRAM START ;TCC
INTERRUPT-------------------------------------------------------------
TCCI: MOV AB,A ;AB <- A SWAP AB ;AB <- BA SWAPA RF MOV
RFB,A ;RFB<- FR COM FG INC SEC CHECK: MOV A,SEC SUB A,@59 ;59-
SEC=A JBC RF,FC JMP C_MIN CLR SEC INC MIN C_MIN: MOV A,MIN
SUB A,@99 ;99-MIN=A JBSRF,FC CLR MIN TCCE: SWAPA RFB MOV RF,A
;RF<- RFB SWAPA AB ;A <- BA BC 0X0F,0 ;CLEAR TCC_INT RETI
JMP INIT ;PROGRAM START JMP INIT ;PROGRAM START ;TABLE 7
SEGEMENT------------------------------------------------------- T7: CALL
TABLE JBC FG,00 XOR A,@0X80 RET JMP INIT ;PROGRAM START
JMP INIT ;PROGRAM START ;TABLE ---------------------------------------
------------------------------------ TABLE: ADD PC,A ; GFE DCBA
RETL @0B01000000 ;0 0100 0000 RETL @0B01111001 ;1 0111 1001
RETL @0B00100100 ;2 0010 0100 RETL @0B00110000 ;3 0011 0000
RETL @0B00011001 ;4 0001 1001 RETL @0B00010010 ;5 0001 0010
RETL @0B00000010 ;6 0000 0010 RETL @0B01011000 ;7 0101 1000
RETL @0B00000000 ;8 0000 0000 RETL @0B00010000 ;9 0001 0000
JMP INIT ;PROGRAM START JMP INIT ;PROGRAM START ;DELAY ------
--------------------------------------------------------------------- DELAY:
WDTC MOV P5,A MOV A,@00 IOW P5 MOV A,@0X3F MOV RSR,A MOV
A,@0X1F MOV DL,A CLRA DELAY1: ADD A,IAR DEC RSR DJZ DL JMP
DELAY1 OR A,@00 JBS RF,FZ JMP INIT ;PROGRAM START MOV
A,@0XFF IOW P6 RET JMP INIT ;PROGRAM START JMP INIT
;PROGRAM START ;INIT ---------------------------------------------
---------------------------------- INIT: MOV A,@0X3F MOV RSR,A MOV
A,@0X2F MOV DL,A INIT1: CLR IAR DEC RSR DJZ DL JMP INIT1
MOV A,@0X0
0 IOW P5 ;PORT 5 OUTPUT IOW P6 ;PORT 6 OUTPUT MOV
A,@0X80 IOW 0X0E ;ENABLE WDT MOV A,@0X01 IOW 0X0F
;ENABLE TCC_INT MOV A,@0X05 ;1/64 CONTW ENI JMP SCAN JMP
INIT ;PROGRAM START JMP INIT ;PROGRAM START ;SCAN ------
----------------------------------------------------------------------- SCAN:
MOV A,MIN HTD: CLR DG H_H: ADD A,@246 ;A=A-10 JBS RF,FC JMP H_L
INC DDH JMP H_H H_L: ADD A,@10 CALL T7 IOW P6 MOV P6,A MOV A,@255
;DISPLAY DIGIT 0 CALL DELAY MOV A,DG CALL T7 IOW P6 XOR
A,@0XFF MOV P6,A MOV A,@00 ;DISPLAY DIGIT 1 CALL DELAY JMP
SCAN JMP INIT ;PROGRAM START JMP INIT ;PROGRAM START