13.01.2013 Views

sistemas digitales ii ejercicios tema 3 resueltos - OCW UPM

sistemas digitales ii ejercicios tema 3 resueltos - OCW UPM

sistemas digitales ii ejercicios tema 3 resueltos - OCW UPM

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

SISTEMAS<br />

DIGITALES II<br />

EJERCICIOS TEMA 3<br />

RESUELTOS<br />

Departamento de Sis<strong>tema</strong>s Electrónicos y de Control<br />

1<br />

2005-2006


EJERCICIO 1)<br />

EJERCICIOS TEMA 3<br />

DE SISTEMAS DIGITALES II (RESUELTOS)<br />

Configure el Timer 2 para medir el retardo entre dos señales externas de modo que si llega un<br />

segundo flanco por la primera de ellas sin que se haya producido uno en la segunda este primero sea<br />

ignorado<br />

NOTA: Se supone que la frecuencia del reloj del sis<strong>tema</strong> es de 11MHz.<br />

a) Al no tener rango es necesario tener en cuenta OVFs. Además para hacer más sencilla la rutina<br />

de atención se conecta la señal de entrada a dos pines de captura del microcontrolador (CT0 y<br />

CT1) que se configuran en flanco de subida. Para hacer más sencilla la rutina de atención se<br />

conecta la señal de entrada a dos pines de captura del microcontrolador (CT0 y CT1)<br />

main(){<br />

Float Cuenta=0,OVFs=0; //variables globales<br />

Unsigned int valor1=0, valor2=0;<br />

TM2CON = 0x00; //Reloj parado<br />

CTCON = 0x01; //Captura CT0 en flanco subida<br />

STE=0x00; //Sin pines<br />

RTE=0x00;<br />

IEN1 |=0x03; //Int de CT0 y de CT1<br />

IP1 |= 0x03; //Alta prioridad<br />

IEN0 |= 0x80; //Hab INTs<br />

TM2CON=0x81; //Reloj interno y OVF de 16 bits<br />

While (1);<br />

}<br />

Void Timer2_Captura0 (void) interrupt 6<br />

{Valor1= (((unsigned int)CTH0)


TM2IR&=0x7F; //Flag OVF<br />

}<br />

IEN1&=0x7F; //Deshab INT OVF 16 bits<br />

Cuenta=Valor2-Valor1+65536*OVFs;<br />

OVFs=0;<br />

TM2IR&=0xFD; //Borrar flag CT1<br />

CTCON=0x01; //Hab captura de CT0 y<br />

//deshabilitar de CT1<br />

}<br />

Void Timer2_OVF (void) interrupt 14<br />

{OVFs++;<br />

TM2IR&=0x7F; //Borrar flag OVF<br />

}<br />

EJERCICIO 2)<br />

NOTA: Se supone que la frecuencia del reloj del sis<strong>tema</strong> es de 11MHz.<br />

Programe el Timer 2 para generar a través de uno de los pines del microcontrolador un monoestable<br />

de 10 mseg de activación cuando llegue un flanco de subida de una señal externa<br />

La señal que lanza el monoestable se conecta al pin CT0 y la salida se genera a través del pin P4.0.<br />

Main()<br />

{TM2CON = 0x00; //Reloj parado<br />

CTCON = 0x01; //Captura CT0 en flanco subida<br />

STE=0x00; //Sin pines<br />

RTE=0x00;<br />

IEN1 | =0x01; //Int de CT0<br />

IP1 | = 0x01; //Alta prioridad<br />

IEN0 | = 0x80; //Hab INTs<br />

TM2CON=0x01; //Reloj interno sin prescaler<br />

While (1);<br />

}<br />

Void Timer2_Captura0 (void) interrupt 6<br />

{Unsigned int Valor=0, Final=0;<br />

P4=P4|0x01; //Poner a 1 la salida<br />

CTCON=0x00; //Deshabilita detección de flanco para<br />

//que no sea redisparable<br />

Valor= (((unsigned int)CTH0)8;<br />

RTE=0x01; //CM1 resetea el pin P4.0<br />

IEN1=0x10; //Habilita INT CM1 y deshabilita<br />

//CT0<br />

TM2IR&=0xFE; //Borrar el flag<br />

}<br />

4


Void Timer2_Comparacion1 (void) interrupt 12<br />

{RTE=0; //No se conmuta el pin<br />

IEN1=0x01; //Habilita int CT0 y desha<br />

//CM1<br />

CTCON=0x01; //Habilitar detección CT0 en flanco sub.<br />

TM2IR&=0xEF; //Borrar flag<br />

}<br />

a) Valor máximo de tiempo que se puede generar en el monoestable<br />

T=(8*12*65536)/11000000 = 571 mseg<br />

b) Valor mínimo<br />

Viene determinado por la latencia máxima y el tiempo de atención a la rutina de<br />

interrupción de CT0<br />

c) Precisión<br />

El monoestable no se “arranca” cuando llega el flanco externo sino que tiene que esperar a<br />

que esa interrupción se atienda y ponga el pin de salida a “1”. Este tiempo será la latencia<br />

mas la ejecución de la primera instrucción (P4=P4|0x01; que serían dos ciclos<br />

máquina=24CLKs). Por tanto este tiempo estaría entre 60 CLKs (5CM) y 132 CLKs (11<br />

CM). Lo que haría que el pulso fuera de 9167-5 (o 11).<br />

Para 60 CLK tiempo=9162*12/11000000=9.994mseg<br />

Para 132 CLK tiempo=9156*12/11000000=9.988 mseg<br />

EJERCICIO 3)<br />

Utilizando un 80c552 funcionando a una frecuencia de 12 Mhz., se quiere medir el ciclo de<br />

trabajo de una señal digital con las siguientes características:<br />

- Frecuencia comprendida entre 500 Hz. y 2 KHz.<br />

- Ciclo de trabajo entre el 10% y el 90%.<br />

El cálculo del ciclo de trabajo deberá realizarse cada vez que se active un pulsador<br />

incorporado al circuito: P1. No se atenderá a P1 hasta que no se haya realizado el cálculo del ciclo<br />

de trabajo solicitado anteriormente.<br />

Se pide:<br />

a) Describir los recursos a utilizar del microcontrolador, así como la función de cada uno de ellos y<br />

las conexiones hardware que tengan que realizarse, teniendo en cuenta que el microcontrolador no<br />

se va a dedicar a realizar otras funciones.<br />

La señal a medir puede tener la siguiente apariencia:<br />

5


Los recursos a utilizar serán:<br />

• Interrupción externa 0: hay que conectar el pulsador a dicha línea y programar esta<br />

interrupción por flanco de bajada.<br />

• Timer 2: Hay que programarlo en modo captura y se conectará la señal a medir a las<br />

líneas externas de captura CT0 y CT1 simultáneamente. En CT0 se puede capturar el<br />

flanco de subida y en CT1 se puede capturar el flanco de bajada. Por supuesto que hay<br />

que programar y habilitar adecuadamente las interrupciones asociadas a estas líneas.<br />

Una estimación del tiempo que tiene el timer para contar en cada uno de los límites de<br />

las señales es:<br />

b) Indicar clara y brevemente las funciones que deberá realizar el programa principal así como las<br />

diferentes rutinas de atención a las interrupciones utilizadas, si ha lugar, para el correcto<br />

funcionamiento del circuito planteado en el apartado anterior (no incluya en ningún caso el código<br />

necesario para su realización).<br />

Las funciones a realizar en el programa principal y en las rutinas serán:<br />

Programa principal:<br />

Frecuencia Periodo Th=10% Th=90%<br />

500 hz. 2000 usg. 200 usg. 1800 usg<br />

2 Khz. 500 usg. 50 usg. 450 usg<br />

� Programar timer 2 modo captura sin overflows<br />

� Programar interrupción externa 1 en flanco de bajada<br />

� Habilitar interrupción externa 0.<br />

� Arrancar el T2<br />

Rutina de atención a interrupción externa 0.<br />

� Deshabilitar interrupción externa 0.<br />

� Programar el timer 2:<br />

o Modo captura sin prescalado<br />

o Programar captura de CT0 en flanco de subida.<br />

o Habilitar interrupción timer 2 provocada por CT0.<br />

o Arrancar T2<br />

6


Rutina de atención a interrupción CT0.<br />

� Borrar flag<br />

� Saber si es el primer flanco que se captura.<br />

� SI<br />

o El siguiente será el segundo flanco capturado<br />

o Tomar el valor del contador del timer en la variable inicio.<br />

o Programar el timer 2:<br />

� Habilitar captura CT1 en flanco de bajada<br />

� Habilitar interrupción timer 2 de CT1.<br />

� NO<br />

o El siguiente será el primer flanco capturado<br />

o Tomar el valor del contador del timer en la variable fin.<br />

o Hacer cuentas con los valores de inicio, tintermedio y fin<br />

o Programar el timer 2:<br />

� Parar timer.<br />

� Deshabilitar interrupcion timer 2.<br />

