Keil C51 pointer summary

Publisher:快乐家庭Latest update time:2016-12-16 Source: eefocusKeywords:keil Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

  A variable is a quantity whose value can change continuously during the execution of a program. To use a variable in a program, you must first use an identifier as the variable name and indicate the data type and storage mode used, so that the compiler system can allocate the corresponding storage space for the variable. The format for defining a variable is as follows:
  [Storage type] Data type [Memory type] Variable name table
  In the definition format, except for the data type and variable name table, which are necessary, the others are optional. There are four types of storage: auto, external, static, and register, and the default type is auto. The specific meaning and usage of these storage types will be further studied in Lesson 7 "Variable Storage".
  The data type here is the same as the definition of the data type we learned in Lesson 4. After describing the data type of a variable, you can also choose to describe the memory type of the variable. The description of the memory type is to specify the storage area used by the variable in the microcontroller C language hardware system and accurately locate it during compilation. Table 6-1 shows the memory types that KEIL uVision2 can recognize. Note that in the AT89c51 chip, only the lower 128 bits of RAM are available, while the upper 128 bits from 80H to FFH are only useful in the 52 chip and overlap with the special register address.

Memory Type

illustrate

data

Direct access to internal data memory (128 bytes), fastest access speed

bdata

Bit-addressable internal data memory (16 bytes), allowing mixed bit and byte access

the data

Indirect access to internal data memory (256 bytes), allowing access to all internal addresses

pdata

Paging access to external data memory (256 bytes), accessed using MOVX @Ri instruction

xdata

External data memory (64KB), accessed using MOVX @DPTR instruction

code

Program memory (64KB), accessed with MOVC @A+DPTR instruction

  如果省略存储器类型,系统则会按编译模式SMALL、COMPACT或LARGE所规定的默认存储器类型去指定变量的存储区域。无论什么存储模式都能声明变量在任何的8051存储区范围,然而把最常用的命令如循环计数器和队列索引放在内部数据区能显著的提高系统性能。还有要指出的就是变量的存储种类与存储器类型是完全无关的。

  Data storage mode
The storage mode determines the default storage area for variables, function parameters, etc. that do not have an explicitly specified storage type. There are three types in total:
Small mode: All default variable parameters are loaded into the internal RAM. The advantage is fast access speed, but the disadvantage is limited space. It is only suitable for small programs.
Compact mode: All default variables are located in a page (256Bytes) of the external RAM area. The specific page can be specified by the P2 port and described in the STARTUP.A51 file. It can also be specified by pdata. The advantage is that the space is more spacious than Small, the speed is slower than Small, and faster than large. It is an intermediate state.
Large mode: All default variables can be placed in an external RAM area of ​​up to 64KB. The advantage is that the space is large and more variables can be stored. The disadvantage is that the speed is slower.
  Tip: The storage mode is selected in the microcontroller C language compiler options.

 

  Previously, we briefly mentioned the methods of defining variables using sfr, sfr16, and sbit. Now let's take a closer look. sfr and sfr16 can directly define the special registers of the 51 microcontroller. The definition method is as follows:
sfr special function register name = special function register address constant;
sfr16 special function register name = special function register address constant;
We can define the P1 port of AT89c51 like this

sfr P1 = 0x90; //define P1 I/O port, its address is 90H

  The sfr keyword is followed by a name to be defined. You can choose any name, but it must comply with the naming rules of identifiers. It is best if the name has a certain meaning. For example, port P1 can be named P1, which will make the program much easier to read. The equal sign must be followed by a constant. Expressions with operators are not allowed, and the constant must be within the address range of the special function register (80H-FFH). For details, please refer to the relevant table in the appendix. sfr is used to define an 8-bit special function register, while sfr16 is used to define a 16-bit special function register, such as the T2 timer of 8052, which can be defined as:

sfr16 T2 = 0xCC; //Here define 8052 timer 2, address is T2L=CCH, T2H=CDH

  When using sfr16 to define a 16-bit special function register, the equal sign is followed by its low-order address, and the high-order address must be above the physical low-order address. Note that it cannot be used to define timers 0 and 1.

  sbit can define a bit-addressable object, such as accessing a bit in a special function register. In fact, this application is often used, such as accessing the second pin P1.1 in port P1. We can define it as follows:
(1) sbit bit variable name = bit address

sbit P1_1 = 0x91;

This assigns the absolute address of the bit to the bit variable. Like sfr, the bit address of sbit must be between 80H and FFH.
(2) Sbit bit variable name = special function register name ^ bit position

sfr P1 = 0x90;
sbit P1_1 = P1^1; //First define a special function register name and then specify the position of the bit variable name

  This method can be used when the addressable bit is located in a special function register
(3) sbit bit variable name = byte address ^ bit position

sbit P1_1 = 0x90^1;

  This method is actually the same as 2, except that the address of the special function register is directly represented by a constant.
  In the microcontroller C language memory type, there is a bdata memory type, which refers to a bit-addressable data memory located in the bit-addressable area of ​​the microcontroller. The data that requires bit-addressable data can be defined as bdata, such as:

unsigned char bdata ib; //define ucsigned char type variable ibint bdata ab[2]; //define array ab[2] in the bit-addressable area, these are also called addressable bit objects sbit ib7=ib^7 //use keyword sbit to define bit variable to independently access one bit of addressable bit object sbit ab12=ab[1]^12;

  The maximum value of the bit position following the operator "^" depends on the specified base address type, char0-7, int0-15, long0-31.
  

  Next, we will use the circuit from the previous lesson to practice the knowledge of this lesson. We will also do a simple marquee experiment, and the project name is RunLED2. The program is as follows:  

Copy code

