Red de conocimiento del abogados - Respuesta jurídica de la empresa - ¿Por qué es necesario incluir el archivo de encabezado en el lenguaje C51?

¿Por qué es necesario incluir el archivo de encabezado en el lenguaje C51?

Déjame responder a tu pregunta. Tengo un cierto conocimiento profundo de este aspecto hace unos días y también escribí muchas notas.

Aunque al programar en C, para diferentes. Los chips tienen archivos de encabezado diferentes, pero siguen siendo los mismos.

Siempre que aprenda a escribir su propio archivo de encabezado, podrá manejar varios tipos de microcontroladores. Incluso si está usando AT89C2052, AT89C51, STC12C, etc., puede usar un archivo de encabezado reg51.h. Pero necesitas hacer las reparaciones adecuadas.

La siguiente es mi opinión personal sobre reg51.h: (muy útil para usted). El archivo de encabezado utilizado al escribir C51 va seguido de una explicación detallada de sus funciones internas y definiciones de macros.

Si desea obtener más información sobre los siguientes aspectos, envíe un correo electrónico a amwjie72@163.com

1. Análisis en profundidad de la estructura de la memoria C51

2 Análisis del archivo reg51.header

Tres, una breve introducción a los tipos de variables y sus alcances

Cuatro, archivos de encabezado comunes C51

Cinco, una breve discusión. de interrupciones

Seis, limitaciones del compilador C51

7. Puntero Xiaodan C51

/////////////// /////////// /////////////////////////////////////// ////////////// ///////////////////////////////////// ///////////////// //////////////////////

archivo de encabezado. análisis

Cuando normalmente escribimos aplicaciones de microcontrolador, la mayoría de los archivos de encabezado utilizados son reg51.h o reg52.h. Cualquiera que sepa escribir C51 lo utilizará, pero no mucha gente conoce las definiciones internas de sus archivos de encabezado.

La siguiente es una explicación detallada de sus componentes internos para facilitar a los lectores una mayor comprensión y uso de varios tipos de microcontroladores. Porque las funciones mejoradas de los modelos mejorados de microcontroladores se controlan mediante registros de funciones especiales.

Abra el archivo de encabezado reg52.h y encontrará que está compuesto por una gran cantidad de declaraciones sfr, sbit e incluso sfr16. De hecho, todas estas declaraciones están relacionadas con los registros de funciones internas. (registros de funciones especiales) del microcontrolador La siguiente es una explicación detallada del mismo

sfr: Declarar variables

SFR declara una variable es básicamente la misma que otras variables de C. declaraciones La única diferencia es que SFR asigna un registro de función especial como dirección de almacenamiento cuando se declara. A diferencia del tipo entero, tipo de carácter, etc. declarado por las variables C, el compilador asigna automáticamente espacio de almacenamiento.

Por ejemplo, en el archivo de encabezado reg52.h, la primera declaración es sfr P0 = 0x80

Aquí se declara una variable P0 y su dirección de almacenamiento se especifica como función especial; registrar 0x80;, Después de agregar el archivo de encabezado reg52.h. Al escribir un programa de aplicación, P0 se puede usar directamente sin definición. La operación de P0 es leer y escribir el registro de función especial interno (0x80 al puerto P0 de la MCU de la aplicación).

Si cambia la primera declaración a sfr K0 = 0x80, entonces, si desea bajar todos los puertos P0 del microcontrolador, no puede escribir P0=0x00; debe guardarlo y luego; escríbalo en el programa de aplicación K0=0x00; de lo contrario, el compilador indicará "P0 es un identificador indefinido"

Uso:

sfr [variable] = [dirección] //Asignar. una función especial al registro de variable.

1 El lado derecho del signo igual solo puede ser constantes de datos enteros decimales o hexadecimales, y no se permiten expresiones con operadores

SFR compatible con el kernel 8051 clásico La dirección es de 0x80H~0xFF Philips 80C51MX series 0x180H~0x1FF