� Deshabilitar captura CT1<br />

� Habilitar interrupción externa 0 asegurando que no está<br />

habilitado el flag de esta interrupción.<br />

Rutina de atención a interrupción CT1.<br />

� Tomar el valor del contador del timer en la variable tintermedio.<br />

� Borrar flag<br />

EJERCICIO 4)<br />

Se dispone de un dispositivo sensor de temperatura MAX1618, al que se conecta un transistor<br />

situado en el equipo a medir (por ejemplo un Pentium en un PC). Este dispositivo puede ser<br />

programado vía serie, para elegir uno de los dos modos de funcionamiento siguientes:<br />

- Conversión continua, donde el dispositivo toma muestras permanentemente.<br />

- Conversión bajo demanda del microcontrolador, que solicita la conversión, mediante la<br />

escritura de un comando sobre el dispositivo.<br />

También se puede acceder al MAX1618 para:<br />

- Fijar la temperatura que active su salida “/ALERT”, que indica que se ha sobrepasado<br />

dicho valor y permanece activada (a nivel bajo) hasta que la temperatura disminuya 5ºC<br />

del valor de alarma.<br />

- Realizar la lectura de la temperatura medida.<br />

El dispositivo se encuentra configurado para que las comunicaciones serie asíncronas tengan los<br />

siguientes parámetros: 9600 baudios, 1 bit de parada, sin paridad y 8 bits/dato.<br />

El microcontrolador encargado de programar y comunicarse con el sensor de temperatura es un<br />

82c552. En la figura siguiente se muestran los elementos mencionados.<br />

7


a) Complete dicha figura, utilizando las líneas del microcontrolador que considere oportuno,<br />

sabiendo que se necesita generar una interrupción cuando se active la salida “/ALERT”, y responda<br />

a las cuestiones siguientes:<br />

TX<br />

RX<br />

TxDato<br />

RxDato<br />

Con el fin de detectar tanto el flanco negativo como el positivo de la señal de alarma del MAX1618,<br />

se utilizan las dos señales externas de interrupción, una de forma directa y otra negada, y así<br />

programando estas dos líneas sensibles al flanco de bajada, podremos tener acotados los instantes<br />

para generar/parar la señal de PWM.<br />

b) Indique la programación de la UART, para conseguir el funcionamiento anterior. No genere<br />

interrupción cuando se lea un valor de temperatura.<br />

Para poder enviar 8 datos + 1 bit de parada es necesario trabajar en modo 1 puesto que los<br />

modos 2 y 3 solo permiten enviar tramas de 9 bits (+ 1 bit de stop)<br />

Para ajustar la velocidad de Tx/Rx es necesario emplear el Timer 1 como generador de<br />

reloj configurado en el modo 2 para posibilitar la recarga.<br />

El valor de recarga se obtendrá de la expresión<br />

BAUD=(2 SMOD *fosc)/(32*12*(256-TH1))<br />

Seleccionando SMOD = 1 y despejando queda TH1=250’032.<br />

Como se emplea 250 (0xFA) no se obtienen 9600 baudios sino 9548.<br />

Unsigned char DatoRecibido, DatoEnviado; /* Variables globales */<br />

TCON &= 0xB0; /* Parar el T1 */<br />

8<br />

82c552<br />

(CLK = 12Mhz)


TMOD &= 0x2F; /* Gate=0, CT=0 */<br />

TMOD |= 0x20; /* Modo 2 */<br />

TH1 = 0xFA; /* Ajuste de la velocidad */<br />

PCON |= 0x80; /* Se activa el bit SMOD */<br />

S0CON = 0x50; /* Modo 1 con 1 bit de stop y 8 */<br />

/* de datos. Se activa REN */<br />

TCON |= 0x40; /* Arranca el T1 */<br />

IEN0 & = 0xEF; /* Deshah. Int.de la UART */<br />

c) Escriba el código necesario para leer la temperatura (en modo continuo de conversión) del<br />

MAX1618.<br />

while (1)<br />

{<br />

while (!RI);<br />

DatoRecibido = S0BUF;<br />

RI = 0;<br />

}<br />

}<br />

d) Escriba el código necesario, para cambiar el modo de funcionamiento del dispositivo a<br />

conversiones bajo demanda (para ello es necesario escribir sobre él el dato 0xF0) y además leer el<br />

valor de la temperatura.<br />

while (!TI); //Espera por si se estuviera enviando un dato<br />

TI=0; //Borra flag<br />

S0BUF = 0xF0; //Envía dato<br />

while (!RI); //Espera recepción de un nuevo dato<br />

DatoRecibido = S0BUF; //Lectura dato recibido<br />

RI=0; //Borrar flag<br />

e) Incluya el código de la rutina de atención a la señal de alarma, de modo que se genere una señal<br />

PWM para controlar el motor de un ventilador. En este último caso, la duración de la señal a nivel<br />

alto será del 95% del periodo, con una frecuencia de 1KHz, hasta que se desactive la condición de<br />

alarma.<br />

Para generar la señal que active el ventilador se utilizará el módulo de PWM del<br />

microcontrolador, al cual se accede mediante los registros PWMP y PWM0.<br />

void AtencionINT0(void) interrupt 0<br />

{<br />

PWMP = 23; /* Periodo de 1Khz. Aprox. */<br />

PWM0= 1; /* ciclo de trabajo del 95 % aprox. */<br />

}<br />

void AtencionINT1(void) interrupt 2<br />

{<br />

PWM0= 255; /* Para PWM */<br />

}<br />

9


EJERCICIO 5)<br />

Se desea emplear un microcontrolador 80c552 para controlar remotamente un invernadero que se<br />

modelará como un sis<strong>tema</strong> analógico que recibe una señal analógica (Vin) que permite regular la<br />

humedad. Además el Invernadero dispone de un sensor de temperatura que genera una tensión<br />

analógica (Vout) que se encuentra entre 0 y 1 voltio.<br />

Vin Vout<br />

Invernadero<br />

Entrada para<br />

Controlar<br />

humedad<br />

10<br />

Salida para<br />

Medir la<br />

Temperatura<br />

El funcionamiento del sis<strong>tema</strong> es el siguiente: el microcontrolador recibe a través de la línea serie<br />

valores de humedad que debe enviar hacia el invernadero. Una vez que se envía un dato al<br />

invernadero, y para evitar que la temperatura se eleve en exceso, se debe tomar una muestra de la<br />

misma por si fuera necesario lanzar una alarma.<br />

a) Comunicaciones Serie<br />

El código digital que permite generar Vin se recibe vía serie a través de un conector DB9<br />

empleando la norma RS-232 sin líneas de protocolo. Realice sobre la figura el conexionado de los<br />

elementos que se emplean para recibir los datos.<br />

En la figura final<br />

b) Generación de las señales del invernadero<br />

El microcontrolador debe generar la señal de entrada al invernadero y leer la temperatura<br />

empleando un canal de su conversor analógico digital.<br />

Dado que el 80c552 no incluye un convertidor digital-analógico se dispone de uno externo que<br />

habrá que conectar al microcontrolador. Simplificando el convertidor se puede indicar que genera<br />

una tensión analógica proporcional al dato de 8 bits que recibe (D7...D0).<br />

Realice sobre la figura, y empleando etiquetas, el conexionado entre el microcontrolador, el<br />

convertidor y el invernadero.<br />

En la figura final<br />

c) Programación<br />

La secuencia de funcionamiento del sis<strong>tema</strong> es la siguiente. Cuando se recibe un dato por el puerto<br />

serie a 9600 baudios con 8 bits de datos, uno de parada y sin paridad deben realizarse las siguientes<br />

tareas:


• el dato debe ser enviado al convertidor digital-analógico.<br />

• debe ordenarse una lectura del sensor de temperatura a través del canal del ADC del<br />

microcontrolador.<br />

Una vez que se haya realizado la conversión, los 8 bits mas significativos (se desprecian los 2 de<br />

menor peso) deben guardarse en la posición de memoria 0xFFFF.<br />

c1) Codifique el programa principal necesario para configurar el sis<strong>tema</strong> y cumplir las<br />

especificaciones planteadas teniendo en cuenta que todos los periféricos deben ser atendidos por<br />

interrupción. Comente el código.<br />

Para recibir datos es necesario programar la UART tal y como se indica empleando el modo 1 y<br />

ajustando la velocidad con T1.<br />

TH1=256- (2 SMOD fosc/(32*12*9600))<br />

Para SMOD=0 TH1=253.5555 (254)<br />

Para SMOD=1 TH1=251.1111 (251)<br />

Se emplea el segundo valor por ser más próximo al valor exacto obteniendo una velocidad de 9375.<br />

TCON&=0xBF; //Parar el T1<br />

TMOD&=0x2F; //Gate=0 CT=0<br />

TMOD|=0x20; //Modo 1<br />

TH1=0xFB; //9600 baudios<br />

PCON|=0x80 //SMOD=1<br />

