You are on page 1of 12

SISTEMAS DIGITALES II

EJERCICIOS TEMA 2 RESUELTOS

Departamento de Sistemas Electrnicos y de Control

2005-2006

SISTEMAS DIGITALES II EJERCICIOS RESUELTOS TEMA 2


EJERCICIO 1
Se dispone de un sistema basado en el 80C552 cuyas primeras posiciones de memoria contienen las siguientes instrucciones: Direccin 0000H-0002H 0003H-0005H 000BH-000DH 0013H-0015H Instruccin LJMP 4000H LJMP 6000H LJMP 6100H LJMP 6200H

Adems, se conoce que el contenido de algunos registros es el que se muestra en la tabla siguiente: Registro IEN0 IEN1 IP0 IP1 TCON Contenido 10000111b 00000000b 00000010b 00000000b 00000101b

Por ultimo se sabe que como parte del cdigo desarrollado para la aplicacin existen las siguientes rutinas, ubicadas por el enlazador en las direcciones que se muestran: Funcin void rutina0 (void) interrupt 0 void rutina1 (void) interrupt 1 void rutina2 (void) interrupt 2 Direccin 6000H 6100H 6200H

Responda a las siguientes preguntas: a) Qu interrupciones se utilizan en este sistema y cmo estn programadas? b) Qu funcin da servicio a cada una de las interrupciones utilizadas? c) Suponga que el microcontrolador, en un momento dado, se medio de la ejecucin de la rutina0 y se producen las dos restantes de forma simultnea. Cul sera la secuencia de cdigo seguida por el microcontrolador? (indique tan slo el encuentra en interrupciones ejecucin del nombre de la

funcin, cuando considere que se debe ejecutar el programa principal indquelo con main) d) Suponga que el microcontrolador, en un momento dado, se encuentra en medio de la ejecucin de la rutina0 y se producen las tres interrupciones de forma simultnea. Cul sera la secuencia de ejecucin del cdigo seguida por el microcontrolador? (indique tan slo el nombre de la funcin, cuando considere que se debe ejecutar el programa principal indquelo con main) e) Qu se entiende por tiempo de latencia en una interrupcin? SOLUCIN: a) Interrupcin externa 0, activa por flanco de bajada y en el nivel bajo de prioridad. Interrupcin externa 1, activa por flanco de bajada y en el nivel bajo de prioridad. Interrupcin por desbordamiento del timer 0, en el nivel alto de prioridad.

b) Externa 0: rutina0 (void) Externa 1: rutina2 (void) Timer 0: rutina1 (void) c) La secuencia en la ejecucin sera la siguiente se producen las dos interrupciones restantes a la vez

rutina0 rutina1 rutina0 (continuacin) main rutina2 main d) La secuencia en la ejecucin sera la siguiente se producen las tres interrupciones a la vez

rutina0 rutina1 rutina0 (continuacin) main rutina0 (otra vez) main rutina2 main e) El tiempo que tarda el microcontrolador desde que se produce la peticin de interrupcin hasta que se ejecuta la primera instruccin de la rutina de atencin a la misma. No es un tiempo fijo, al contrario, se trata de un tiempo variable cuyo valor depende de tres parmetros principalmente: Si se est ejecutando otra interrupcin de mayor o igual prioridad, en cuyo caso habr de esperar la nueva interrupcin a que finalice la ejecucin de la rutina en curso

Siempre tiene que ejecutarse por completo una instruccin antes de proceder con la secuencia de atencin a la interrupcin, por lo tanto el retraso depender del tiempo de ejecucin de la instruccin en curso. Si la instruccin en curso es un RETI o una escritura en los registros IE o IP ha de ejecutarse una instruccin adicional.

Por lo tanto, el tiempo de latencia es desconocido a priori y su valor depender de las circunstancias en las que se produzca la peticin.

EJERCICIO 2
Se quiere realizar un reloj de tiempo real con el 8051 programando uno de los timers para que genere interrupciones peridicamente, con una frecuencia que sea mltiplo de una centsima de segundo; tambin habr que realizar la rutina de atencin a la interrupcin de manera que actualice los datos del reloj: las centsimas, los segundos, los minutos y las horas. Se utilizar el timer 0 del 8051 para realizar un temporizador con recarga automtica, de manera que dicho timer interrumpa a la CPU con una frecuencia constante. La subrutina de atencin a estas interrupciones se encargar de actualizar las variables que tendrn en todo momento los datos sobre las centsimas, los segundos, los minutos y las horas. Indique los valores (en binario) que deben tener los siguientes registros del 8051 para cumplir con las especificaciones anteriores, explicando brevemente el significado del contenido de cada uno de ellos: TMOD= TCON= IE= Sabiendo que el 8051 tiene conectado un reloj de 11.059 Mhz, calcule el nmero de cuenta que debera cargarse en TH0 para generar una interrupcin cada centsima de segundo: TH0= Si el nmero calculado sobrepasa la capacidad de TH0 cmo se puede resolver este problema?