2 SFR no se puede declarar dentro de ninguna función, incluida la función principal. Sólo se puede declarar fuera de una función.

3 Después de declarar una variable con SFR, no puede usar el operador de dirección & para obtener su dirección. La compilación no pasará y el compilador solicitará una operación ilegal.

4 Una cosa que necesita atención especial es que 51 core 0x80~0xff es el rango de direcciones de registro de función especial, pero no todas las direcciones están definidas si el chip MCU que está utilizando no tiene una dirección determinada. Definición, luego, cuando use sfr para definir variables, no asigne la dirección de la variable a un registro de función especial indefinido. Aunque puede pasar al compilar y simular con KEIL, parece que no hay problema, pero cuando se descarga al chip y. corre, algo saldrá mal. Por ejemplo, si se realiza una operación de lectura en un registro de función especial indefinido, se leerá un número desconocido. (Los lectores pueden realizar la prueba por sí mismos, primero borrar la comunicación del puerto serie y luego realizar una interacción simple entre persona y computadora. Después de leer un número, enviarlo a la computadora y usar el asistente de depuración del puerto serie o el monitoreo del puerto serie para verificar. Este método se puede utilizar durante la simulación. Es muy útil). Por lo tanto, debe consultar el manual del chip que está utilizando para saber qué registros de funciones especiales se pueden utilizar.

5 Si encuentra un microcontrolador mejorado, solo necesita conocer la dirección de su registro de función especial extendido y usar SFR para determinarlo.

Se puede programar fácilmente.

sbit: Declarar una variable

sbit también declara una variable, similar al uso de SFR, pero SBIT se usa para declarar una variable de bit, porque, en la aplicación de la serie 51 Es muy necesario acceder a un solo bit del SFR, y el tipo de datos de bits le permite tener capacidades de direccionamiento de bits.

Por ejemplo, existe la siguiente declaración en reg52.h

sfr IE = 0xA8;

sbit EA = IE^7;

sbit ET2 = IE^5; //8052 solamente

sbit ES = IE^4;

sbit ET1 = IE^3;

sbit EX1 = IE ^2;

sbit ET0 = IE^1;

sbit EX0 = IE^0;

Por lo tanto, la operación de EA es operar el bit más alto de operación de IE.

Pero si desea que registros de funciones especiales como SP DPL DPH PCON TMOC TL0 TL1 TH0 TH1 SBUF tengan direccionamiento de bits, no funcionará utilizando la definición anterior como IE, aunque después de la modificación, funcionará durante. No se producirá ningún error en la compilación, pero se producirá un error cada vez que se utilice el nombre de la variable de bit que definió. La razón es que el direccionamiento de bits sólo es posible si la dirección del registro de función especial es múltiplo de 8 (que termina en 0 u 8 en hexadecimal).

Abra el archivo de encabezado reg52.h y podrá ver que las direcciones de todos los registros de funciones especiales declarados con sbit terminan en 0 u 8

Si insiste en cumplir los requisitos anteriores, puedes usar Completado por definición de macro con parámetros. No hay una explicación detallada aquí (no significa mucho).

La siguiente es una introducción detallada al uso de sbit:

Con la aplicación de 8051, es muy necesario acceder a un solo bit del registro de función especial del compilador C51. utiliza sbit Tipo de datos que proporciona operaciones de bits en registros de funciones especiales.

Las siguientes son tres formas de aplicación de sbit:

1. nombre de sbit = sfr-name^bit-position;

sfr PSW =0xD0; p>

sfr IE =0xA8;

sbit OV= PSW^2;

sbit CY=PSW^7;

sbit EA= IE^ 7;

Segundo, nombre de sbit= dirección-sft^posición-bit;

sbit OV =0xD0^2;

sbit CY =0xD0^ 7;

sbit EA =0xA8^7;

Tres, nombre de sbit= dirección-sbit;

sbit OV =0xD2;

sbit CY =0xD7;

sbit EA =0xAF;

Ahora haremos las explicaciones necesarias para las tres formas de declaraciones anteriores

La primera forma es sbit name = sfr -name^bit-position; como sbit OV= PSW^2; el registro de función especial debe haberse definido con sfr antes; de lo contrario, la compilación fallará.

la posición del bit varía de 0 a 7;

La segunda forma sbit name= sft-address^bit-position, como sbit OV =0xD0^2; primera forma La única diferencia es que la dirección de PSW se usa directamente aquí. La primera forma debe definir primero PSW. La tercera forma sbit name=sbit-address, como sbit OV =0xD2, se usa directamente como. Dirección de OV

El método de cálculo de la dirección de OV es la dirección de registro donde se encuentra OV más la posición de bit de OV

Nota:

No todos los SFR pueden Ser direccionamiento posicionado en bits. El direccionamiento de bits solo se puede realizar si la dirección del registro de función especial es múltiplo de 8 (el número hexadecimal termina en 0 u 8), y aunque el nombre de la variable declarada por sbit se puede elegir arbitrariamente, es mejor no comenzar con un guión bajo, porque comienza con un guión bajo. Todo lo que comienza con un guión bajo está reservado para el archivo de encabezado C51 como palabra reservada.

sfr16: declarar variables

Muchos microcontroladores derivados del 8051 utilizan dos registros de funciones especiales con direcciones consecutivas para almacenar un valor de 16 bits. Por ejemplo, 8052 usa 0xCC y 0xCD para guardar el byte alto y el byte bajo del temporizador/registro de conteo 2. El compilador proporciona el tipo de datos sfr16 para guardar dos bytes de datos. Crea virtualmente un registro de 16 bits.

Como sigue:

sfr16 T2 = 0xCC

El método de almacenamiento es little endian, con el byte bajo primero y el byte alto al final. Al definir, escriba solo la dirección de byte bajo. Como se indicó anteriormente, defina T2 como un registro de función especial de 16 bits. T2L= 0CCh, T2H= 0CDh

Uso:

sfr [variable] = [low_address]

1 En el lado derecho del signo igual, escriba solo dos funciones especiales La dirección baja del registro solo puede ser constantes de datos enteros decimales o hexadecimales. No se permiten expresiones con operadores

2 SFR no se puede declarar dentro de ninguna función, incluida la función principal. Sólo se puede declarar fuera de una función.

3 Después de declarar una variable con SFR, no puede usar el operador de dirección & para obtener su dirección. La compilación no pasará y el compilador solicitará una operación ilegal.

4 Cuando escribe datos en un sfr16, el código generado por el compilador KEIL CX51 escribe primero el byte alto y luego el byte bajo (puede verlo a través de la ventana de ensamblaje de retorno). En algunos casos, esta no es la secuencia de operaciones deseada. Preste atención al usarlo.

5 Cuando los datos que desea escribir en sfr16 son muy importantes, ya sea que el byte alto se escriba primero o el byte bajo se escriba primero, solo puede usar la palabra clave sfr para definirlo y solo guardar un byte para que la operación pueda garantizar una escritura correcta.

//////////////////////////////////////////// // ///////////////////////////////////////////////// ///// ////////////////////////////////////////////// ///

Archivos de encabezado comunes C51

En KEIL, para los archivos de encabezado utilizados por los microcontroladores, además de reg51 reg52, también hay algunos archivos de encabezado con funciones similares a reg51 y reg52 que se puede descargar de los sitios web oficiales de varios fabricantes de chips, además de un conocimiento profundo, también debe tener el conocimiento correspondiente de los archivos de encabezado que son comunes y bastante útiles para varios tipos de microcontroladores. Porque las funciones y definiciones de macros contenidas en su interior pueden facilitarnos enormemente la escritura de aplicaciones.

Función de 1 carácter ctype.h

1 bit externo isalpha(char);

