指针与指量
指针是动态数据结构的根本,利用指针程序员可随意操纵数据结构,因为指针具有极大的灵活性,所有使用指针也必须小心。ZJB根据单片机的特点,为了避免生成效率低下的代码,ZJB用户仅可操作硬件指针,使用硬件指针的好处是代码小巧精悍,不利的一点是硬件指针只有少数的几个,所以使用指针前必须首先对指针进行赋值,这种要求也是用好指针的金科玉律,为了使用指针,必须了解存储结构和地址,这点在声明变量时必须保证声明顺序不变,这样,这些顺序声明的变量就形成了数据结构,你可以使用
#变量名 来取得变量的首地址,然后把地址赋值给指针,这样指针指向的地址就可增量或减量操作,我们把指针指向的地址变量称作指量,操作指针只是指向要操作的指量,指量一般在指针前加@或@@来代表指量。
单片机硬件指针:
R0 八位内存指针0,指向片内内存
R1 八位内存指针1,指向片内内存
DP 16位外存指针,指向片内或片外16位存储器
DP.x 16位程序代码指针,指向16位程序存储器,x为8位偏移量
@R0 8位内存指量0
@R1 8位内存指量1
@@R0 8位外存指量0(具体应用请参阅硬件文档手册)
@@R1 8位外存指量1(具体应用请参阅硬件文档手册)
@@DP 16位外存指量
@@DP.x 16位程序存储器指量
;利用指针进行内存清零示例:
R0=~0 ;指针赋值
.. @R0=0,??R0< ; 递减循环指量清零
其他代码
;利用指针把外存2000H处的8字节数据复制到内存缓冲器,
:: x:7 ;定义内存8字节缓冲器x
DP=2000H ;外存指针指向外存2000H处
R0=#x ;内存指针指向内存缓冲器x
8.. @R0=@@DP ;重复复制8字节数据到x
++R0,++DP ;修改指针指向下一个指量
其他代码
;利用指针进行7段数码管显示示例:
数码显示(A):
DP=七段显示代码 ;指针赋值
P1=@@DP.A ;获取指量7段代码并在P1口驱动数码管
/
七段显示代码: 0xCF, 0xA4,0xB0,0x99,0x92,0x82,0xD8,0x80,0x90
移位与通信
通信是单片机和外界联系的必要手段,随着外部芯片越来越多的使用串行器件,对单片机的编程也提出了相应的要求,为此,ZJB修改了移位语句来和这些新颖的硬件打交道,例如大量使用的IIC器件和SPI器件等。
串行通信的实质为移位操作,在发送端,把发送缓冲器中的数据逐位移出移出到通信的输出口,同时再把通信输入端的电平状态从另一端逐位移入到发生缓冲器中,当发送缓冲器中的数据全部移出后,发送缓冲器中就收到了对方传入的数据,这样就完成了一帧数据的通信或信息交换。可以看出,通信需要3个部件,1:发送端口(位变量),2:数据缓冲器,3:接收端口(位变量),由于以上原因,ZJB的移位语句被设计为一个三目语句,由于通信可能从缓冲器高位移出也可能从低位移出,所以ZJB的基本移位语句有两个,她们分别是左移语句和右移语句。
基本移位语句形式如下:
[可选左移输出的位]<<通信缓冲器变量[<<可选左移输入的位]
[可选右移输入的位]>>通信缓冲器变量[>>可选右移输出的位]
功能:把数据从一端移入变量,从变量的另一端移出数据到位变量,变量内容移位改变。
可能的变形语句:
1:如果忽略可选的输入位,那么移位结束缓冲器的数据不定。
2:如果可选输入位为0或1那么移位结束缓冲器中为全0或全1。
3:移位语句每次只能移位1次,多位传送需在定次循环中完成。
;利用串并语句进行1字节SPI通信的例子:
SPI(*A): ;声明SPI通信过程,缓冲器为A
SDI==P1.0 ;定义输入口
SDO==P1.1 ;定义输出口
SCK==P1.2 ;定义同步口
8.. ;重复8次,传递1字节数据
SDO<<A<<SDI ;从输入口接收数据从输出口传出数据
SCK=1,~SCK ;给出一个同步脉冲
/ ;返回
;利用串并语句进行BCD转换的例子:
BCD(x"1,/y"2): ;x:BIN码,y:压缩BCD码,y为可返参数
y=0 ;y清零
16.. ;2字节BIN码,共2*8=16位
C<<x ;左移
A=y0++y0,DAA,y0=A ;y+y,BCD调整
A=y1++y1,DAA,y1=A
A=y2++y2,DAA,y2=A
/
单目操作语句
编程中最重要的任务是操作一个变量,为了简单快速操作变量,ZJB设计了一系列单目语句用于操作变量本身,这些语句由一个变量和一个前缀运算符组成,可以完成诸如取反、取补、增量、减量和半字节交换等简单任务,单目语句简单明快,操作简单,下面介绍常用的单目语句。
取反语句: ~ 变量,
功能:对变量内容取反,相当于汇编的CPL指令。
取补语句: - 变量,
功能:对变量内容取反,相当于汇编的CPL指令。
增量语句: ++ 变量,
功能:对变量内容直接进行+1操作,不影响标志字,相当于汇编中的 INC指令。
减量语句: -- 变量,
功能:对变量内容直接进行-1操作,不影响标志字,相当于汇编中的 DEC指令。
半交换语句: <> 字节变量,
功能:把字节变量的高低四位进行互换,不影响标志字,相当于汇编的SWAP指令。
通用操作语句
通用语句由左值表达式和右值表达式组成,右值表达式一般是一个运算式,由一系列变量、常量和运算符组成,右值运算的结果将赋值给左值表达式中的每一个变量,如果左值表达式中的变量有一个后缀运算符,那么这个左值变量和右值运算的结果再次运算,然后再赋值给这个左值变量,左值表达式的赋值顺序从右向左逐个运算并赋值,而右值表达式的计算则按从左到右的顺序逐个计算,然后生成结果。
为了完成复杂的运算,ZJB使用了如下运算符:
= 赋值运算符 双目
+ 加法运算符 双目
- 减法运算符 双目 取补运算符 前缀单目
* 乘法运算符 双目
/ 除法运算符 双目
& 位与运算符 双目
| 位或运算符 双目
^ 异或运算符 双目
~ 位非运算符 前缀单目
;赋值运算示例:
x=y=z=20 ;赋值顺序: z=20,y=z,x=y
x=y=z=~0 ;赋值顺序: z=~0,y=z,x=y
x=y=z=-1 ;赋值顺序: z=-1,y=z,x=y
;混合运算示例:
x=y|z+10 ;运算顺序:y和 z相或再加20,最后把结果赋值给x
;混合运算示例:
x=y|=z&20H ;运算顺序: y=y|z&20H,x=y
为了简化编译器,右值表达式的优先级为从左到右,她们按运算顺序从左到右逐个计算,这点和其他编译器不同,至于其他运算,请参阅附录:ZJB运算符一节