SCON=0x50; //Modo 1 con 1 bit de stop y habilitada la Rx<br />

IEN0|=0x10; //Interrupción de UART<br />

IP0|=0x10; //Interrupción de UART a nivel alto de prioridad<br />

ADCON=0x00; //Canal 0 de conversión y hab por SW.<br />

IEN0|=0x40; //Interrupción de ADC<br />

IP0|=0x40; //Interrupción de ADC a nivel alto de prioridad<br />

TCON|=0x40; //Arranca T1<br />

IEN0|=0x80; //Hab Ints<br />

c2) Realice el organigrama de la/s interrupción/es que haya empleado<br />

Int de la UART Int del ADC<br />

Leer SBUF<br />

Escribirlo en P1<br />

Lanzar<br />

Conversión ADC<br />

Flag de UART<br />

11<br />

Leer ADCH<br />

Guardarlo en<br />

0xFFFF<br />

Flag de ADC


12<br />

VCC<br />

1V<br />

GND<br />

12MHz<br />

GND<br />

U7<br />

80C552/FP<br />

58<br />

57<br />

56<br />

55<br />

54<br />

53<br />

52<br />

51<br />

71<br />

70<br />

69<br />

68<br />

67<br />

66<br />

65<br />

64<br />

31<br />

32<br />

60<br />

59<br />

50<br />

77<br />

9<br />

74<br />

49<br />

48<br />

75<br />

76<br />

10<br />

11<br />

12<br />

13<br />

14<br />

15<br />

16<br />

17<br />

38<br />

39<br />

40<br />

41<br />

42<br />

45<br />

46<br />

47<br />

18<br />

19<br />

20<br />

23<br />

24<br />

25<br />

26<br />

27<br />

80<br />

1<br />

2<br />

4<br />

5<br />

6<br />

7<br />

8<br />

P0.0/AD0<br />

P0.1/AD1<br />

P0.2/AD2<br />

P0.3/AD3<br />

P0.4/AD4<br />

P0.5/AD5<br />

P0.6/AD6<br />

P0.7/AD7<br />

P5.0/ADC0<br />

P5.1/ADC1<br />

P5.2/ADC2<br />

P5.3/ADC3<br />

P5.4/ADC4<br />

P5.5/ADC5<br />

P5.6/ADC6<br />

P5.7/ADC7<br />

XTAL2<br />

XTAL1<br />

AVREF+<br />

AVREF-<br />

EA<br />

EW<br />

RST<br />

STADC<br />

ALE<br />

PSEN<br />

PWM0<br />

PWM1<br />

P1.0/CT0I<br />

P1.1/CT1I<br />

P1.2/CT2I<br />

P1.3/CT3I<br />

P1.4/T2<br />

P1.5/RT2<br />

P1.6/SCL<br />

P1.7/SDA<br />

P2.0/A08<br />

P2.1/A09<br />

P2.2/A10<br />

P2.3/A11<br />

P2.4/A12<br />

P2.5/A13<br />

P2.6/A14<br />

P2.7/A15<br />

P3.0/RXD<br />

P3.1/TXD<br />

P3.2/INT0<br />

P3.3/INT1<br />

P3.4/T0<br />

P3.5/T1<br />

P3.6/WR<br />

P3.7/RD<br />

P4.0/CMSR0<br />

P4.1/CMSR1<br />

P4.2/CMSR2<br />

P4.3/CMSR3<br />

P4.4/CMSR4<br />

P4.5/CMSR5<br />

P4.6/CMT0<br />

P4.7/CMT1<br />

MAX232<br />

13<br />

8<br />

11<br />

10<br />

1<br />

3<br />

4<br />

5<br />

2<br />

6<br />

12<br />

9<br />

14<br />

7<br />

R1IN<br />

R2IN<br />

T1IN<br />

T2IN<br />

C+<br />

C1-<br />

C2+<br />

C2-<br />

V+<br />

V-<br />

R1OUT<br />

R2OUT<br />

T1OUT<br />

T2OUT<br />

CONNECTOR DB9<br />

5<br />

9<br />

4<br />

8<br />

3<br />

7<br />

2<br />

6<br />

1<br />

INVERNADERO<br />

Vin Vout<br />

Vout<br />

DAC08<br />

D0<br />

D1<br />

D2<br />

D3<br />

D4<br />

D5<br />

D5<br />

D7<br />

Rx<br />

Figura


EJERCICIO 6)<br />

Se va a desarrollar un sis<strong>tema</strong> complejo empleando un microcontrolador de la familia<br />

MSC51 de modo que uno de los elementos que es necesario gestionar por parte del<br />

micro es un convertidor tensión-frecuencia (V-F) de alta precisión.<br />

El funcionamiento del convertidor es el siguiente: cuando se le solicita una conversión<br />

(activación de la señal SOC) éste realiza la misma y una vez que la tiene disponible<br />

genera a través del terminal frec_out un tren de pulsos digital cuya frecuencia es<br />

proporcional al valor analógico (Vin) de la entrada. Para que el microcontrolador<br />

conozca el momento en el que se comienza a generar la señal frec_out el conversor<br />

activa su señal de salida EOC. A partir de ese preciso instante se genera durante<br />

exactamente 100 mseg la señal de salida frec_out. Una vez pasados los 100 mseg esta<br />

línea queda en estado indefinido hasta que se realice una nueva petición de conversión.<br />

Para aclarar un poco más el funcionamiento de este dispositivo se muestra en la<br />

siguiente figura un cronograma de su temporización.<br />

SOC<br />

EOC<br />

Frec<br />

_out<br />

Tmin=1mseg<br />

100mseg<br />

El objetivo de este problema es emplear este convertidor V/F como ADC de alta<br />

resolución ya que si se mide la frecuencia que genera y se conocen los rangos de la<br />

tensión de entrada y su relación con la frecuencia es sencillo calcular la tensión de<br />

entrada que se está aplicando.<br />

A continuación se proponen diversas alternativas para poder realizar las medidas cuya<br />

principal diferencia se encuentra en la resolución de las mismas.<br />

NOTA: Los apartados que se proponen en este problema son independientes entre<br />

si por lo que puede abordar cada uno de ellos sin haber resuelto los anteriores.<br />

13


A) Gestionar el convertidor V-F empleando un 8051 con interrupciones externas<br />

Se desea realizar la medida de la tensión de entrada del convertidor V-F empleando un<br />

80C51 del que tan solo están disponibles sus dos señales de interrupción externas y los<br />

pines de los puertos de entrada salida.<br />

NOTA: Tenga en cuenta que si le resulta necesario dispone de la función<br />

retardo(miliseg).<br />

A1) Indique cómo piensa hacer la medida y realice el conexionado oportuno en el<br />

siguiente esquema<br />

12MHz<br />

31<br />

19<br />

18<br />

9<br />

U2<br />

EA/VP<br />

X1<br />

X2<br />

RESET<br />

8051<br />

P0.0<br />

P0.1<br />

P0.2<br />

P0.3<br />

P0.4<br />

P0.5<br />

P0.6<br />

P0.7<br />

P2.0<br />

P2.1<br />

P2.2<br />

P2.3<br />

P2.4<br />

P2.5<br />

P2.6<br />

P2.7<br />

P1.7<br />

P1.6<br />

P1.5<br />

P1.4<br />

P1.3<br />

P1.2<br />

P1.1<br />

P1.0<br />

INT1<br />

INT0<br />

39<br />

38<br />

37<br />

36<br />

35<br />

34<br />

33<br />

32<br />

21<br />

22<br />

23<br />

24<br />

25<br />

26<br />

27<br />

28<br />

8<br />

7<br />

6<br />

5<br />

4<br />

3<br />

2<br />

1<br />

13<br />

12<br />

14<br />

CONVERTIDOR V-F<br />

SOC<br />

frec_out<br />

A1) Se generará el pulso de comienzo de conversión empleando un pin de entradasalida<br />

y aprovechándose de la existencia de la función de retardo que permite realizar<br />

su temporización. Una vez finalizada la temporización de esta señal se entra en un<br />

bucle esperando a que se reciba la señal de final de conversión. A partir de ese instante<br />

se entra en una función de retardo de 100mseg esperando a que se acabe el tren de<br />

pulsos.<br />

Cuando el periférico finalice la conversión se generará una interrupción a través e<br />

INT0. Dentro de esta interrupción se activará la atención de la INT1 por la que irán<br />

llegando los pulsos de la señal Frec_out. Cada pulso genera una interrupción en la que<br />

se incrementa por SW el valor de pulsos.<br />

EOC<br />

Vin


12MHz<br />

31<br />

19<br />

18<br />

9<br />

U2<br />

EA/VP<br />

X1<br />

X2<br />

RESET<br />

8051<br />

P0.0<br />

P0.1<br />

P0.2<br />

P0.3<br />

P0.4<br />

P0.5<br />

P0.6<br />

P0.7<br />

P2.0<br />

P2.1<br />

P2.2<br />

P2.3<br />

P2.4<br />

P2.5<br />

P2.6<br />

P2.7<br />

P1.7<br />

P1.6<br />

P1.5<br />

P1.4<br />

P1.3<br />

P1.2<br />

P1.1<br />

P1.0<br />

INT1<br />

INT0<br />

39<br />

38<br />

37<br />

36<br />

35<br />

34<br />

33<br />

32<br />

21<br />

22<br />

23<br />

24<br />

25<br />

26<br />

27<br />

28<br />

8<br />

7<br />

6<br />

5<br />

4<br />

3<br />

2<br />

1<br />

13<br />

12<br />

15<br />

SOC<br />

FREC<br />

EOC<br />

SOC<br />

FREC<br />

EOC<br />

CONVERTIDOR V-F<br />

SOC<br />

frec_out<br />

EOC<br />

Vin<br />

A2) Codifique el programa principal y las rutinas de atención a las interrupciones<br />

necesarias teniendo en cuenta que la frecuencia que se genera varía en un rango entre<br />

1KHz y 10 KHz cuando la tensión varía entre 0 y 10V. El programa debe realizar una<br />

única conversión guardando el valor de la tensión calculada en una variable global.<br />

Unsigned char ini_pulsos=0; //Flag de comienzo de conversión bastaría con ser bool<br />

Unsigned int pulsos=0; //Basta con un unsigned int para el rango especificado<br />

Float tension=0; //Es posible que sea decimal por lo que hay que asignar<br />

//un flotante<br />

main ()<br />

{<br />

IT0=1; //atención por flanco de INT0<br />

IT1=1; //atención por flanco de INT1<br />

EX0=1; //habilitación de la interrupción externa 0<br />

EX1=0; //deshabilitación de la interrupción externa 1<br />

PX0=1; //interrupción INT0 de alta prioridad<br />

PX1=0; //interrupción INT1 de baja prioridad<br />

EA=1; //habilitación de las interrupciones<br />

P1.0=0; //Generación del pulso de SOC. Hay que tener en cuenta<br />

Retardo(1); //que tras un reset P1=0xFF<br />

P1.0=1;<br />

While(1)<br />

{<br />

While(ini_pulsos==0); //espera a que llegue el EOC<br />

Retardo(100); //espera mientras se hace la medida<br />

EX1=0; //deshabilita las interrupciones<br />

EX0=0; //deshabilita las interrupciones<br />

Ini_pulsos=0; //fin de medida


}<br />

Tension=(float)pulsos/90+10.0/9;<br />

//cálculo de la tensión<br />

void interrupcion_externa0 () interrupt 0<br />

{<br />

EX1=1; //Habilita interrupción de cuenta de pulsos<br />

EX0=0; //Deshabilita interrupción de nueva conversión<br />

Pulsos=0; //Inicializa la variable de cuenta<br />

Ini_pulsos=1; //Indica comienzo de los 100ms<br />

}<br />

void interrupcion_externa1 () interrupt 2<br />

{<br />

pulsos++; //incremento de pulsos<br />

}<br />

A3) Indique las posibles fuentes de error que tiene sus sis<strong>tema</strong> a la hora de realizar la<br />

medida de la frecuencia.<br />

La solución propuesta posee varias fuentes de error:<br />

1. La latencia de la INT0 hace que desde que llegue el EOC hasta que se active la<br />

interrupción INT1 que realiza la cuenta pase un tiempo en el que no se cuentan<br />

los pulsos de entrada (FREC). Este error se podría estimar en<br />

Latmax+2instrucciones=11CM = 11useg. Con esto se perdería 1 pulso si la<br />

frecuencia de entrada fuera de 90KHz. Al ser menos solo se pierde 1 pulso.<br />

2. El retardo SW hace que en realidad no se midan 100mseg por lo que la ventana<br />

en la que se realiza la medida no es exacta. Esto lleva a que se puedan contar<br />

pulsos de mas. Esto es difícil de cuantificar al no darse información de la<br />

precisión en el retardo de milisegundos. Si se supone una precisión de 1CM el<br />

error vendría dado por el tiempo de ejecución de la instrucción que prohíbe las<br />

interrupciones. Dado que esto requiere 1CM, en el peor caso se perdería 1<br />

pulso.<br />

3. Al no estar sincronizada la señal de frecuencia que genera el conversor con el<br />

momento en el que se comienza a atender a la INT1 es posible que se pierda un<br />

pulso<br />

El error será por tanto de 4 pulsos lo que a 10KHz supone un error de 0.06%<br />

A4) Indique razonadamente si la aplicación funcionaría en el caso en el que la<br />

frecuencia que genera el conversor estuviera entre 1Hz y 500KHz.<br />

El sis<strong>tema</strong> no funcionaría puesto que el tiempo máximo que puede haber entre pulsos<br />

viene condicionado por el tiempo que se tarda “en contar” cada uno de ellos. Este<br />

tiempo se calcula como el tiempo de latencia máximo mas el tiempo de atención a la<br />

interrupción. Este segundo tiempo es el resultado de la suma de un dato unsigned long<br />

(aproximadamente 4CM) + la instrucción de IRET (1CM).<br />

16


Por tanto se tardaría 9+4+1 = 14CM = 14 useg lo que llevaría 71.4KHz como<br />

frecuencia máxima. Por tanto el funcionamiento de esta aplicación no sería correcto.<br />

B) Gestionar el convertidor empleando un 8051 con interrupciones y timers<br />

Con el fin de ampliar el rango de frecuencia a medir se propone utilizar un 80C51 en el<br />

que se pueden emplear todos los periféricos que posee.<br />

B1) Indique cómo piensa hacer la medida y realice el conexionado oportuno en el<br />

siguiente esquema<br />

12MHz<br />

31<br />

19<br />

18<br />

9<br />

12<br />

13<br />

14<br />

15<br />

U2<br />

EA/VP<br />

X1<br />

X2<br />

RESET<br />

INT0<br />

INT1<br />

T0<br />

T1<br />

8051<br />

P0.0<br />

P0.1<br />

P0.2<br />

P0.3<br />

P0.4<br />

P0.5<br />

P0.6<br />

P0.7<br />

P2.0<br />

P2.1<br />

P2.2<br />

P2.3<br />

P2.4<br />

P2.5<br />

P2.6<br />

P2.7<br />

P1.7<br />

P1.6<br />

P1.5<br />

P1.4<br />

P1.3<br />

P1.2<br />

P1.1<br />

P1.0<br />

39<br />

38<br />

37<br />

36<br />

35<br />

34<br />

33<br />

32<br />

21<br />

22<br />

23<br />

24<br />

25<br />

26<br />

27<br />

28<br />

8<br />

7<br />

6<br />

5<br />

4<br />

3<br />

2<br />

1<br />

17<br />

CONVERTIDOR V-F<br />

SOC<br />

frec_out<br />

Se generará el pulso de comienzo de conversión empleando un pin de entrada-salida y<br />

aprovechándose de la existencia de la función de retardo que permite realizar su<br />

temporización.<br />

Para esperar a la llegada de la señal EOC se empleará la INT0 de modo que cuando<br />

esta se reciba se habilitará la cuenta del Timer 0 que se emplea para medir los 100<br />

msegundos de la ventana y del Timer 1 que cuenta el número de pulsos.<br />

Una vez vencidos los 100mseg se realizan las cuentas.<br />

EOC<br />

Vin


12MHz<br />

EOC<br />

FREC<br />

31<br />

19<br />

18<br />

9<br />

12<br />

13<br />

14<br />

15<br />

U2<br />

EA/VP<br />

X1<br />

X2<br />

RESET<br />

INT0<br />

INT1<br />

T0<br />

T1<br />

8051<br />

P0.0<br />

P0.1<br />

P0.2<br />

P0.3<br />

P0.4<br />

P0.5<br />

P0.6<br />

P0.7<br />

P2.0<br />

P2.1<br />

P2.2<br />

P2.3<br />

P2.4<br />

P2.5<br />

P2.6<br />

P2.7<br />

P1.7<br />

P1.6<br />

P1.5<br />

P1.4<br />

P1.3<br />

P1.2<br />

P1.1<br />

P1.0<br />

39<br />

38<br />

37<br />

36<br />

35<br />

34<br />

33<br />

32<br />

21<br />

22<br />

23<br />

24<br />

25<br />

26<br />

27<br />

28<br />

8<br />

7<br />

6<br />

5<br />

4<br />

3<br />

2<br />

1<br />

18<br />

SOC<br />

SOC<br />

FREC<br />

EOC<br />

CONVERTIDOR V-F<br />

SOC<br />

frec_out<br />

B2) Codifique el programa principal y las rutinas de atención a las interrupciones<br />

necesarias teniendo en cuenta que la frecuencia que se genera varía en un rango entre<br />

1KHz y 500 KHz cuando la tensión varía entre 0 y 10V. El programa debe realizar una<br />

única conversión guardando el valor de la tensión calculada en una variable global.<br />

Unsigned int OVFs=0;<br />

