PIC头文件——寄存器位地址定义代码解析

2019-04-15 11:46发布

编译工具:MPLAB X IDE v4.15 单片机型号:PIC16F1938 MPLAB开发环境中,包含各种PIC系列单片机的头文件,我在理解头文件中关于寄存器位地址定义时绕了些弯路,所以特意写出来加强记忆。 以LATA寄存器为例:在pic16f1938.h头文件中,关于LATA寄存器的定义如下 // Register: LATA volatile unsigned char LATA @ 0x10C; // bit and bitfield definitions volatile bit LATA0 @ ((unsigned)&LATA*8)+0; volatile bit LATA1 @ ((unsigned)&LATA*8)+1; volatile bit LATA2 @ ((unsigned)&LATA*8)+2; volatile bit LATA3 @ ((unsigned)&LATA*8)+3; volatile bit LATA4 @ ((unsigned)&LATA*8)+4; volatile bit LATA5 @ ((unsigned)&LATA*8)+5; volatile bit LATA6 @ ((unsigned)&LATA*8)+6; volatile bit LATA7 @ ((unsigned)&LATA*8)+7;

一、代码解析

1. “@”符号

    在很多嵌入式编译环境中,"@"符号表示“将符号左边的变量钳制在符号右边的地址” 。     C语言中本来是没有“@”符号的,但在MPLAB编译环境里,“@”相当于汇编中的“EQU”伪指令,即     C语言代码:     LATA @ 0x10C        等价于汇编指令:     LATA    EQU    0x10C     用自然语言表述,就是:char型变量LATA的值,存放在字节地址为“0x10C”的内存空间。 

 2. “LATA0   @ ((unsigned)&LATA*8)+0”语句

    ① 在C语言中,“unsigned”是“unsigned int”的简写, 在这句代码中的作用是强制类型转换,即:将“&LATA*8”的结果强制类型转换为无符号整型;     ② “&LATA*8”语句,由于取地址符“&”的优先级高于乘号“*”,所以这句代码的意思是:取LATA的地址“0x10C”,并将这个值乘以8。从二进制角度来看,就是将“00 0001 0000 1100”左移3位。(其中的二进制数,是由“0x10C”转换而来,由于PIC16F1938的地址总线宽度是14位的,所以该二进制数只能有14位。) 左移之后,结果是“00 1000 0110 0000”(0x860);     于是,“((unsigned)&LATA*8)+0”语句的运算结果就是“0x860”。     用自然语言表述该语句的执行结果:bit型变量LATA0的值,存放在位地址为“0x860”的内存空间。

 二、验证

    接下来,就该验证一下LATA0的位地址是不是“0x860”了。     既然已经知道了LATA寄存器的字节地址是0x10C,那只要计算一下它的位地址就好:         十六进制(0x10C)—> 十进制(268)         十进制(268 × 8 = 2144) —> 十六进制(0x860)     即LATA0的位地址是“0x860”,和代码的执行结果一致。   至此,位地址定义代码解析结束,重点是要了解位地址的计算方法。