单片机_指针读取内容解析

发布者:cocolang最新更新时间:2020-06-27 来源: eefocus关键字:单片机  指针  读取内容 手机看文章 扫描二维码
随时随地手机看文章

STC单片机自带内部参考电压,单片机生产时内部已经做校准,可分别在ram和rom中读取,


(1)rom中读取


在rom中读取的时候,需要在下载时候勾选下载软件中的 在程序区的结束处添加重要测试参数,如下图所示:

勾选下载后,BandGap电压以mV为单位可以读取。


BGV = (int code *)0xeff7;  ROM容量大小不同,地址不同如// STC8A8K60S4A10 是0xeff7


code 是指程序存储(rom)地址


 


(2)ram中读取


而在ram中不需要勾选(在程序区的结束处添加重要测试参数),放在在idata区域,读取时候用如下程序①(官方例程):


#include "reg51.h"

int *BGV;

unsigned char  hi;

unsigned char  Low;

void main()

{

BGV = (int idata *)0xef;

Low =(*BGV);

hi = (*BGV) >> 8;

}

 


疑问1:指针类型为何设置为int?是否可以设置为unsigned int?


????


疑问2:0xef是一个地址,为何可以读取高地址和低地址的数据?


在debug session 中观察汇编代码


     6: void main() 

     7: { 

     8:         BGV = (int idata *)0xef; 

     9:          

C:0x002E    7B00     MOV      R3,#0x00

C:0x0030    7A00     MOV      R2,#0x00

C:0x0032    79EF     MOV      R1,#0xEF

C:0x0034    8B0A     MOV      BGV(0x0A),R3

C:0x0036    8A0B     MOV      0x0B,R2

C:0x0038    890C     MOV      0x0C,R1

    10:         Low =(*BGV); 

C:0x003A    120003   LCALL    C?ILDPTR(C:0003)

C:0x003D    AEF0     MOV      R6,B(0xF0)

C:0x003F    F508     MOV      Low(0x08),A

    11:         hi = (*BGV) >> 8; 

    12:          

    13:          

C:0x0041    EE       MOV      A,R6

C:0x0042    FF       MOV      R7,A

C:0x0043    8F09     MOV      hi(0x09),R7

如上调用了函数ILDPTR,ILDPTR汇编的代码如下


                 C?ILDPTR:

C:0x0003    BB010A   CJNE     R3,#0x01,C:0010

C:0x0006    8982     MOV      DPL(0x82),R1

C:0x0008    8A83     MOV      DPH(0x83),R2

C:0x000A    E0       MOVX     A,@DPTR

C:0x000B    F5F0     MOV      B(0xF0),A

C:0x000D    A3       INC      DPTR

C:0x000E    E0       MOVX     A,@DPTR

C:0x000F    22       RET      

C:0x0010    5006     JNC      C:0018

C:0x0012    87F0     MOV      B(0xF0),@R1

C:0x0014    09       INC      R1

C:0x0015    E7       MOV      A,@R1

C:0x0016    19       DEC      R1

C:0x0017    22       RET      

C:0x0018    BBFE07   CJNE     R3,#0xFE,C:0022

C:0x001B    E3       MOVX     A,@R1

C:0x001C    F5F0     MOV      B(0xF0),A

C:0x001E    09       INC      R1

C:0x001F    E3       MOVX     A,@R1

C:0x0020    19       DEC      R1

C:0x0021    22       RET      

C:0x0022    8982     MOV      DPL(0x82),R1

C:0x0024    8A83     MOV      DPH(0x83),R2

C:0x0026    E4       CLR      A

C:0x0027    93       MOVC     A,@A+DPTR

C:0x0028    F5F0     MOV      B(0xF0),A

C:0x002A    7401     MOV      A,#0x01

C:0x002C    93       MOVC     A,@A+DPTR

C:0x002D    22       RET      

此程序功能是:

(1)R3的值等于0x01时,执行如下程序:


C:0x0006    8982     MOV      DPL(0x82),R1

C:0x0008    8A83     MOV      DPH(0x83),R2

C:0x000A    E0       MOVX     A,@DPTR

C:0x000B    F5F0     MOV      B(0xF0),A

C:0x000D    A3       INC      DPTR

C:0x000E    E0       MOVX     A,@DPTR

C:0x000F    22       RET      

程序功能:读取扩展RAM内的数据并赋值给A,寻址范围0~65535。当数组用xdata定义时如


BGV = (int idata *)0xef;

会跳转到此处。

(2)R3的值小于0x01即等于0x00时,执行如下程序:


C:0x0010    5006     JNC      C:0018

C:0x0012    87F0     MOV      B(0xF0),@R1

C:0x0014    09       INC      R1

C:0x0015    E7       MOV      A,@R1

C:0x0016    19       DEC      R1

C:0x0017    22       RET    

CJNZ操作会影响CY,所以JNC (进位位为0则跳转)


 CJNE     R3,#0x01,C:0010

上述操作 CJNE     R3,#0x01,C:0010 会影响PSW中的借位位,当R3小于#0x01时,CY置1,否则置0.



程序功能:读取单片机内部256字节RAM内的数据并赋值给A,寻址范围0~255。当数组用data或idata定义时,会跳转到此处。如执行BGV = (int idata *)0xef;语句时,即跳转到自处,读取内部RAM地址内的数据。   

(3)R3的值不等于0x00或0x01时,通过JNC指令跳转到C:0x0018处,开始与0xFE做比较。R3的值等于0xFE时,执行如下程序:


C:0x0018    BBFE07   CJNE     R3,#0xFE,C:0022

C:0x001B    E3       MOVX     A,@R1

C:0x001C    F5F0     MOV      B(0xF0),A

C:0x001E    09       INC      R1

C:0x001F    E3       MOVX     A,@R1

C:0x0020    19       DEC      R1

C:0x0021    22       RET 

程序功能:读取单片机片外RAM内的数据并低位赋值给B,高位赋值给A,寻址范围0~255。当数组用pdata定义时,会跳转到此处。通常8051单片机不使用pdata定义变量或数组。

(4)R3的值不等于0xFE时,即R3的值等于0xFF时,跳转到C:0x0022处执行如下程序:


C:0x0022    8982     MOV      DPL(0x82),R1

C:0x0024    8A83     MOV      DPH(0x83),R2

C:0x0026    E4       CLR      A

C:0x0027    93       MOVC     A,@A+DPTR

C:0x0028    F5F0     MOV      B(0xF0),A

C:0x002A    7401     MOV      A,#0x01

C:0x002C    93       MOVC     A,@A+DPTR

C:0x002D    22       RET      

程序功能:读取单片机内部ROM内的数据并低位赋值给B,高位赋值给A,寻址范围0~65535。当数组用code定义时,如 BGV = (int code *)0xef;

由此可见,子函数“C?ILDPTR”的作用是,根据数据所在存储空间,用不同的寻址方式读取某地址下的数据。R3用于确定寻址方式,R3的值与对应的寻址方式对应关系为:

1、R3值等于0x00时,片内RAM间接寻址;此时数据用data,idata定义。

2、R3值等于0x01时,片外RAM(扩展RAM)间接寻址;此时数据用xdata定义。

3、R3值等于0xFE时,片外RAM(扩展RAM)低246字节间接寻址;此时数据用pdata定义

4、R3值等于0xFF时,从存储存储器(ROM)进行变址寻址;此时数据用code定义


在Keil C-51编译环境下,指针变量,不管长度是单字节或是双字节,指针变量所占字节数为3字节,R3表示所在存储空间R1和R2表示地址


综上所述,Keil C-51编译环境下,指针是一个占3字节的特殊变量,编译器编译程序时,自动生成判断寻址方式的子函数,并根据根据目标数据所在的物理存储区不同,为指针首字节赋值,根据赋值的不同,进行不同方式的寻址;指针的后2字节,用于存放引用的地址。


回到程序①,使用的是BGV = (int idata *)0xef;  使用的是idata 所以会执行


C:0x0010    5006     JNC      C:0018

C:0x0012    87F0     MOV      B(0xF0),@R1

C:0x0014    09       INC      R1

C:0x0015    E7       MOV      A,@R1

C:0x0016    19       DEC      R1

C:0x0017    22       RET    

程序功能:R1存地址0xEF,MOV      B(0xF0),@R1操作后,给R1地址加一变为0xF0,所以疑问二可以读取高低俩个地址。


附录


(1)C?CLDPTR 是操作char指针会调用,与ILDPTR(int 指针)汇编原理类似,不做讨论


如定义 char *BGV1;读取内容可得如下代码


                 C?CLDPTR:

C:0x00AF    BB0106   CJNE     R3,#0x01,C:00B8

C:0x00B2    8982     MOV      DPL(0x82),R1

C:0x00B4    8A83     MOV      DPH(0x83),R2

C:0x00B6    E0       MOVX     A,@DPTR

C:0x00B7    22       RET      

C:0x00B8    5002     JNC      C:00BC

C:0x00BA    E7       MOV      A,@R1

C:0x00BB    22       RET      

C:0x00BC    BBFE02   CJNE     R3,#0xFE,C:00C1

C:0x00BF    E3       MOVX     A,@R1

C:0x00C0    22       RET      

C:0x00C1    8982     MOV      DPL(0x82),R1

C:0x00C3    8A83     MOV      DPH(0x83),R2

C:0x00C5    E4       CLR      A

C:0x00C6    93       MOVC     A,@A+DPTR

C:0x00C7    22       RET      

(2)在keil的memory中D:0x0F 表示在ram中的数据,C:0x0F表示在code中的数据


(如单片机内部ram中高128字节,直接寻址是SFRS(特殊功能寄存器),间接寻址是内部数据区,二者物理上是分开的)


  C:代码存储空间


  D:直接寻址片内存储空间


  I :间接寻址片内存储空间


  X:扩展的外部RAM空间


(3)for(;;a++,b++) for语句可以加N个++

[1] [2]
关键字:单片机  指针  读取内容 引用地址:单片机_指针读取内容解析

上一篇:51单片机 | 串口通信实验(模拟串口通信/多机通信实例)
下一篇:手把手教你单片机——串口

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多每日新闻

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved