1 - Programacion en C - Tema 2 8051
1 - Programacion en C - Tema 2 8051
1 - Programacion en C - Tema 2 8051
para 8051
Informática Industrial
Universidad de Jaén
Ángel Gaspar González Rodríguez
1
Especificadores de memoria en C para 8051
code: la variable se almacena en memoria de programa
variable de sólo lectura
no tiene sentido si no está inicializada
data: se almacena en memoria de datos interna (0 a 0x7F)
bdata: se almacena en subárea direccionable bit a bit (0x20 a 0x2F)
xdata: se almacena en memoria externa de datos
También idata y pdata
La extensión _at_ (en var. globales) impone la dirección de almacenamiento
Ejemplos
char code texto[] = “Pulsa 0 para salir”;
int data suma_parcial _at_ 0x40;
int bdata word_flags;
sbit flag1 = word_flags^1;
sbit flag10 = word_flags^10;
int xdata ventas[100];
2
Ejemplos de direccionamiento
// Definiciones de valores constantes. No se almacenan en ningún sitio. Es más bien una herramienta de
edición.
#define CONSTANTE1 300
#define CONSTANTE2 0x40
#define CONSTANTE3 'C'
/* Variables que imponemos que su valor se almacene en una posición RAM determinada (RAM interna <->
data) */
// Han de ser globales (fuera de cualquier función, incluida main()
char data c_variable_de_1_byte _at_ 0x11;
int data i_variable_de_2_bytes _at_ 0x12;
/* La mayoría de variables que vienen a continuación pueden ser definidas como globales o locales. Las
binarias han de ser también globales. */
// Variables intermedias que pueden ser direccionables bit a bit, y que se emplearán a tal fin
int bdata b_word_de_flags; // El compilador le busca una posición en la zona entre 0x20 y 0x2F
3
// Variables binarias
// Si queremos que ocupen un lugar determinado, se declara con sbit. Ha de referirse a un SFR o a una
variable declarada con bdata
sbit P0_6 = P0^6; // Es el bit 6 del puerto P0
sbit flag_alarma1 = b_word_de_flags^1;
// O tal vez no sea preciso imponer que se encuentre en una posición determinada
bit flag_timer0;
bit flag_interrupcion0 = 1;
/* En memoria de programa se incluirían datos constantes que no variarán a lo largo de la ejecución del
programa.
No podemos especificar dónde queremos grabar esos datos (durante la programación de la EEPROM). */
void main(void)
{
char xdata x_array2[100];
char array_local[16];
unsigned char contador;
4
Definición de los SFR
/* FILE NAME : C8051F340.h */
Existe un fichero de
cabecera con la definición /* BYTE Registers */
de los SFR’s sfr P0 = 0x80; /* PORT 0 */
sfr SP = 0x81; /* Stack Pointer */
Incluye los SFR’s del 8051 sfr DPL= 0x82; /*Data Pointer-low byte*/
genérico y los específicos sfr DPH= 0x83; /*Data Pointer-high byte */
sfr PCON = 0x87; /* Power Control */
del µC empleado …
/* Specific registers */
El archivo de cabecera sfr DAC0CN = 0xD4; /* DAC 0 Control */
para un 8051 genérico es …
reg51.h /* BIT Registers */
/* TCON 0x88 */
El de las prácticas es sbit TF1 = TCON^7; /*Timer1 overflow flag */
C8051F340.h sbit TR1 = TCON ^ 6; /* Timer1 On/Off */
…
5
Ejercicios simples de Bucles III. Factura
Lista de productos que se van leyendo con un lector de código
de barras conectado a P1.
Cuando se pulse P0.0, debe proporcionar la suma de precios.
Factura
SumaP ß 0
n_prod ß 0
SumaP ß 0
n_prod ß0
Mientras tecla_fin no pulsada
c_prodß0
Si codigo == 0
Continuar en bucle ¿tecla_fin Sí
Fin Si pulsada?
No ¿c_prod<
codigosn_prod = codigo No
n_prod?
n_prod ++ Sí Sí
Esperar a que P1 sea 0 ¿P1 = 0?
Fin Mientras producto ß codigos[c_prod]
No
codigos[n_prod] ß P1
Para c_prod ß 0 hasta n_prod-1 hacer Sumap += precio[producto]
producto ß codigosc_prod
n_prod++
SumaP += preciosproducto
c_prod++ Fin
Fin Para cont
Esperar a que P1 sea 0
6
Factura. Codigo fuente
#include <reg51.h>
unsigned int code precios[11] = {0, 6, 33, 65, 2, 45, 77 , 22, 500, 123, 245};
// el 1er elemento corresponde al producto de código 0, que no existe
char xdata codigos[100] _at_ 0x100;
sbit tecla_fin = P0^0; // Suponemos un pulsador unido mediante R de pull-down
main()
{
char n_prod = 0; // nº total de productos que han pasado
char c_prod; // contador de productos
char producto; // código del producto
unsigned int sumaparcial = 0;
while ( ! tecla_fin) {
if (P1 == 0)
continue;
codigos[n_prod] = P1;
n_prod ++;
while (P1); // espera a que deje de reconocerse el producto
}
for (c_prod = 0; c_prod < n_prod; c_prod ++)
{
producto = codigos[c_prod];
sumaparcial += precios[producto];
}
}
7
Ejercicio bits. Codificación NRZI
NRZI (Non Return to Zero Inverted):
el uno se representa por una transición
el cero lógico por una no transición. El 1º que se envía
Momentos en que se
Inicios y finales de bit cambia el estado
NRZI
reloj
externo
SA
12
Tanque. Solución secuencial
#include "direcciones_SFR.h"
do
{
estado No estado No estado = P1 & 03;
=1 =2 if (estado != 1)
Sí estado_ant ß estado {
Sí
if (estado != 2) // no hay error
estado_anterior = estado;
estado_ant
=0 Obtener salida
salida = actuacion[estado];
No
Sí }
salida ß 0x07 salida ß 0x03
else
Una bomba Ninguna bomba switch(estado_anterior)
{
case 0: salida = 0x07; break;
case 3: salida = 0x03; break;
}
P1 = salida ;
} while (1);
}
13