代码的移植性是对编程人员的一大检测,这个问题应该时间考虑。乃至从你策划项目的一会儿开端,就应该考虑到代码或许会被屡次修正,或许功能模块的删减等。项目的外围硬件许多时分都会依据需求改动,究竟怎样样的编写技巧能使修正量降至最小,而又能很好的完结项目呢?这便是今日研讨的论题。这儿先说一些小的比如,以及实践怎样运用。
(1)用宏界说替代直接IO操作
我觉得最典型的比如便是蜂鸣器,4KHZ驱动的沟通蜂鸣器,假设蜂鸣器接在 P50 口,那么驱动的代码就应该是:
mov a,@0x01
xor 0x05,a
代码很简略,0x01 和 P5口异或出来的成果,便是 P50 口取反,不断的取反那么得到的是 P50 口输出方波,用C言语来描绘便是:
PORT5 ^= 0x01
好了,这个代码的移植性超级差,假设我的蜂鸣器现在需求修正到 P62口,那么代码也有必要相应的修正为:
mov a,@0x04
xor 0x06,a
当然了,咱们这儿只需求一处,还不见得费事,假设你的代码中有50处,乃至100处需求修正,我想你肯定要抓狂。所以这种不行移植的代码有必要丢掉。
修正版1:
经过界说蜂鸣器的IO口来处理
buz_port EQU 0x05
mov a,@0x01
xor buz_port,a
这儿用 buz_port 这个姓名替代了蜂鸣器的输出端口,那么现在移植性有了进步,假设修正了端口的话,咱们只需求从头界说 buz_port 这个宏,就完结了对代码的一切的修正。
依照上面的描绘,能处理了端口的问题,可是咱们发现,问题还没有彻底处理,mov a,@0x01 咱们还得手艺核算蜂鸣器在哪个引脚上面,并且还得在一个一个的修正,所以还需求改善。
修正版2:
buz_port EQU 0x05
buz_pin EQU 0
mov a,@1< xor buz_port,a 这个代码就真实完成了所谓的移植性。用C言语来解释一下 buz_port ^= 1< 假设C言语过关的同学应该对这个表达式很熟悉了。1< 例如 1<<0 得到的成果是 1 (00000001b) 1<<3 得到的成果是 8 (00001000b) 道理是这样,可是运用起来一点也不担任,能够说是很好用。能够直接和IO的姓名对应起来,例如前面说的 P62 的话,那么界说就应该为: buz_port EQU 0x06 buz_pin EQU 2 只需求修正一下界说,程序傍边一切运用了这个IO口的部分都不需求修正,这样移植性就十分好了。这个技巧尽管简略,可是是有必要学会的。 (2)动态绑定IO口 考虑一种状况,咱们运用 3个IO口别离发不同占空比的PWM,驱动3个不同色彩的LED发光,构成彩灯作用。要求便是3个IO口独立操控,那么很天然的主意便是,3段程序,每一段程序都生成PWM,也便是说将1路的状况扩展到3路,别离操控。可是寄存器的耗费和ROM的耗费也相对应的变成了3倍,这是很好了解的。可是3段程序惊人的相似,很或许仅仅IO口输出部分修正了一下,咱们考虑,时分能够合在一起写呢?也便是说,用1个PWM程序生成PWM,别离输出到3个不同的IO口,我主张,在看下去之前先自己考虑一下,敲一下程序,就能很深入的了解到这个问题的难点。 相似的状况也不少见,例如RC测温,假设测1路的话很好办,可是假设测许多路呢?你不会真的需求将每一路都一份对应的程序吧?那肯定不或许,处理的方法相似,也便是说,用一个程序处理多个IO的输入数据,切换。这有点相似数字电路里边的数据选择器。 答案是:动态绑定IO口输入输出,途径是R0和R4合作的直接寻址。怎样完成?其实很简略,由于直接寻址自身能拜访地址 0x05 和 0x06 ,也便是能直接拜访 PORT5 和 PORT6 ,这样就很简单联想到,例如 PORT6 口输出状况,然后 PORT6 的输出状况修正为 0X0F (P60~P63高电平,P64~P67低电平)一般的做法是: mov a,@0x0f mov PORT6,a 假设经过直接寻址的方法,那么便是 mov a,@0x06 mov R4,a mov a,@0x0f mov R0,a 首要即将拜访的寄存器地址 0x06放到地址寄存器 R4,然后将数据 0x0f 送到 R0中,那么实践的作用便是将 0xf 送到 PORT6 傍边,用仿真器跑一下就OK了,很简略的。 懂了这个原理之后,那么所谓的“动态绑定”就很简单了解了,将原来用 PORT5 PORT6拜访IO口的指令,变成用 R0 R4 直接寻址来拜访,这样程序就能够变得很灵敏。 例如有用回之前的那个蜂鸣器的比如 体系有两个蜂鸣器,P50和P62,那么下面看看怎样经过动态绑定将方波别离输出到这两个蜂鸣器傍边。 分配两个寄存器,别离保存当时需求操作的端口信息。 REG_PORT == 0x10 REG_PIN == 0x11 假设当时需求对 P50输出 Mov a,@0x05 Mov REG_PORT,a Mov a,@1<<0 Mov REG_PIN,a 那么蜂鸣器的驱动函数就应该做相应的修正,前面说了,原来是直接对PORT口操作,现在变成直接寻址 Mov a,REG_PORT Mov R4,a Mov a,REG_PIN Xor R0,a 能够了解么?其实很简略,首要确认当时需求操作的端口,前面设定了REG_PORT的值为0x05,也便是说操作 PORT5,然后将需求操作的脚 1<<0 也便是 0x01 和 R0(现在指向PORT5)异或,得出来的作用便是 P50 改动电平,屡次调用就变成输出方波了。 假设现在需求对 P62输出,那么工作就变得很简略,只需求: Mov a,@0x06 Mov REG_PORT,a Mov a,@1<<2 Mov REG_PIN,a 那么中心的方波生成部分就通用了,咱们需求操作哪个端口,直接送值就OK。 看到没有?这儿便是所谓的动态绑定。假设考虑移植性,也便是说今后或许会修正端口的话,那调集第一点傍边所说的,界说一个宏就OK了,横竖这东西需求自己灵敏的运用。 结束语: 很简略的两个东西,我用了大篇幅来描绘便是为了阐明问题罢了,假设了解的话真的很简略,乃至是不足齿数。可是,怎样说呢,程序便是这类小技巧一点一点的堆集起来的。期望今日说的2个小技巧能对你有利。