Realice el cdigo en lenguaje C correspondiente al programa principal y a la rutina de atencin a la interrupcin del Timer 0. Teniendo en cuenta que: La rutina de atencin a la interrupcin del timer 0 debe actualizar convenientemente las centsimas, los segundos, los minutos y las horas de nuestro reloj. Cada uno de estos datos se manejar como un contador software que habr que incrementar en uno o bien habr que ponerlo a cero si ha llegado al final de su cuenta.

El programa principal, una vez realizada la inicializacin del sistema, permanecer en un bucle infinito en el que no deber realizar ninguna tarea. SOLUCIN:

unsigned short int cuenta_tics=0; /* cuenta las interrupciones del timer 0 */ unsigned short int centesimas=0; unsigned short int segundos=0; unsigned short int minutos=59; unsigned short int horas=23; /* Rutina de atencin a la interrupcin del timer 0 Actualiza los registros del reloj con el valor adecuado */ void tic_tac (void) interrupt 1 { cuenta_tics++; //almacena el numero de interrupciones que se producen if (cuenta_tics>63) //cuenta_tics = 64 indica que ha pasado una centsima //de segundo */ { cuenta_tics=0; // puesta a cero para iniciar la medida de una nueva //centsima centesimas++; if (centesimas>99) { centesimas=0; segundos++; if (segundos>59) { segundos=0; minutos++; if (minutos>59) { minutos=0; horas++; if (horas>23) horas=0; } } } } }

main () { EA = 0; TMOD|=0x02; TMOD&=0xFD; TH0=256-144; // prohibimos interrupciones para programar los perifricos // timer 0 como temporizador sin GATE y en modo 2

TR0=1;

// 1 centsima son 9216 tic_tacs del reloj de 11,059 MHz dividido por 12 9216/64 = 144, se cuentan 64 tic_tacs para medir una centsima /* ponemos en marcha el timer 0 */

IE |= 0x02; EA = 1; while (1); }

/* habilitamos la interrupcin del timer 0 */ /* habilitamos las interrupciones */

EJERCICIO 3
NOTA: Se supone que la frecuencia del reloj del sistema es de 11MHz Configurar el Timer 0 para que genere una interrupcin de alta prioridad cada 8.9 mseg aproximadamente. Indique tambin las tareas que sera imprescindible realizar en la rutina de tratamiento de esta interrupcin para que el funcionamiento fuera el correcto. Calcular cual es el mximo periodo que se puede configurar entre interrupciones peridicas empleando este Timer Realizar la programacin del Timer para obtener una interrupcin cada 200 useg Calcular la precisin con la que se produce la interrupcin anterior (suponiendo que es la nica existente en el sistema) Obtener el rango de periodos en los que se podra generar una interrupcin empleando el modo 2 del Timer 0. Indicar cmo podra generarse una interrupcin cada segundo con la mxima resolucin posible.

SOLUCIN:

a) Se emplea el Modo 0 ya que para conseguir este periodo se necesita un contador de 13bits TMOD & = 0xF0; IEN0 | = 0x02; IP0 | = 0x02; IEN0 | = 0x80; TCON | = 0x10; While (1); //Modo 0, temporizador //Habilita INTs Timer 0 //Int de alta prioridad //Habilita INTs //Habilita T0

En la rutina no hay que hacer nada puesto que el flag se borra solo. void timer_0 (void) interrupt 1 { Procesamiento de la interrupcin }

b) Se emplea el Modo 1 ya que este permite un mayor estado de cuenta al tener 16 bits

TMOD & = 0xF1; TMOD | = 0x01; IEN0 | = 0x02 ; IP0 | = 0x02; IEN0 | = 0x80; TCON | = 0x10; While (1);

//Modo 1, temporizador //Habilita INTs Timer 0 //Int de alta prioridad //Habilita INTs //Habilita T0