Unsigned int pulsos=0;<br />

Float tension=0;<br />

EOC<br />

main ()<br />

{<br />

IT0=1; //atención por flanco de INT0<br />

EX0=1; //habilitación de la interrupción externa 0<br />

PX0=1; //interrupción INT0 de alta prioridad<br />

}<br />

TR0=TR1=0; //Timers parados<br />

TMOD=0x52; //Timer 0 como temporizador en modo 2 para recargar<br />

//Timer 1 como contador en modo 1 ya que su valor<br />

//máximo de cuenta es 50.000 (500KHz)<br />

ET0=1; //Interrupción del Timer 0<br />

TH0=5; //Valor de recarga de T0 para interrupciones periódicas<br />

//cada 250useg<br />

TH1=TL1=0; //Inicializa el contador de pulsos<br />

EA=1; //habilitación de las interrupciones<br />

P1.0=0; //Generación del pulso de SOC<br />

Retardo(1);<br />

P1.0=1<br />

While(1);<br />

Vin


void interrupcion_externa0 () interrupt 0<br />

{<br />

TR1=1; //Arranca la cuenta de pulsos<br />

TR0=1; //Arranca la cuenta de 100mseg<br />

}<br />

void interrupcion_Timer0 () interrupt 1<br />

{<br />

OVFs++;<br />

If(OVFs==400) //400 * 250useg = 100mseg<br />

{<br />

TR0=TR1=0; //Parar las cuentas de tiempo y de pulsos<br />

OVFs=0;<br />

Pulsos=((unsigned long)TH1)


B5) Calcule la resolución de la medida que realiza el convertidor expresada en V para<br />

un rango de frecuencias entre 1KHz y 500KHz. Compare la resolución de este<br />

convertidor con la del convertidor analógico digital que incorpora el 80x552.<br />

Calcule la resolución de la medida que realiza el convertidor expresada en V para un<br />

rango de frecuencias entre 1KHz y 500KHz. Compare la resolución de este convertidor<br />

con la del convertidor analógico digital que incorpora el 80x552.<br />

La resolución de la medida viene dada por el paso de cuantificación de la señal a<br />

medir. En este caso, si se usa el convertidor AD del propio microcontrolador se tiene<br />

que<br />

1LSB = Rango_de_tensión_de_entrada / 2 numero de bits = 10/1024 = 0,009765625 V<br />

En el caso del conversor V/F este rango se caracteriza por<br />

1LSB Rango de tensión de entrada / Rango_de_frecuencia = 10/499000 =<br />

2,004e-5 V<br />

C) Gestionar el convertidor empleando un 80552<br />

Indique si se le ocurre algún procedimiento para eliminar las fuentes de error que ha<br />

analizado en los apartados anteriores empleando el Timer 2 del 80c552. En caso<br />

afirmativo describa detalladamente su propuesta (no es necesario que realice ningún<br />

programa)<br />

De los errores que se producen en las dos medidas anteriores se puede intentar<br />

eliminar el del instante en el que comienza la medida y el del instante en que acaba la<br />

cuenta de los pulsos. Para ello se debe generar una ventana de exactamente 100 mseg<br />

que comience cuando se reciba la señal EOC.<br />

La generación de esa ventana se puede realizar con el Timer 2 empleando los<br />

comparadores y haciendo que estos conmuten uno de los pines del P4. Esta señal que<br />

se genera se conecta a la habilitación HW de cuenta del Timer 1 de modo que este sólo<br />

contará durante el tiempo en el que se está generando la señal por parte del<br />

convertidor V/F.<br />

Al realizar de este modo la medida se elimina completamente el error.<br />

EJERCICIO 7)<br />

Se desea desarrollar un sis<strong>tema</strong> basado en el 80C552 funcionando a 12KHz para<br />

controlar una máquina tragaperras sencilla. Para ello se dispone, además del<br />

microcontrolador, de los componentes que aparecen en el siguiente esquema. De dichos<br />

componentes hay que indicar que los etiquetados como displays se corresponden con<br />

dispositivos ópticos que representan un símbolo en función del dato de 4 bits que se<br />

encuentre en cada momento en su entrada (dispone por tanto de 16 posibles símbolos).<br />

El funcionamiento detallado del sis<strong>tema</strong> se va a ir describiendo en cada uno de los<br />

apartados posteriores, pero a grandes rasgos se podría decir que cuando se presiona el<br />

20


Pulsador1 comienza una nueva partida, con lo que los símbolos del primer display<br />

empiezan a cambiar cíclicamente a ritmo de 10 veces por segundo.<br />

Seguidamente, y cuando se presiona el Pulsador2 o pasan 2 segundos, se para el<br />

primero de los displays y arranca el segundo. Este proceso se repite para el segundo y<br />

tercer display. Finalmente se comprueba si se trata de una combinación ganadora y si es<br />

necesario se activa la alarma.<br />

Cada uno de los pulsadores tiene por tanto una misión diferente. El pulsador 1 sirve<br />

para inicial una nueva partida mientras que el Pulsador 2 tiene como misión parar el<br />

símbolo que se encuentre en ese preciso instante en el display correspondiente. Cada<br />

vez que se produce una pulsación se genera un pulso a nivel bajo de 10 mseg sin<br />

rebotes.<br />

A) CONEXIONADO<br />

A1) Se trata de realizar el conexionado de los displays al microcontrolador de modo que<br />

el acceso a cada uno de ellos se realice mediante escrituras en direcciones del mapa de<br />

datos del microcontrolador. Más concretamente se desea que el display 1 ocupe<br />

exclusivamente la posición 0xFF00, el 2 la 0xFF01 y el 3 la 0xFF02.<br />

Una vez realizado el conexionado genere las ecuaciones lógicas de todas las señales de<br />

selección que haya empleado.<br />

NOTA: Realice el conexionado por etiquetas<br />

12KHz<br />

GND<br />

58<br />

57<br />

56<br />

55<br />

54<br />

53<br />

52<br />

51<br />

38<br />

39<br />

40<br />

41<br />

42<br />

45<br />

46<br />

47<br />

80<br />

1<br />

2<br />

4<br />

5<br />

6<br />

7<br />

8<br />

60<br />

59<br />

32<br />

50<br />

77<br />

9<br />

74<br />

P0.0/AD0<br />

P0.1/AD1<br />

P0.2/AD2<br />

P0.3/AD3<br />

P0.4/AD4<br />

P0.5/AD5<br />

P0.6/AD6<br />

P0.7/AD7<br />

P2.0/A08<br />

P2.1/A09<br />

P2.2/A10<br />

P2.3/A11<br />

P2.4/A12<br />

P2.5/A13<br />

P2.6/A14<br />

P2.7/A15<br />

P4.0/CMSR0<br />

P4.1/CMSR1<br />

P4.2/CMSR2<br />

P4.3/CMSR3<br />

P4.4/CMSR4<br />

P4.5/CMSR5<br />

P4.6/CMT0<br />

P4.7/CMT1<br />

AVREF+<br />

AVREF-<br />

XTAL1<br />

EA<br />

EW<br />

RST<br />

STADC<br />

80C552/FP<br />

P1.0/CT0I<br />

P1.1/CT1I<br />

P1.2/CT2I<br />

P1.3/CT3I<br />

P1.4/T2<br />

P1.5/RT2<br />

P1.6/SCL<br />

P1.7/SDA<br />

P3.0/RXD<br />

P3.1/TXD<br />

P3.2/INT0<br />

P3.3/INT1<br />

P3.4/T0<br />

P3.5/T1<br />

P3.6/WR<br />

P3.7/RD<br />

P5.0/ADC0<br />

P5.1/ADC1<br />

P5.2/ADC2<br />

P5.3/ADC3<br />

P5.4/ADC4<br />

P5.5/ADC5<br />

P5.6/ADC6<br />

P5.7/ADC7<br />

ALE<br />

PSEN<br />

PWM0<br />

PWM1<br />

XTAL2<br />

10<br />

11<br />

12<br />

13<br />

14<br />

15<br />

16<br />

17<br />

18<br />

19<br />

20<br />

23<br />

24<br />

25<br />

26<br />

27<br />

71<br />

70<br />

69<br />

68<br />

67<br />

66<br />

65<br />

64<br />

49<br />

48<br />

75<br />

76<br />

SEÑALES DE CS GENERADAS:<br />

31<br />

3<br />

4<br />

7<br />

8<br />

13<br />

14<br />

17<br />

18<br />

11<br />

1<br />

2<br />

3<br />

1<br />

1D<br />

2D<br />

3D<br />

4D<br />

5D<br />

6D<br />

7D<br />

8D<br />

LE<br />

OE<br />

74HC373<br />

U5<br />

U12A<br />

A<br />

B<br />

E<br />

1Q<br />

2Q<br />

3Q<br />

4Q<br />

5Q<br />

6Q<br />

7Q<br />

8Q<br />

Q0<br />

Q1<br />

Q2<br />

Q3<br />

DECODIFICADOR 2x4<br />

PULSADOR1<br />

PULSADOR2<br />

ALARMA<br />

21<br />

2<br />

5<br />

6<br />

9<br />

12<br />

15<br />

16<br />

19<br />

4<br />

5<br />

6<br />

7<br />

3<br />

4<br />

7<br />

8<br />

13<br />

14<br />

17<br />

18<br />

11<br />

1<br />

3<br />

4<br />

7<br />

8<br />

13<br />

14<br />

17<br />

18<br />

11<br />

1<br />

3<br />

4<br />

7<br />

8<br />

13<br />

14<br />

17<br />

18<br />

11<br />

1<br />

1D<br />

2D<br />

3D<br />

4D<br />

5D<br />

6D<br />

7D<br />

8D<br />

LE<br />

OE<br />

74HC373<br />

U6<br />

1D<br />

2D<br />

3D<br />

4D<br />

5D<br />

6D<br />

7D<br />

8D<br />

LE<br />

OE<br />

74HC373<br />

U7<br />

1D<br />

2D<br />

3D<br />

4D<br />

5D<br />

6D<br />

7D<br />

8D<br />

LE<br />

OE<br />

74HC373<br />

U8<br />

1Q<br />

2Q<br />

3Q<br />

4Q<br />

5Q<br />

6Q<br />

7Q<br />

8Q<br />

1Q<br />

2Q<br />

3Q<br />

4Q<br />

5Q<br />

6Q<br />

7Q<br />

8Q<br />

1Q<br />

2Q<br />

3Q<br />

4Q<br />

5Q<br />

6Q<br />

7Q<br />

8Q<br />

2<br />

5<br />

6<br />

9<br />

12<br />

15<br />

16<br />

19<br />

2<br />

5<br />

6<br />

9<br />

12<br />

15<br />

16<br />

19<br />

2<br />

5<br />

6<br />

9<br />

12<br />

15<br />

16<br />

19<br />

D0<br />

D1<br />

D2<br />

D3<br />

DISPLAY1<br />

D0<br />

D1<br />

D2<br />

D3<br />

DISPLAY2<br />

D0<br />

D1<br />

D2<br />

D3<br />

DISPLAY3


AD0<br />

AD1<br />

AD2<br />

AD3<br />

AD4<br />

AD5<br />

AD6<br />

AD7<br />

58<br />

57<br />

56<br />

55<br />

54<br />

53<br />

52<br />

51<br />

P0.0/AD0<br />

P0.1/AD1<br />

P0.2/AD2<br />

P0.3/AD3<br />

P0.4/AD4<br />

P0.5/AD5<br />

P0.6/AD6<br />

P0.7/AD7<br />

P1.0/CT0I<br />

P1.1/CT1I<br />

P1.2/CT2I<br />

P1.3/CT3I<br />

P1.4/T2<br />

P1.5/RT2<br />

P1.6/SCL<br />

P1.7/SDA<br />

10<br />

11<br />

12<br />

13<br />

14<br />

15<br />

16<br />

17<br />

INT0<br />

INT1<br />

AD0 3<br />

AD1 4<br />

AD2 7<br />

AD3 8<br />

AD413<br />

AD514<br />

AD617<br />

AD718<br />

U6<br />

1D<br />

2D<br />

3D<br />

4D<br />

5D<br />

6D<br />

7D<br />

8D<br />

1Q<br />

2Q<br />

3Q<br />

4Q<br />

5Q<br />

6Q<br />

7Q<br />

8Q<br />

2 A0<br />

5 A1<br />

6 A2<br />

9 A3<br />

12 A4<br />

15 A5<br />

16 A6<br />

19 A7<br />

A8<br />

A9<br />

A10<br />

A11<br />

A12<br />

A13<br />

A14<br />

A15<br />

38<br />

39<br />

40<br />

41<br />

42<br />

45<br />

46<br />

47<br />

P2.0/A08<br />

P2.1/A09<br />

P2.2/A10<br />

P2.3/A11<br />

P2.4/A12<br />

P2.5/A13<br />

P2.6/A14<br />

P2.7/A15<br />

P3.0/RXD<br />

P3.1/TXD<br />

P3.2/INT0<br />

P3.3/INT1<br />

P3.4/T0<br />

P3.5/T1<br />

P3.6/WR<br />

P3.7/RD<br />

18<br />

19<br />

20<br />

23<br />

24<br />

25<br />

26<br />

27<br />

INT0<br />

INT1<br />

/WR<br />

ALE11<br />

GND1<br />

Vcc20<br />

LE<br />

OE<br />

VCC<br />

74HC373<br />

80<br />

1<br />

2<br />

4<br />

5<br />

6<br />

7<br />

8<br />

P4.0/CMSR0<br />

P4.1/CMSR1<br />

P4.2/CMSR2<br />

P4.3/CMSR3<br />

P4.4/CMSR4<br />

P4.5/CMSR5<br />

P4.6/CMT0<br />

P4.7/CMT1<br />

P5.0/ADC0<br />

P5.1/ADC1<br />

P5.2/ADC2<br />

P5.3/ADC3<br />

P5.4/ADC4<br />

P5.5/ADC5<br />

P5.6/ADC6<br />

P5.7/ADC7<br />

71<br />

70<br />

69<br />

68<br />

67<br />

66<br />

65<br />

64<br />

A0<br />

A1<br />

CS<br />

2<br />

3<br />

1<br />

U12A<br />

A<br />

B<br />

E<br />

Q0<br />

Q1<br />

Q2<br />

Q3<br />

12KHz<br />

60<br />

59<br />

32<br />

AVREF+<br />

AVREF-<br />

XTAL1<br />

ALE<br />

PSEN<br />

PWM0<br />

PWM1<br />

49<br />

48<br />

75<br />

76<br />

PWM<br />

PULSADOR1<br />

INT0<br />

GND 50<br />

77<br />

9<br />

74<br />

EA<br />

EW<br />

RST<br />

STADC<br />

XTAL2<br />

31<br />

PULSADOR2<br />

80C552/FP<br />

PWM<br />

DECODIFICADOR 2x4<br />

ALARMA<br />

22<br />

INT1<br />

4<br />

5<br />

6<br />

7<br />

CS0<br />

CS1<br />

CS2<br />

AD0<br />

AD1<br />

AD2<br />

AD3<br />

CS0<br />

GND<br />

AD0<br />

AD1<br />

AD2<br />

AD3<br />

CS1<br />

GND<br />

AD0<br />

AD1<br />

AD2<br />

AD3<br />

CS2<br />

GND<br />

3<br />

4<br />

7<br />

8<br />

13<br />

14<br />

17<br />

18<br />

11<br />

1<br />

3<br />

4<br />

7<br />

8<br />

13<br />

14<br />

17<br />

18<br />

11<br />

1<br />

3<br />

4<br />

7<br />

8<br />

13<br />

14<br />

17<br />

18<br />

11<br />

1<br />

1D<br />

2D<br />

3D<br />

4D<br />

5D<br />

6D<br />

7D<br />

8D<br />

LE<br />

OE<br />

74HC373<br />

U6<br />

1D<br />

2D<br />

3D<br />

4D<br />

5D<br />

6D<br />

7D<br />

8D<br />

LE<br />

OE<br />

74HC373<br />

U7<br />

1D<br />

2D<br />

3D<br />

4D<br />

5D<br />

6D<br />

7D<br />

8D<br />

LE<br />

OE<br />

74HC373<br />

U8<br />

SEÑALES DE CS GENERADAS:<br />

CS=/A15+/A14+/A13+/A12+/A11+/A10+/A9+/A8+A7+A6+A5+A4+A3+A2+/WR<br />

A2) Justifique la necesidad de los lacthes U6, U7 y U8 que aparecen en el esquema.<br />

Indique cual cree que sería el comportamiento del sis<strong>tema</strong> en el caso de que no<br />

existieran.<br />

Los displays están directamente conectados al bus de datos por lo que necesitan<br />

almacenar de algún modo el valor que deben representar en cada momento. Si no<br />

existieran estos buffers el valor que se representaría en cada display iría variando<br />

dependiendo del valor que hubiera en cada momento en el Bus de Datos.<br />

A3) Justifique la necesidad del decodificador 2x4 que aparecen en el esquema. Indique<br />

si se podría realizar un conexionado alternativo en el que no se empleara este<br />

dispositivo.<br />

El decodificador simplifica el proceso de generar los CS de los diferentes displays ya<br />

que a partir de las dos líneas más bajas de direcciones es capaz de seleccionar el<br />

display al que se desea acceder. De este modo, y dado que cada display sólo se mapea<br />

en una dirección de memoria, no es necesario crear un CS que incluya las 16 líneas de<br />

direcciones para cada display ya que basta con hacerlo una vez para el decoder. Por<br />

tanto, en el caso de que no hubiera un decoder, sería necesario generar 3 CSs con<br />

todos los bits del bus de direcciones.<br />

1Q<br />

