新闻中心

EEPW首页 > 模拟技术 > 牛人业话 > 单片机宏定义学习手记

单片机宏定义学习手记

作者:时间:2016-09-26来源:网络收藏

  前言:

本文引用地址:http://www.eepw.com.cn/article/201609/310319.htm

  这几天在整理和生产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 了,跟上面一样。但是老实说,大家愿意用哪个办法去做呢?我会毫不犹豫的选择第二种,有意义的符号比没有意思的数据来的好用。


上一页 1 2 下一页

关键词: 单片机 宏定义

评论


相关推荐

技术专区

关闭