En la rutina no hay que hacer nada puesto que el flag se borra solo. void timer_0 (void) interrupt 1 { Procesamiento de la interrupcin }

c) Se emplea el Modo 2 ya que este permite una recarga del contador que facilita la configuracin de un tiempo concreto. Para 200useg son necesarios 183,3 ciclos de reloj del timer por lo que se aproxima por el entero ms prximo 183 (0xB7). TMOD & = 0xF2; TMOD | = 0x02; TH0 = 0x49; IEN0 | = 0x02 ; IP0 | = 0x02; IEN0 | = 0x80; TCON | = 0x10; While (1); //Modo 2, temporizador

//Habilita INTs Timer 0 //Int de alta prioridad //Habilita INTs //Habilita T0

El tiempo real entre interrupciones sera 199.69 useg En la rutina no hay que hacer nada puesto que el flag se borra solo. void timer_0 (void) interrupt 1 { Procesamiento de la interrupcin } d) La precisin viene marcada por el reloj que le llega al contador: 1,09useg e) Para un valor de cuenta de 1 se obtiene un periodo de 1.09 useg

Para un valor de cuenta de 255 se obtiene un periodo de 279,2 useg


f) La solucin pasa por contar interrupciones. La mayor precisin se obtendr en el modo 2 que es recargable y permite afinar el periodo.

Si por ejemplo si se cuentan hasta el valor 220 por parte del contador (TH0=0x23) se necesitaran 4166.66 interrupciones. En este caso el tiempo real entre interrupciones sera de 1.00008 segundos

EJERCICIO 4
NOTA: Se supone que la frecuencia del reloj del sistema es de 11MHz. a) Programar las comunicaciones asncronas del 80c552 para enviar de forma continua el dato 0x55 por la lnea de TX a la mxima velocidad posible empleando 8 bits de datos y dos de stop. El microcontrolador no debe realizar ninguna otra tarea. a. Empleando poolling b. Empleando interrupciones b) Programar el microcontrolador para enviar y recibir simultneamente datos por el puerto serie a la velocidad de 9600 baudios con 8 bits de datos, 1 de parada y sin paridad. El dato a enviar ser siempre el 0xAA; c) Programar el microcontrolador para enviar lo ms rapidamente posible los 10 datos de un array de unsigned char llamado datos empleando velocidad de 200 baudios con 8 bits por dato, paridad par y con 1 bit de stop. Una vez finalizado el envio la UART debe quedar deshabilitada. d) Esperar a recibir 10 datos por el puerto serie y almacenarlos en el array unsigned char datos [10]. Una vez recibidos los 10 datos se inhabilitar toda Rx. Los datos llegan a 4800 baudios con 8 bits por dato, 1 bit de paridad y 1 bit de stop. (NOTA la paridad no es necesario analizarla) SOLUCIN: a) Empleando polling La mxima velocidad se obtiene con el modo 2 y activando el bit SMOD Unsigned char dato=0x55; PCON|=0x80; S0CON=0x88;

//Se activa el bit SMOD //Modo 2 con dos bits de stop y 8 //de datos

while (1) { S0BUF=dato; S0CON & =0xFD; While((S0CON&0x02)==0); }

Empleando interrupciones La mxima velocidad se obtiene con el modo 2 y activando el bit SMOD Unsigned char dato=0x55; PCON| = 0x80; S0CON = 0x88; IEN0 | = 0x10; IP0 | = 0x10; IEN0 | =0x80;

//Se activa el bit SMOD //Modo 2 con dos bits de stop y 8 //de datos //Interrupciones de la UART //Alta prioridad //Habilita ints

S0BUF=dato; While (1); Void Int_UART (void) interrupt 4 { if (S0CON&0x02) { S0BUF = dato; S0CON & = 0xFD; } }

//enva el primer dato

//Int de transmision? //enviar nuevo dato //Borrar el flag