2Q<br />

3Q<br />

4Q<br />

5Q<br />

6Q<br />

7Q<br />

8Q<br />

1Q<br />

2Q<br />

3Q<br />

4Q<br />

5Q<br />

6Q<br />

7Q<br />

8Q<br />

1Q<br />

2Q<br />

3Q<br />

4Q<br />

5Q<br />

6Q<br />

7Q<br />

8Q<br />

2<br />

5<br />

6<br />

9<br />

12<br />

15<br />

16<br />

19<br />

2<br />

5<br />

6<br />

9<br />

12<br />

15<br />

16<br />

19<br />

2<br />

5<br />

6<br />

9<br />

12<br />

15<br />

16<br />

19<br />

D0<br />

D1<br />

D2<br />

D3<br />

DISPLAY1<br />

D0<br />

D1<br />

D2<br />

D3<br />

DISPLAY2<br />

D0<br />

D1<br />

D2<br />

D3<br />

DISPLAY3


A4) Cuando se produce una combinación ganadora se debe activar una alarma. La<br />

alarma funciona con una señal de entrada digital de frecuencia constante<br />

(aproximadamente 5 Hz) y ciclo de trabajo variable en escalones de 1%. Justifique<br />

cómo piensa gestionar esta alarma y realice su conexionado al microcontrolador sobre el<br />

esquema anterior.<br />

Para generar una señal cuadrada de periodo constante y ciclo de trabajo variable se<br />

puede emplear uno de los generadores de PWM que posee el microcontrolador. Estos<br />

generadores permiten que la frecuencia se ajuste según la expresión<br />

Frec=fosc/(2*255*(1+PWMP))<br />

Despejando se obtiene que PWMP=3.7 por lo que se ajusta a 4. Con este valor se<br />

obtiene una frecuencia real de 4.7Hz<br />

A5) Indique si la solución aportada sería válida en el caso de que la frecuencia requerida<br />

por la alarma fuera de 50 Hz. En el caso de que no fuera válido indique si sería posible<br />

resolver el problema de algún otro modo sin cambiar el reloj del microcontrolador.<br />

La frecuencia máxima que se puede generar se obtendrá cuando en PWMP se cargue<br />

un 0. Con este valor queda que Frecmax=23.5Hz por lo que no es posible generar la<br />

frecuencia obtenida con el PWM<br />

La solución que se podría emplear es la de usar el Timer 2 y sus módulos de<br />

comparación para generar una señal externa. Con uno de los comparadores<br />

conmutaría la salida cuando venciera el ciclo de trabajo y con otro cuando venciera el<br />

periodo.<br />

B) TEMPORIZACION DE CADA UNO DE LOS SIMBOLOS.<br />

En este apartado se pretende controlar el funcionamiento del pulsador 1 y del primer<br />

display. Para ello se propone realizar un programa (programa principal y rutina/s de<br />

interrupción/es) que, cuando se presione el pulsador1, haga que el símbolo que se<br />

represente en el display 1 cambie de forma cíclica 10 veces por segundo.<br />

NOTA: Para desarrollar este apartado debe emplear la menor cantidad de recursos<br />

posibles y en ningún caso una rutina de retardo.<br />

B1) Realice sobre el esquema su conexionado del Pulsador 1 e indique cómo piensa<br />

gestionarlo.<br />

Se conecta a la interrupción externa 0 y se gestiona por interrupción por flanco de<br />

bajada. Cuando se produzca su pulsación se arrancará la temporización de los<br />

displays.<br />

B2) Indique los recursos que va a emplear y los cálculos que sean necesarios para<br />

justificar la viabilidad de la solución propuesta.<br />

Como ya se ha indicado se empleará la interrupción 0 para arrancar la temporización.<br />

Para ésta se va a emplear el T0 en modo 2 para que el periodo sea lo mas preciso<br />

23


posible gracias a la recarga HW. Para ello hay que ver si el rango de valores es<br />

suficiente o si por el contrario hay que realizar una cuenta de interrupciones.<br />

Dado que el periodo del T0 es 12 veces el del reloj del sis<strong>tema</strong> tenemos que el T0<br />

funciona con un periodo de 1mseg. Por tanto, y dado que necesitamos interrupciones<br />

periódicas cada 100mseg podemos emplear este modo sin necesidad de contar<br />

interrupciones.<br />

B3) Codifique el programa (programa principal y rutina/s de interrupción/es) que<br />

cumpla las anteriores especificaciones comentando el código realizado.<br />

Void main(){<br />

IT0=0; //FLACO DE BAJADA PARA INT0<br />

EX0=1; //HABILITA LA INTERRUPCION EXT0<br />

PX0=1; //INTERRUPCION EXT0 DE ALTA PRIORIDAD<br />

TR0=0; //ASEGURARSE DE PARAR EL T0<br />

TH0=255-100; //VALOR PROPORCIONAL A 100mseg<br />

TL0=255-100; //INICIO DE CUENTA<br />

TMOD&=0XF2; //Modo=2, GATE=0, C/T=0<br />

TMOD|=0X02;<br />

ET0=1; //HABILITA INTERRUPCION T0<br />

PT0=0; //INTERRUPCION T0 DE BAJA PRIORIDAD<br />

IE=1; //HABILITA INTERRUPCIONES<br />

While (1); //BUCLE INFINITO<br />

}<br />

Void ISR_EXT0(void) interrupt 0<br />

{<br />

TR0=1; //ARRANCA EL T1<br />

EX0=0; //DESHABILITA LA INTERRUPCION EXTERNA<br />

}<br />

Void ISR_T0(void) interrupt 1<br />

{<br />

static unsigned char barrido=0;<br />

xdata unsigned char *Display1=0xFF00;<br />

*Display1=barrido++;<br />

if (barrido==0x0F) barrido=0;<br />

}<br />

C) APLICACIÓN COMPLETA<br />

Se pretende en este apartado añadir a la aplicación anterior el resto de funcionalidad del<br />

sis<strong>tema</strong>. Para ello deben procesarse las pulsaciones del pulsador2 y las temporizaciones<br />

de dos segundos del siguiente modo:<br />

24


• al activar el Pulsador2 se parará el valor del display activo en ese momento y se<br />

parará al siguiente. Si el display activo es el tercero se finalizará la jugada.<br />

Además al pasar al siguiente display se reiniciará la temporización de los 2<br />

segundos.<br />

• al cumplirse los dos segundos se parará el display activo, se pasará al siguiente y<br />

se comenzará una nueva temporización.<br />

Finalmente, y tras comprobar si se ha obtenido una combinación ganadora, se deberá<br />

activar la alarma.<br />

Para facilitar el desarrollo del programa debe tener en cuenta las siguientes<br />

observaciones:<br />

• Los dos segundos deben medirse de la forma más precisa posible por lo que se<br />

recomienda emplear el Timer 2 para su gestión.<br />

• Para comprobar si se ha obtenido una combinación ganadora se dispone de una<br />

función ya desarrollada que recibe como parámetros los tres dígitos<br />

correspondientes a los tres displays y devuelve el ciclo de trabajo con el que<br />

debe generarse la señal que ataque a la alarma expresada en % (un ciclo=0<br />

indica que no debe activarse).<br />

Unsigned char Calcula_premio (unsigned char display1, unsigned char display2,<br />

unsigned char display3);<br />

• Una vez que se comienza una jugada con el pulsador1, éste no va a volver a<br />

activarse hasta que no finalice dicha jugada. Así mismo, si no se ha comenzado<br />

una partida, las pulsaciones del pulsador 2 no serán tenidas en cuenta.<br />

• La alarma queda activada hasta que se finalice una nueva jugada.<br />

C1) Realice sobre el esquema el conexionado del Pulsador 2 e indique cómo piensa<br />

gestionarlo.<br />

El pulsador 2 se conectará a la interrupción 1 para que dentro de esa interrupción,<br />

gestionada por flanco, se lleve a cabo el paso al siguiente display. Además se conectara<br />

al pin de reset del t2 para que inicialice la cuenta de los dos segundos de forma<br />

hardware empleando para detectar el final uno de los comparadores<br />

C2) Indique los recursos que va a emplear y los cálculos que sean necesarios para<br />

justificar la viabilidad de la solución propuesta. En el caso de que necesite realizar<br />

alguna modificación sobre el conexionado indíquelo de forma justificada.<br />

Para desarrollar el sis<strong>tema</strong> se emplearan los mismos recursos que en el apartado<br />

anterior añadiendo el timer2 para temporizar los dos segundos. Dado que se pide<br />

precisión lo que se hará es temporizar los dos segundos empleando un comparador y<br />

recargando valores proporcionales a los dos segundos.<br />

Queda un problema por resolver y es cómo temporizar los dos primeros segundos<br />

después de arrancar una partida. Para ello se modificará el conexionado para que<br />

cuando se pulse el pulsador1, además de generar la interrupción correspondiente, se<br />

capture el valor de t2 y se recargue con un valor equivalente a 2 segundos mas el valor<br />

