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
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