b) Para poder enviar 8 datos + 1 bit de parada es necesario trabajar en modo 1 puesto que los modos 2 y 3 solo permiten enviar tramas de 9 bits (+ 1 bit de stop) Para ajustar la velocidad de Tx/Rx es necesario emplear el Timer 1 como generador de reloj configurado en el modo 2 para posibilitar la recarga. El valor de recarga se obtendr de la expresin BAUD=(2SMOD*fosc)/(32*12*(256-TH1)) Seleccionando SMOD = 1 y despejando queda TH1=250032. Como se emplea 250 (0xFA) no se obtienen 9600 baudios sino 9548. Unsigned char dato_enviar=0x55, dato_recibir; TCON & = 0xB0; //Parar el T1 TMOD & = 0x2F; //Gate=0, CT=0 TMOD | = 0x20; //Modo 2 TH1=0xFA; //Ajuste de la velocidad PCON| = 0x80; //Se activa el bit SMOD S0CON = 0x50; //Modo 1 con 1 bit de stop y 8 //de datos. Se activa REN IEN0 | = 0x10; //Interrupciones de la UART IP0 | = 0x10; //Alta prioridad IEN0 | =0x80; //Habilita ints TCON | = 0x40; //Arranca el T1 S0BUF=dato; //envo del primer dato While (1); Void Int_UART (void) interrupt 4 { if (S0CON&0x02){ S0BUF = dato_enviar; S0CON & = 0xFD; } if (S0CON&0x01) { dato_recibir=S0BUF; Tratamiento (dato_recibir) S0CON & = 0xFE; } }

//Int de transmision? //enviar nuevo dato //Borrar el flag //Int de recepcin? //se lee el dato //tratamiento de un dato recibido //Borrar el flag

10

c) Para enviar 8+1+1 es necesario trabajar en modo 2 o modo 3. De estos dos el que permite ajustar la velocidad de salida es el modo 3. Para calcular el valor de recarga del Timer1 es necesario emplear la expresin BAUD=(2SMOD*fosc)/(32*12*(256-TH1)). Si se selecciona SMOD=0 el resultado es TH1=113 (para SMOD=1 no sera posible) Unsigned char datos[10]; Unsigned char paridad_par; TCON & = 0xB0; TMOD & = 0x2F; TMOD | = 0x20; TH1=0x71; PCON & = 0x7F; S0CON = 0xC0; IEN0 | = 0x10; IP0 | = 0x10; IEN0 | =0x80; TCON | = 0x40; Paridad_par=CalculaParidad(dato[0]);

//Parar el T1 //Gate=0, CT=0 //Modo 2 //Ajuste de la velocidad //Desactiva el bit SMOD //Modo 3 con 1 bit de stop 1 de //paridad y 8 de datos. //Interrupciones de la UART //Alta prioridad //Habilita ints //Arranca el T1

If (Paridad_par) S0CON & = 0xF7; Else S0CON | = 0x08; S0BUF=dato[0]; While (1);

//se pone a 0 la paridad //se pone a 1 la paridad //envio del primer dato

Void Int_UART (void) interrupt 4 { static unsigned int cuenta=1; if (S0CON&0x02){ //Int de transmision? Paridad_par=CalculaParidad(dato[cuenta++]); If (Paridad_par) S0CON & = 0xF7; //se pone a 0 la paridad Else S0CON | = 0x08; //se pone a 1 la paridad If (cuenta<10) S0BUF = dato[cuenta]; //enviar nuevo dato S0CON & = 0xFD; //Borrar el flag } }

unsigned char CalculaParidad(unsigned char dato) { unsigned char paridad=0; for (i=0;i<8;i++) { paridad=paridad^((dato>>i)&0x01); }

11

return paridad; }

d) Para recibir 8+1+1 es necesario trabajar en modo 2 o modo 3. De estos dos el que permite ajustar la velocidad de salida es el modo 3. Para calcular el valor de recarga del Timer1 es necesario emplear la expresin BAUD=(2SMOD*fosc)/(32*12*(256-TH1)). Si se selecciona SMOD=0 el resultado es TH1=0xFA Unsigned char datos[10]; Unsigned char paridad_par; TCON & = 0xB0; TMOD & = 0x2F; TMOD | = 0x20; TH1=0xFA; PCON & = 0x7F; S0CON = 0xD0; IEN0 | = 0x10; IP0 | = 0x10; IEN0 | =0x80; TCON | = 0x40; While (1); Void Int_UART (void) interrupt 4 { static unsigned int cuenta=0; if (S0CON&0x01){ dato[cuenta++]= S0BUF; If (cuenta==10) S0CON&=0xEF; S0CON & = 0xFE; } }

//Parar el T1 //Gate=0, CT=0 //Modo 2 //Se ajusta la velocidad //Desactiva el bit SMOD //Modo 3 con 1 bit de stop 1 de //paridad y 8 de datos y Rx activa. //Interrupciones de la UART //Alta prioridad //Habilita INTs //Arranca el T1

//Int de recepcion? //guardar nuevo dato //Deshabilita Rx //Borrar el flag

12

You might also like