capturado<br />

25


C3) Indique la prioridad entre las interrupciones que va a emplear de forma justificada.<br />

Hay que tener en cuenta que no todas las interrupciones van a estar activadas de forma<br />

continua.<br />

Inicialmente sólo está activa la int ext0 por lo que su prioridad no es importante. Una<br />

vez atendida esta interrupción se deshabilita a si misma y habilita las otras 3 (int1,<br />

comp0 y T0).<br />

De ellas las más prioritarias son la int1 y la comp0 puesto que es en ellas donde se<br />

produce la lectura del valor en el display y por tanto no se debe esperar mucho tiempo.<br />

Ambas se atienden con alta prioridad. Queda la interrupción del T0 que se conectará a<br />

baja prioridad.<br />

C4) Codifique el programa (programa principal y rutinas de interrupción) que cumpla<br />

las anteriores especificaciones comentando el código realizado.<br />

Void main(){<br />

unsigned char Display_activo=1;<br />

unsigned char Valores_Displays[3]={0,0,0};<br />

unsigned char barrido=0;<br />

static unsigned int cuenta2seg=2000;<br />

IT0=0; //FLACO DE BAJADA PARA INT0<br />

EX0=1; //HABILITA LA INTERRUPCION EXT0<br />

PX0=0; //INTERRUPCION EXT0 DE BAJA PRIORIDAD<br />

IT1=0; //FLACO DE BAJADA PARA INT1<br />

EX1=0; //DESHABILITA LA INTERRUPCION EXT1<br />

PX1=1; //INTERRUPCION EXT1 DE ALTA PRIORIDAD<br />

TR=0; //ASEGURARSE DE PARAR EL T0<br />

TH0=255-100; //VALOR PROPORCIONAL A 100mseg<br />

TL0=255-100; //INICIO DE CUENTA<br />

TMOD&=0XF2; //MODO=2, GATE=0, C/T=0<br />

TMOD|=0X02;<br />

ET0=1; //HABILITA INTERRUPCION T0<br />

PT0=0; //INTERRUPCION T0 DE BAJA PRIORIDAD<br />

ECM0=0; //INTERRUPCION DEL COMP_0 DESHABILITADA<br />

PCM0=1; //INT DEL COMPARADOR 0 DE ALTA PRIORIDAD<br />

TM2COM=0x20; //TIMER 2 PARADO, SIN PRESCALER, SIN OVF<br />

//CON RESET HW EN EL FLANCO DE SUBIDA<br />

STE=RTE=0; //SIN PINES<br />

CTCON=1; //CAPTURA POR FLANCO SUBIDA EN EL REG0<br />

T2COM|=0x01; //ARRANCA T2<br />

PWMP=4; //FRECUENCIA DEL PWM DE 4.7Hz<br />

26


}<br />

PWM0=255; //DE MOMENTO SIN SONAR<br />

IE=1; //HABILITA INTERRUPCIONES<br />

While(1);<br />

Void ISR_EXT0(void) interrupt 0 //INT EXTERNA 0<br />

{ TR0=1; //ARRANCA EL T0<br />

EX0=0; //DESHABILITA LA INTERRUPCION EXTERNA0<br />

EX1=1; //HABILITA LA INTERRUPCION EXTERNA1<br />

Cuenta2segundos=(((unsigned int)CTH0)8;<br />

ECM0=1; //INTERRUPCION DEL COMP0 HABILITADA<br />

Display_activo=1; //PRIMER DISPLAY<br />

}<br />

Void ISR_T0(void) interrupt 1 //INT TIMER 0<br />

{<br />

xdata unsigned char *Display1=0xFF00, *Display2=0xFF01,<br />

*Display3=0xFF02;<br />

switch (Display_activo)<br />

{<br />

case 1:<br />

*Display1=barrido++;<br />

break;<br />

case 2:<br />

*Display2=barrido++;<br />

break;<br />

case 3:<br />

*Display3=barrido++;<br />

break;<br />

default:<br />

Display_activo=1;<br />

break;<br />

}<br />

if (barrido==0x0F) barrido=0;<br />

}<br />

Void ISR_EXT1(void) interrupt 2 //INT EXTERNA 1<br />

{ unsigned char ciclo=0;<br />

Valores_Displays[Display_activo-1]=barrido;//GUARDA VALOR<br />

Display_activo++; //PASAR AL SIGUIENTE<br />

CMH0=0x07; //CARGA DEL VALOR INICIAL<br />

//DE CUENTA<br />

CML0=0xD0; //2000d=0x07D0<br />

cuenta2segundos=2000; //REINICIA COMPARADOR 0<br />

27


}<br />

If (Display_activo==4)<br />

{<br />

TR0=0; //PARAR T0<br />

TL0=255-100; //INICIO DE CUENTA<br />

Ciclo=calcula_premio(Valores_Displays[0],<br />

Valores_Displays[1],<br />

Valores_Displays[2]);<br />

PWM0=255-(255*(unsigned long)ciclo)/100;<br />

//CALCULAR VALOR PWM<br />

ECM0=0; //INT DEL COMPARADOR 0<br />

//DESHABILITADA<br />

EX1=0; //INT EXT1 DESHABILITADA<br />

EX0=1; //INT EXT0 HABILITADA<br />

}<br />

Void ISR_COMP0(void) interrupt 12 //COMPARADOR 0<br />

{<br />

unsigned char ciclo=0;<br />

}<br />

Valores_Displays[Display_activo-1]=barrido;//GUARDAR VALOR<br />

Display_activo++; //PASAR AL SIGUIENTE<br />

If (Display_activo==4)<br />

{<br />

TR0=0; //PARAR T0<br />

TL0=255-100; //INICIO DE CUENTA<br />

Ciclo=calcula_premio(Valores_Displays[0],<br />

Valores_Displays[1],<br />

Valores_Displays[2]);<br />

PWM0=255-(255*(unsigned long)ciclo)/100;<br />

ECM0=0; //INT COMP0 DESHABILITADA<br />

EX1=0; //INT EXTERNA1 DESHABILITADA<br />

EX0=1; //INT EXTERNA0 HABILITADA<br />

}<br />

cuenta2segundos+=2000; //CALCULA VALOR CARGA<br />

CMH0=(cuenta2segundos&0xFF00)>>8; //RECARGA COMPARADOR 0<br />

CML0=cuenta2segundos&0x00FF;<br />

CMI0=0; //FLAG COMPARADOR 0<br />

EJERCICIO 8)<br />

En un sis<strong>tema</strong> digital basado en el 80C552 que trabaja con un reloj de frecuencia 120<br />

KHz. se necesita realizar la medida del desfase entre dos señales <strong>digitales</strong> de periodo<br />

200 ms e igual ciclo de trabajo. Dicho valor debe guardarse, expresado en radianes, en<br />

la variable: float desfase.<br />

28


Indique, justificadamente, que elementos del microcontrolador usaría, con qué valores<br />

deben trabajar dichos elementos y realice en código C (comentando las instrucciones)<br />

toda la programación necesaria (iniciación de periféricos y rutina/s de interrupción/es de<br />

los mismos) para esta aplicación.<br />

NOTA: Tenga en cuenta que no es posible que lleguen dos flancos de la señal 1 sin que<br />

haya llegado alguno de la señal 2.<br />

Señal 1<br />

Señal 2<br />

t1<br />

Para calcular el desfase habrá que medir el tiempo t1 y relacionarlo con el periodo:<br />

φ = (t1 x 2π) / Tseñal<br />

Para medir t1 usaremos el timer 2 y dos de sus entradas de captura conectadas una a la<br />

señal 1 (CT0I) y la otra a la señal 2 (CT1I). Ambas activas por flanco de subida. Al<br />

capturar la segunda se producirá interrupción y se realizará el cálculo del desfase.<br />

Veamos si puede haber overflows:<br />

El desfase será menor de 200 msg lo que implica un número de cuentas:<br />

Sin prescaler: Tcuenta = TCLK x 12 = 12/(120 x 10 3 ) = 10 -4 = 0,1 msg<br />

nº de cuentas máximo: 200 / 0,1 = 2.000 < 65.536<br />

Luego no necesitamos contar los overflows.<br />

float desfase,cuenta;<br />

unsigned int valor1, valor2, ovf = 0;<br />

main (void)<br />

{<br />

EA = 0; /* se prohíben interrupciones */<br />

TM2CON = 0x00; /* timer 2 parado */<br />

CTCON = 0x05; /* CT0I y CT1I activas por flanco de subida*/<br />

}<br />

IP1 = 0x02; /* prioridad alta para la int. de CT1I */<br />

IEN1 = 0x02; /* se habilita la int. de CT1I */<br />

EA = 1; /* se habilitan interrupciones */<br />

TM2CON = 0x01; /* selecciona fuente de reloj para timer 2*/<br />

While(1);<br />

29<br />

t<br />

t


void timer2() interrupt 7<br />

{<br />

valor1 = (CTH0

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!