(二)解读程序工作原理
(瑶汉牧)莫尔斯电码自动解读程序见所附的源程序清单。语句中凡是(')符号右面的内容均为注释,仅供阅读时参考,与程序本身工作无关,可以省略。
第70号语句定义了一个数组MC$,用以存放莫尔斯电码表。当程序执行到第160至180句时,原堆放在第590至630句中的电码表数据被读入数组MC$备查。电码表的数据在MC$中是这样安排的:一个点信号即字母“E”,放在数组MC$的第二号单元中。两个点即字母“I”,放在地址比一个点的单元大一倍的地方,即第4号单元。三个点“S”放在第8单元,四个点“H”放在第16单元,依次类推,多一个点者,地址加倍。一个划信号即字母“T”,放在比一个点信号“E”地址大一号的单元,即第3单元中。依次类推,“的大(A)”放在“的的(I)”后面单元,即5号单元。“的的的大(V)”放大四个点“H”后面即第17单元。“的大的(R)”比“A”多一个点,因此放在地址比“A”大一倍的单元,即第10号。而“的大大(W)”则应放在“R”后面,即第11号单元。电码表数据的这种安排是为了程序便于查找。
程序通过两个循环不断对计算机的异步通信接口DSR寄存器扫描。
其中一个循环由第230及250句转向语句构成。当DSR为低电位时,程序反复执行230及250句,每循环一次将空号计时变量TS加一,直到检测到有信号(DSR变高)才跳出循环。这时TS的值表示刚才无信号(空号)所持续的时间长短。
另一个循环由第410句转向语句构成。当DSR为高电位时,程序反复执行410句,每循环一次将传号计时变量TM加一,直到检测到信号消失(DSR变低)才跳出循环。这时TM的值表示刚才有信号(传号)所持续的时间长短。
程序启动后,在空号检测循环不断查询通信接口,等待第一个电码信号的到来。
收到第一个电码信号后,进入传号检测循环,不断查询通信接口,等待第一个电码信号的结束。然后在第430句将这个码元的长度TM假设是一个“点”信号的标准长度T0。接着返回空号检测循环等待下一码元。
在等待过程中,由第250句判断等待时间是否已超出字与字之间的间隔标准。如是,则调整用显示子程序将当前电码译出并显示。
等待到下一个码元后,程序由第230句转入第270句,判断当前的码元间隔是否小于标准“点”信号的三分之一。如果是,则说明前面收到的第一个码元应当是“划”,刚才假设为“点”,应予以纠正。
在第280句到290句,判断前相邻码元间隔,如大于字与字之间的间隔标准,则调用显示子程序译出并显示当前电码。如大于组与组之间的间隔标准,则多显示一个空格。如间隔时间很长,则插入一次换行,使后面的电文另起一行。
如果前一个字符已经显示完毕,则执行第370句,使电码表的指针指向第1号单元。如果这个字符还没有处理完,则由250句直接跳到第390句。
接收到每一个码元后,先由440句判断,如发现码元长度小于标准“点”的十分之一,则认为收到的是窄脉冲干扰,不予理睬。如果不是这种干扰,则先假设这个码元至少是一个“点”。按照电码表的排列规律,应该把指针移到原来所指单元地址的两倍的那个地址上去。
在第460句,对该码元进行长度判别,如果确实是“点”,则不再作任何处理。如果是个“划”,则按照电码表排列规律,将指针往后移一个单元。同时判断当前的“划”信号是否和原来的时间参数相吻合。如果这个“划”特别长,说明发报速度可能突然变慢,则根据这个“划”的长度重新修改原来的标准时间值。如果这个“划”基本与原参数吻合,则仅对原来的标准“划”略作微调以适应可能发生的速度渐变现象。
对程序性能影响最大的参数是第80、90和100句中的三个变量。尤其是字间隔长度系数KCS,如太大,则对于字间隔偏小的手法适应性差,如太小,则对于点划脱节的手法适应性差。本程序除了在第220句中采用经实际信号修正过的“划”作为判别间隔的基础,能较好地适应标准点划比例间隔、“划”长“点”细、“划”后抢“点”等常见手法外,还经常在320句查询键盘,如果在键盘直接接下“ 0”至“9”数字键中的任何一个,可对KCS进行调整。数字越小,越接近原设置。数字越大,对点划脱节的宽余度越大,而对“抢”间隔的宽余度越小。
本程序可在多数BASIC语言环境下运行。首次运行时,应先用一个电键,直接跨接在计算机RS-232异步串行通信口插座的DTR和DSR两端,用比较标准的手法试拍各个字符,观察计算机是否能正确显示相应字符,以便发现在打入程序时可能发生的错误。一切正常后,再接入上期介绍的电码检出电路进行联机接收。
应当说明的是,计算机自动解读可以减轻人们的劳动,但还不能完全代替人的大脑。当信噪比不佳、干扰较多时,人工抄收质量会比机器好得多。尤其是本程序具有自动适应速度变化以及不同手法的能力,但干扰频繁时,程序无法完全将干扰脉冲分离出来,而反会把干扰脉冲当作电码去跟踪,造成混乱。有兴趣的朋友可以根据自己的使用要求对程序加以修改,以适应特定的目标。也希望大家能设计出兼顾范围更广的电码解读系统。
上期图1中IC2(TIL117)第4脚与计算机CTS端中应串入一个10k欧电阻,特此说明。
A
10 ′莫尔斯电码自动解读BASIC程序
20 ′适用于各档IBM—PC微型计算机及其兼容机
30 ′
40 ′<程序段—初始化处理:>
50 KEY OFF:CLS
60 PRINT TAB(16);″MORSE DECODING SOFT WARE FROM BZIHAM, NOV.1993″
70 DIM MC$(255):NO=0: YES=NOT(NO)
80 DASH=2 ′划与点的最小比例
90 KCS=.4 ′字间隔与划的最小比例
100 KWS=2 ′词(组)间隔与字间隔的最小比例
110 KLS=20 ′自动换行时间(以字间隔为单位)
120 PORT=&H3F8 ′COM1串行通信口的I/O
地址。如改用COM2,应改为PORT=&H2F8
130 OUT PORT+4,1 ′设置串行通信口DSR和CTS线的初始电位
140 ′
150 ′<程序段—读入电码表:>
160 FOR I=0 TO 255
170 READ MC $(I): IF MC $(I)=″END″ THEN GOTO 200
180 NEXT I
190 ′
200 ′<程序段—空号处理:>
210 TS=0 ′空号计时变量
220 CSPC=ODS*KCS ′字间隔
230 IF(INP(PORT+6) AND &H20)>0 THEN
GOTO 270 ELSE TS=TS+1 ′判空号状态结束否
240 ′下一句判断加间隔超时即自动结束当前字符并显示
250 IF TS<CSPC THEN GOTO 230 ELSE GOSUB 520: GOTO 230
260 ′下一语句根据信号间隔过小判定原将划错设为标准点,并予纠正
270 IF TS<TO/3 AND TM<TO* DASH THEN ODS=TO: TO=TS: IF N=2 THEN N=3
280 IF TS<CSPC THEN GOTO 390 ELSE GOSUB 520 ′信号间隔满字间隔
290 IF TS>CSPC* KLS THEN PRINT ELSE IF TS>CSPC* KWS THEN PRINT″ ″;′换组或换行
300 ′
310 ′(程序段—键盘命令)
320 K$=INKEY$: IF K$=CHR$(27) THEN END ′<ESC>键中止运行
330 ′下句允许通过按数字键0至9来选择补偿点划脱节手法的参数。9允许最严重的脱节
340 IF K$>=″0 ″ AND K$<=″9″THEN KCS=.4+VAL(K$)*.1: PRINT″[″;VAL(K$);″]″;
350 ′
360 ′<程序段—开始处理一个新字符:>
370 N=1 ′电码表初始指针
380 ′
390 ′<程序段—传号处理:>
400 TM=0 ′传号计时变量
410 IF(INP(PORT+6) AND&H20)>0 THEN TM=TM+1: GOTO 410 ′判传号状态结束否
420 IF T0>0 THEN GOTO 440 ′仅开始运行后的第一个信号结束时才执行下一语句
430 TO=TM: ODS=TO*DASH ′开始时将第一个信号假设为标准点
440 IF TM<TO/10 THEN GOTO 500 ′滤除窄脉冲干扰
450 N=N+N ′每遇一个新信号代码表指针值加倍
460 IF TM<TO*DASH THEN GOTO 500′点信号无特殊处理
470 N=N+1 ′遇划信号代码表指针向后推一格
480 ′下一句为划信号处理,如速度突然变慢则重设标准点划长度,否则仅动态微调标准划
490 IF TM>ODS*DASH*1.5 THEN TO=ODS:ODS=TO*DASH ELSH ODS=(ODS+TM)/2
500 GOTO 200 ′返回空号处理
510 ′
520 ′<子程序—显示解读出的字符:>
530 IF N=0 THEN GOTO 560 ′无信号时,即使满字间隔时间,也无内容可显示
540 ′下一句中非正常码被显示为小写的x,如遇—…—则自动插入换行
550 IF N>255 THEN PRINT ″X″; ELSE PRINT MC$(N);: IF MC$(N)=″=″ THEN PRINT
560 N=0: RETURN
570 ′
580 ′(数据—电码符号表:)
590 DATA,,E,T,I,A,N,M,S,U,R,W,D,K,G,O,H,V,F,x,L,x,P,J,B,X,C,Y,Z,Q,x,x
600 DATA 5,4,<sn>,3,x,x,x,2,<as>,x,<ar>,x,x,x,x,1,6,=,/,x,x,<starting>
610 DATA(,x,7,x,x,x,8,x,9,0,x,x,x,x,x,<sk>,x,x,x,x,x,x,?,-,x,x,x,x,<″>
620 DATA x,<p>,.,x,x,x,x,x,x,x,x,′,x,x,-,x,x,x,x,x,x,x,x,;,x,x,),x,x,x
630 DATA x,x,″,″,x,x,x,x,″:″:x:x:x:x:x:x:x:x,x,x,x,x,x,x,x,x,″$″,END