sfr P1 = 0x90; //No predefined file is used here, sbit P1_0 = P1^0; //Instead, define the special register sbit P1_7 = 0x90^7; //The predefined file we used before actually has this function sbit P1_1 = 0x91; //Here, define the P1 port and P10, P11, and P17 pins respectively void main(void)
{
    unsigned int a;
    unsigned char b;    
    do{        for (a=0;a<50000;a++)
            P1_0 = 0; //Light up P1_0
        for (a=0;a<50000;a++)
            P1_7 = 0; //Light up P1_7
        
        for (b=0;b<255;b++)
        {            for (a=0;a<10000;a++)
            P1 = b; //Use the value of b to make a marquee pattern }
        
        P1 = 255; // Turn off the LED on P1
        for (b=0;b<255;b++)
        { for (a=0;a<10000;a++) //P1_1 flashes
                P1_1 = 0;            for (a=0;a<10000;a++)
                P1_1 = 1;
        }
        }while(1);
}

Copy code

 

 

Keil c51 pointer variable
microcontroller c language supports general pointer (Generic Pointer) and memory pointer (Memory_Specific Pointer).
1. 1. General pointer
The declaration and use of general pointer are the same as standard C, but it can also indicate the storage type of the pointer, for example:

long * state; // is a pointer to a long integer, and state itself is stored according to the storage mode. char * xdata ptr; // ptr is a pointer to char data, and ptr itself is placed in the external RAM area. The data pointed to by the above long, char and other pointers can be stored in any memory.

Generally, the pointer itself is stored in 3 bytes, which are the memory type, high offset, and low offset.
2. 2. Memory pointers
specify the storage type when describing the memory pointer, for example:

char data * str; //str points to the char type data in the data area int xdata * pow; //pow points to the int type integer in the external RAM.

When storing this type of pointer, only one or two bytes are needed, because only the offset is needed.
3. 3. Pointer conversion
is the conversion of pointers between the above two types:
when a memory-based pointer is passed as an actual parameter to a function that requires a general pointer, the pointer is automatically converted.
If the external function prototype is not declared, the memory-based pointer is automatically converted to a general pointer, resulting in an error, so please use "#include" to declare all function prototypes.
The pointer type can be forcibly changed.

 

Storage class of variables

1. static (static local) variables.
1. Static local variables will not release memory during the entire program running period.
2. For static local variables, the initial value is assigned at compile time, that is, it is only assigned once. If there is an initial value when the program is running, it will not be reassigned each time it is called.
3. If no value is assigned when defining a local variable, it will be automatically assigned to 0 at compile time. For automatic variables, if no value is assigned when defined, it is an uncertain value.
4. Although static variables still exist after the function call ends, other functions cannot reference them.
2. Use extern to declare external variables.
Using extern to declare external variables is to expand the scope of external variables. For example, a program can be composed of multiple source program files. If a program needs to refer to an external variable that has been defined in another file, it needs to use extern to declare it.
The correct approach is to define the external variable in one file and use extern to declare the variable as an external variable in another file.
In one file: int abc;
In another file: extern abc;
Example: Use extern to extend the scope of external variables to other files:
File 1:

Copy code

//Use extern to extend the scope of external variables to other files#include
#include
#include

unsigned int array[10];void fillarray();void init_ser()
{
    SCON=0X50;
    TMOD|=0X20;
    TH1=0XF3;
    TR1=1;
    IF=1;
}void main()
{
    unsigned int i;
    init_be();
    fillarray();    
    for(i=0;i<10;i++)
    {
        printf("array[%d]=%d\n",i,array[i]);
    }    
    for(;;){;}
}

Copy code

File 2:

Copy code

extern int array[10];void fillarray()
{
    unsigned char i;    
    for(i=0;i<10;i++)
    {
        array[i]=i;
    }
}

Copy code

 

 

  There are several ways to allocate the space of variables in the C language of single-chip microcomputers.
1. The data area has a small space, so only variables that are frequently used or require high computing speed are placed in the data area, such as the count value in the for loop. 
2. It is best to put local variables in the data area. Because the space of local variables can cover the local variable space of a function, it will be released when the function is exited and covered by the local variables of other functions, which can improve memory utilization. Of course, static local variables are excluded, and their memory usage is the same as global variables; 
3. Make sure there are no uncalled functions in your program. In Keil C, when an uncalled function is encountered, the compiler will consider it as an interrupt function. The space of local variables used in the function is not released, that is, it is treated the same as global variables. Keil C is stupid in this regard, but there is no way. 
4. The logical flag variables encountered in the program can be defined in bdata, which can greatly reduce the memory space occupied. There are 16 bytes of bit addressing area bdata in the 51 series chip, in which 8*16=128 logical variables can be defined. The definition method is: bdata bit LedState; but the bit type cannot be used in arrays and structures. 
5. Other variables that are not frequently used and do not require high computing speed are placed in the xdata area. 
6. If you want to save data space, you must use the large mode and put all variables with undefined memory locations in the xdata area. Of course, it is best to specify the memory type for all variables. 
7. When using pointers, specify the memory type that the pointer points to. 
  In the microcontroller c51 language, a general pointer that does not define a memory type occupies 3 bytes; a pointer that points to the data area only occupies 1 byte; a pointer that points to the xdata area occupies 2 bytes. If the pointer p points to the data area, it should be defined as: char data *p;. You can also specify the storage memory type of the pointer itself, such as: char data * xdata p;. This means that the pointer p points to the variable in the data area, and it itself is stored in the xdata area.


Keywords:keil Reference address:Keil C51 pointer summary

Previous article:The startup process of C program in keil c51
Next article:The use of pointers in Keil C51

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号