Función: compruebe si el carácter del parámetro es una letra en inglés, si es así, return 1

2 bit externo isalnum(char)

Función: comprueba si el carácter es una letra en inglés o un carácter numérico; si es así, devuelve 1

3 bit externo iscntrl(char)

Función: Verifique si el valor del parámetro está entre 0x00~0x1f o igual a 0x7f, si es así, devuelve 1

4 bit externo isdigit(char)

Función: comprueba si el parámetro es un carácter numérico; de ser así, se devuelve 1

5 bits externos isgraph(char)

Función: comprueba si el parámetro el valor es un carácter imprimible, si es así, se devuelve 1, un carácter imprimible 0x21~0x7e

6 bits externos isprint(char)

Función: Además de ser lo mismo que isgraph , también acepta el carácter de espacio 0x20

7 bits externos ispunct (char)

Función: Sin introducción.

8 bits externos islower(char)

Función: comprueba si el valor del carácter del parámetro es una letra inglesa minúscula; si es así, devuelve 1

9 bit externo isupper (char)

Función: verifique si el valor del carácter del parámetro es una letra mayúscula en inglés; de ser así, devuelva 1

10 bit externo isspace(char)

Función: comprueba si el carácter es uno de los siguientes: espacio, tabulación, retorno de carro, avance de línea, tabulación vertical y avance de papel.

Si es verdadero, devuelve 1

11 bits externos isxdigit(char)

Función: comprueba si el carácter del parámetro es un carácter de dígito hexadecimal; si es así, devuelve 1

12 extern char toint(char)

Función: convierte caracteres ASCII 0~9 a~f (independiente de mayúsculas y minúsculas) en números hexadecimales correspondientes,

Valor de retorno 00H ~0FH

13 extern char tolower(char)

Función: Convertir caracteres en mayúsculas a minúsculas Si la variable de caracteres no está entre A ~ Z, no se realizará ninguna conversión y se devolverá el valor. directamente. Carácter

14 extern char toupper(char)

Función: convertir caracteres en minúsculas a mayúsculas. Si la variable de carácter no está entre a~z, el carácter se devolverá directamente sin. conversión.

15 define toascii(c) ((c)&0x7f)

Función: Esta macro reduce cualquier valor entero al rango ASCII válido y aplica un AND a la variable con 0x7f. todos los dígitos por encima del séptimo dígito

16 #define tolower(c) (c-'A'+'a')

Función: Esta macro combina caracteres con la constante 0x20 Bitwise OR

17 #define toupper(c) ((c)-'a'+'A')

Función: Esta macro ejecuta AND bit a bit con caracteres con la constante 0xdf

2 Función matemática math.h

extern int abs (int val);

extern char cabs (char val);

extern long labs (long val);

fabs flotantes externas (float val);

Función: Devuelve el valor absoluto. Las cuatro funciones anteriores tienen las mismas funciones excepto los parámetros formales y los valores de retorno.

exp flotante externo (valor flotante);

registro flotante externo (valor flotante);

log flotante externo10 (valor flotante);

Función: exp devuelve eval

log devuelve el logaritmo natural de val

log10 devuelve el logaritmo de val con base 10

extern float sqrt ( float val );

Función: Devuelve la raíz cuadrada positiva de val

extern int rand();

extern void srand(int n);

Función: rand devuelve un número pseudoaleatorio entre 0 y 32767. srand se utiliza para inicializar el generador de números aleatorios a un valor conocido (esperado).

La biblioteca math.h en Keil uVision3 no contiene esta función.

sin flotante externo (valor flotante);

cos flotante externo (valor flotante);

bronceado flotante externo (valor flotante);

Función: Devuelve los valores seno, coseno y tangente de val.

val es radianes fabs(var) <=65535

asin flotante externo (val flotante);

acos flotante externo (val flotante);

atan flotante externo (float val);

extern float atan2 (float y, float x);

Función: asin devuelve el arco seno de val. acos devuelve el arco coseno de val.

