前语:
这几天在收拾和出产EMC单片机程序的一些宏,发现这东西真的是好用得超乎了幻想,大大的简化了写程序时的重复劳动。以下以 EM78P260为主,其实其他类型大通小
异,留意修正一下寄存器就能够。
(1)最常用的 PAGE 和 BANK
EMC 的IC是分几个page和几个bank的,低端的EM78P156等只要一个bank和一个page,所以不必切换,新一点的IC根本都要切换的了,这个经常用的冬冬,做成宏就最合适,
代码如下:
/*****************************************************
* BANK SELECTION *
*****************************************************/
BANK macro num
if num == 0
bc R4,6
bc R4,7
elseif num == 1
bs R4,6
bc R4,7
elseif num == 2
bc R4,6
bs R4,7
elseif num == 3
bs R4,6
bs R4,7
else
message "warring!"
endif
endm
/*****************************************************
* PAGE SELECTION *
*****************************************************/
PAGE macro num
if num == 0
bc psw,5
bc psw,6
elseif num == 1
bs psw,5
bc psw,6
elseif num == 2
bc psw,5
bs psw,6
elseif num == 3
bs psw,5
bs psw,6
else
message "warring!"
endif
endm
调用格局是
BANK num (num是 0~3 代表4个BANK)
PAGE num (num是 0~3 代表4个PAGE)
这样便利多了,并且不会犯错
(2)带参数的宏
作为比如,咱们假定界说一个宏“ FUNC” ,带两个参数,功用是单纯的将传进来的数据传到PORT5 和 PORT6 罢了,演示用法。
首要看界说:
FUNC MACRO ARG1,@ARG2
MOV A,@ARG1
MOV PORT5,A
MOV A,ARG2
MOV PORT6,A
ENDM
留意到,为什么 ARG1前面有个 @ 的符号的呢?这个代表的是宏接纳的第一个参数是一个当即数,而ARG2没有那个符号,代表宏接纳的第二个参数是一个寄存器的地址。
为了程序的一致性,做宏的时分,但凡当即数的,都加上@符号,一般寄存器变量都不加,构成一致的风格。
好了,看在主程序怎样用:
FUNC 0X10, @0X20
这样就OK了,编辑器编译的时分,会主动进行宏替换,将0X10这个当即数作为第一个参数传递进去,而将0X20寄存器的内容,作为第二个参数传递进去,进行宏替换之后的结
果,等效于:
MOV A,@0x10
MOV PORT5,A
MOV A,0x20
MOV PORT6,A
根本用法便是这样。不难,试一下就会用。
(3)说一点C言语的一种杰出风格
C言语上面有一种比较好的编程风格,给个C51的比如:
咱们想设置TIMER0在形式1,TIMER1在形式2
一般教程的思维和代码便是:
翻材料看看TMOD的位的界说,然后渐渐算,形式1和形式2该给什么值,最终写指令:TMOD = 0x21; 竣工…..
其实咱们还能够有别的一种方法,那便是这样写:
TMOD = CT0_MODE1 | CT1_MODE2 ;
其间里边用到一些宏,详细界说是:
#define CT0_MODE0 0x00 // Timer0/Counter0 Mode
#define CT0_MODE1 0x01
#define CT0_MODE2 0x02
#define CT0_MODE3 0x03
#define CT1_MODE0 0x00 // Timer1/Counter1 Mode
#define CT1_MODE1 0x10
#define CT1_MODE2 0x20
#define CT1_MODE3 0x30
TMOD = CT0_MODE1 | CT1_MODE2 ;
这个应该很简单看的懂吧?中心的 “|”是或运算,这个便是编译器在编译的时分做的运算了,详细CT0_MODE1 代表 0X01 CT1_MODE2 代表0x20,然后“或运算”之后成果便是
0X21 了,跟上面相同。可是老实说,我们乐意用哪个方法去做呢?我会坚决果断的挑选第二种,有意义的符号比没有意思的数据来的好用。