一、Forth复合字 前面文章:F351(3):Forth点灯,照亮AI单片机学习之路(https://www.stcaimcu.com/forum.php?mod=viewthread&tid=12013)给出了使用“金湖X51_F51编译器”的LED闪烁的星星点灯例子,其效果如下:
(1)星星点灯的Forth程序的主函数部分如下: 其中第89行到第91行是系统引导程序(BOOT),第94行到第99行程序是STC8H单片机端口初始化程序,第103行到113行是主程序(mian())的主循环部分。 (2)在Forth中,基本元素是“词/字(Word)”,每个词都有确定含义,它让计算机完成特定的功能。 (3)复合词定义。就像在C语言中可以用现有的函数新定义一个函数一样,在Forth语言中也允许用现有的词构成一个新的词,新词按次序完成其组成词的功能。这种由其他词组成的词在Forth中称为“复合词/复合字”。在WD-Forth中复合词的定义规范如下: CW_: 新词名称 旧词1 旧词2 ... 旧词N ;_CW 比如可以定义一个新词将一个数乘以10: CW_: *10 10 * ;_CW 以后在程序中使用它就可以完成将堆栈顶上的数乘以10的功能。例如程序:“123 *10 ”的结果是1230。 (4)在Forth语言中,对词的名称的组成字符没有特别的限制,就像上面直接使用“*10”也可以。在Forth如果新词的名称已经存在,编译器不会进行任何警告,只是替代了旧词:从此后新词的功能代替了旧词原有的功能。
二、Forth复合字应用例子 (5)为了简化范例1中的主函数,范例2在第80行处加入了新定义的复合词,下图是本文范例程序“F351_Demo_0502.wdf”中新词的定义部分: (6)在F51汇编语言中,指令“PX, 立即数MOV#”是将立即数赋值给PX端口,这是8051单片机控制外部设备最重要的方法,将这个指令用Forth复合字的方法给出专门的“新指令”,有助于Forth程序的可读性。上面第82行到第84给出了对端口赋值的新指令定义,以后就可以用新指令进行对端口赋值了,比如将“P0, 55 MOV#”指令写为“55 写入_P0”。 (7)利用Forth复合字的方法,也可以像C语言函数一样将整段的程序原样放在复合字的定义中,以后只要用一个Forth就可以完成整段程序的功能。上面第89行到第93行定义了本范例的引导程序部分,第95行到第102行程序定义了对端口的初始化功能。 (8)预先定义了上面的复合字后,使用这些复合字就可以使后面的Forth程序变得清晰明了:
其中第112行是系统引导程序,第115行是端口初始化,第129行是转移语句,第119行到127行每行程序实现一个功能,整个程序简洁多了。 并且引入汉字复合词名称后,程序的可读性大大加强了。 (9)如果将上面程序用C语言写,对应的程序如下: 可以看出C语言与Forth汇编语言程序是一一对应的。 (10)结论:C语言是公认的高级计算机语言,借助Forth语言的复合词功能,就将Forth 8051汇编语言升级为高级计算机语言了。 这样以后用Forth语言编写STC单片机就能够像C语言一样简单方便,不必处处像汇编语言一样冗长难懂了。
三、Forth“虚词”,打造有味的中文程序 (11)笔者一直认为:计算机程序不单只是给计算机编译器看的,更重要是给人看到(最少编程的是个人),因此编出来的程序就是一种作品,是作品就要完善到艺术,是艺术就要提高到有文化,要文化就要带有点中文味。 (12)Forth语言的复合词也可以是虚词,就是光有词的名字,并不包含任何内容。这样的虚词在计算机程序执行时没有任何作用,但是人类读它的时候感觉就不一样了。下面是将范例2程序加上虚词后的样子: 其中第104行到第106行程序定义了3个虚词,然后将虚词加入到主循环语句中,就成了下面的样子。
================================================================== 写在最后: 考试题:如何编写STC单片机程序,使得单片机上的3组LED灯如上面视频中那样闪烁? 答: Main_Loop 将十六进制数 55 写入_P0, 将十六进制数 33 写入_P1, 将十六进制数 F0 写入_P2, 延时500毫秒, 将十六进制数 AA 写入_P0, 将十六进制数 CC 写入_P1, 将十六进制数 0F 写入_P2, 延时500毫秒, 向 Main_Loop 转移, 如此循环,永不停止。
请问,这样的程序能得几分?
|