atan devuelve el arcotangente de val.

El rango de valores de asin atan acos es -π/2~+π/2

atan2 devuelve el valor del arco tangente de x/y, y su rango de valores es -π~ + π

sinh flotante externo (valor flotante);

cosh flotante externo (valor flotante);

tanh flotante externo (valor flotante);

Función: cosh devuelve el valor del coseno hiperbólico de var, sinh devuelve el valor del seno hiperbólico de var,

tanh devuelve el valor de la tangente hiperbólica de var.

ceil flotante externo (val flotante);

Función: redondea y devuelve el entero más pequeño mayor que val.

piso flotante externo (val flotante);

Función: redondea hacia abajo y devuelve el entero más grande menor que val.

pow flotante externo (flotante x, flotante y);

Función: Calcular el valor de xy. Se produce un error cuando (x=0,y<=0) o (x<0.y no es un número entero).

extern void fpsave(struct FPBUF *p)

extern void fprestore(struct FPBUF *p)

Función: fpsave guarda el estado del programa de punto flotante fprestore restaura el estado original de la subrutina de punto flotante. Estas dos funciones son útiles cuando es necesario realizar operaciones de punto flotante en el programa de interrupción.

Nota: La biblioteca math.h en Keil uVision3 no contiene esta función.

3 Acceso absoluto a dirección absacc.h

#define CBYTE ((código volátil de caracteres sin firmar *) 0)

#define DBYTE ((datos volátiles de caracteres sin firmar) *) 0)

#define PBYTE ((unsigned char volatile pdata *) 0)

#define XBYTE ((unsigned char volatile xdata *) 0)

Función: CBYTE se dirige al área de CÓDIGO

DBYTE se dirige al área de DATOS

PBYTE se dirige al área de XDATA (256 inferiores)

XBYTE se dirige al área de XDATA p>

Ejemplo: La siguiente instrucción accede al área de memoria externa en la dirección 0x1000

xvar=XBYTE[0x1000];

XBYTE[0x1000]=20;

#define CWORD ((unsigned int volatile code *) 0)

#define DWORD ((unsigned int volatile data *) 0)

#define PWORD (( unsigned int volatile pdata *) 0)

#define XWORD ((unsigned int volatile xdata *) 0)

Función: Similar a la macro anterior, excepto que el tipo de datos que especifican no está firmado int ..

Mediante el uso flexible de diferentes tipos de datos, se puede acceder a todos los espacios de direcciones 8051.

Por ejemplo

DWORD[0x0004]=0x12F8;

Es decir, (0x08)=0x12; (0x09)=0xF8 en la memoria de datos interna

4 Función interna intrins.h

extern unsigned char _cror_ (unsigned char var, unsigned char n);

extern unsigned int _iror_ (unsigned int var, unsigned char n);

extern unsigned long _lror_ (unsigned long var, unsigned char n);

Función: desplaza circularmente la variable var hacia la derecha en n bits.

La diferencia entre las tres funciones anteriores es que los tipos de parámetros y valores de retorno son diferentes

extern unsigned char _crol_ (unsigned char var, unsigned char n);

extern unsigned int _irol_ (unsigned int var, unsigned char n);

extern unsigned long _lrol_ (unsigned long var, unsigned char n);

Función: circular desplaza la variable var a la izquierda n bits.

La diferencia entre las tres funciones anteriores es que los tipos de parámetros y valores de retorno son diferentes

Por ejemplo:

#include

void main()

{

unsigned int y;

y=0x0ff0;

y =_irol_(y,4 ); //y=0xff00

y=_iror_(y,4); //y=0x0ff0

}

void _nop_(void);

Función: _nop_ genera una instrucción NOP para el microcontrolador 8051 El compilador C51 genera directamente una instrucción NOP donde el programa llama a la función _nop_.

Además, existen compras grupales de productos en el grupo de webmasters, y los precios están garantizados