Está en la página 1de 13

IT-8-ACM-03-R02

UNIVERSIDAD AUTÓNOMA DE NUEVO LEÓN


FACULTAD DE INGENIERÍA MECÁNICA Y ELÉCTRICA

TIPO DE EXAMEN: MEDIO CURSO ENERO JUNIO


MATERIA: DISEÑO DE SISTEMAS EMBEBIDOS
SEMESTRE: SEPTIMO
ACADEMIA: ELECTRONICA

Luis Fernando Martínez Ovalle 14 03


Nombre: __________________________________________________________Fecha____/____/2023

1754102
Matricula __________________Hora V1-V3 Salón _________
_______ 12:00 Final ______
7215 Tiempo: Inicio ______ 14:30

INSTRUCCIONES:

a) Lea cuidadosamente este examen y resuelva los problemas propuestos en las hojas anexas, encierre los resultados en un
rectángulo, no despegue las hojas. Favor de dejar su celular apagado y dentro de su mochila.
b) Es un examen individual a libro cerrado, no está permitido el uso de notas, apuntes, calculadoras.
c) No se arriesgue, será considerado como copia, ver el examen de su compañero o el uso de notas.
d) Confirme los resultados obtenidos, de un ingeniero esperan que proporcione resultados correctos y soluciones concretas.
e) Concéntrese en su examen, tiene 2 horas 30 minutos para resolverlo.

Reloj Programable utilizando Interrupciones Externas y Barrido en displays

Utilizando dos displays de 4 dígitos de ánodo común se generará un barrido generando persistencia visual en
los displays. Para ello se utilizará un CI 74238 para controlar el ánodo que enciende cada digito y un CI 7447
para generar el número que se escribirá en cada digito. Para lograr el funcionamiento adecuado siga las
siguientes instrucciones:
1.- Desarrolle el código necesario para enviar un numero y su correspondiente señal de activación en el lugar
que le corresponda del display.
2.- Genere el efecto de persistencia visual de forma simultanea en los 8 dígitos del display, considerando un
digito apagado entre horas, minutos y segundos.
3.- Genere un contador de interrupciones.
4.- Utilizando el ADC, ajuste el rango de la conversión de 0-4095 a 0-60 para segundos y minutos, y de 0-
4095 a 0-24 para las horas. Al tener el contador de interrupciones el valor de 1 se asignará la lectura
correspondiente a los segundos, el valor de 2 asignara el valor del adc a los minutos y por último al ser el
contador de interrupciones el valor de 3 se asignara el valor correspondiente del adc a las horas.

Indicaciones para el reporte del Proyecto:

1.- Marco Teórico


Describir:
Persistencia de la visión
La persistencia de la visión es un tipo de ilusión óptica según la cual el ojo humano continua viendo, por un
pequeño lapso de tiempo, una imagen después de que esta ya no esté en el campo de visión. Se utiliza en la
animación para dar la impresión de movimiento. El físico Peter Mark Roget describió por primera vez este efecto,
también conocido como “persistencia retiniana”, y proporcionó una definición para la persistencia de la visión en
el siglo XIX. Explicó que la retina humana puede retener una imagen durante una fracción de segundo antes de
que otra la reemplace. Esto llevó al descubrimiento de que, si se reemplaza una imagen tras otra en una secuencia
veloz, se obtiene la ilusión del movimiento.

REVISIÓN No.: 7
VIGENTE A PARTIR DE: 01 de Agosto del 2016
Ejemplos de persistencia de la visión en el día a día:
• La línea “continua” de luz que se puede ver cuando saltan chispas en una hoguera por la noche.
• Si se mueve un palo de incienso en círculos con la velocidad suficiente, se puede observar un círculo de
luz roja.
• Al mirar las aspas en movimiento de un ventilador, parece que estén unidas.

En el mundo de la ingeniería electrónica se utiliza comúnmente este fenómeno para el control de múltiples
displays con la intención de generar lectura de los diferentes caracteres que se pueden formar sin que se pierda la
visualización durante la transición o cambio de caracter de cada uno de ellos.

Interrupciones en microcontroladores
Las interrupciones son eventos que hacen que el microcontrolador deje de realizar la tarea actual y pase a efectuar
otra actividad. Al finalizar la segunda actividad retorna a la primera y continúa a partir del punto donde se produjo
la interrupción. Las interrupciones permiten que un solo microcontrolador ejecute varias tareas (no exactamente
al mismo tiempo) dependiendo del evento que desencadene la interrupción. Estos dispositivos tienen desde 10
hasta 15 fuentes de interrupción dependiendo del tipo específico de microcontrolador. El manejo de las
interrupciones se programa por medio de registros especiales que controlan el comportamiento del
microcontrolador bajo determinadas circunstancias.

Funcionamiento del Convertidor analógico a digital de aproximaciones sucesivas


El convertidor analógico-digital de aproximaciones sucesivas es uno de los convertidores màs usados y tiene
como parte de sus características fundamentales la conversión en lapso de tiempo corto, con respecto a las
configuraciones que le preceden como el convertidor de rampa.

Aplicaciones:
• Digitalización de sonido
• .Multímetro digital
• Microcontroladores con conversores A/D

Requerimientos:
Se requiere un mínimo de tres terminales de control:
• Una señal de reloj
• Fin de conversión
• Inicio de la conversión
Una salida digital: en forma serie o paralela.
Una terminal: para el voltaje de entrada analógica Vent.
Consta de: un convertidor digital analógico.

Comparador.
La operación de los convertidores A/D está basada en "n" comparaciones sucesivas de la señal analógica con el
voltaje de realimentación Vf.

Circuito Integrado.
El AD670 es un convertidor analógico a digital de aproximaciones sucesivas compatible con microprocesadores
de 8 bits. El encapsulado de 20 terminales, contiene todas las características ya mencionadas. Ademàs contiene
reloj integrado, voltaje de referencia y amplificador de instrumentación y sólo necesita una fuente de poder
sencilla de 5V.

REVISIÓN No.: 7
VIGENTE A PARTIR DE: 01 de Agosto del 2016
Funcionamiento:
El voltaje analógico de entrada se compara con Vo. El comparador le dice a SAR cuando Vent es mayor o menor
que la salida del convertidor digital o analógico, Vo. Para cada bit de la salida de 3 bits, deben efectuarse tres
comparaciones. Transforma cada número digital en una salida analógica Vo. Las comparaciones se hacen
comenzando con el bit màs significativo y terminan con el bit menos significativo. Al terminar la comparación el
registro de aproximaciòn sucesiva (SAR) envía la señal que finalizò la conversión. El equivalente digital de Vent
està ahora presente en la salida digital del registro. Conecta la secuencia de números digitales, un número por
cada bit, a las entradas del convertidor digital a analógico.

Ilustre gráficamente de la mejor forma posible el fenómeno de persistencia de la visión..

A continuación, se muestra un ejemplo gráfico del fenómeno de persistencia visual utilizando los displays y un
delay de 100 milisegundos para poder realizar de mejor manera su captura.

2.- Algoritmo

Elabore un diagrama de flujo que muestre el comportamiento general del programa utilizado.

REVISIÓN No.: 7
VIGENTE A PARTIR DE: 01 de Agosto del 2016
Programa principal

REVISIÓN No.: 7
VIGENTE A PARTIR DE: 01 de Agosto del 2016
Subrutina de interrupción

Llamada de la interrupción

REVISIÓN No.: 7
VIGENTE A PARTIR DE: 01 de Agosto del 2016
3.- Diagrama Eléctrico

Elabore un diagrama eléctrico que muestre todas las conexiones de los componentes utilizados.

REVISIÓN No.: 7
VIGENTE A PARTIR DE: 01 de Agosto del 2016
4.- Evidencia gráfica
Imágenes representativas del funcionamiento del circuito.
Circuito energizado

Primer interrupción valor de los seg = 30

REVISIÓN No.: 7
VIGENTE A PARTIR DE: 01 de Agosto del 2016
Segunda interrupción vaor de lo min = 30

Tercer interrupción valor de las hr = 12

REVISIÓN No.: 7
VIGENTE A PARTIR DE: 01 de Agosto del 2016
5.- Escriba y explique el código utilizado para los siguientes apartados
Configuración de los periféricos.
En la línea 1 se inicia la configuración del sistema y los periféricos a través de la función main().
En la línea 3 se realiza una llamada a la función de inicialización de los pines GPIO. Esta función es generada
automáticamente por la herramienta de generación de código.
En la línea 4 se establece la configuración del ADC se realiza en la función MX_ADC1_Init(). En esta función
se configuran los parámetros del ADC, como la resolución, la tensión de referencia y el modo de conversión.
En la línea 5 se establece la configuración del RTC se realiza en la función MX_RTC_Init(). En esta función se
configuran los parámetros del RTC, como el formato de fecha y hora, el formato de visualización y la fuente de
reloj utilizada.
1. int main(void)
2. {
3. MX_GPIO_Init();
4. MX_ADC1_Init();
5. MX_RTC_Init();

Escriba los prototipos de funciones utilizados.


En la línea 1 declara un prototipo de función llamada displayNumber que toma un parámetro valor de tipo entero.
Esta función se utiliza para mostrar un número en los displays de 7 segmentos.
En la línea 2 declara un prototipo de función llamada setDisplay que toma ocho parámetros de tipo entero (dig1,
dig2, dig3, dig4, dig5, dig6, dig7, dig8). Esta función se utiliza para configurar los dígitos de los displays de 7
segmentos.
En la línea 3 se utiliza para configurar el sistema de reloj del microcontrolador.
En la línea 4 se utiliza para inicializar y configurar los pines GPIO (General Purpose Input/Output) del
microcontrolador.
En la línea 5 se utiliza para inicializar y configurar el ADC1 (convertidor analógico-digital).
En la línea 6 se utiliza para inicializar y configurar el módulo de tiempo real (RTC).
1. void displayNumber(int valor);
2. void setDisplay(int dig1, int dig2, int dig3, int dig4, int dig5, int dig6, int dig7, int dig8);
3. void SystemClock_Config(void);
4. static void MX_GPIO_Init(void);
5. static void MX_ADC1_Init(void);
6. static void MX_RTC_Init(void);

Escritura de un número y generación del barrido en los displays (describir displayNumber y setDisplay)

En este prototipo llamado displayNumber se declaran las unidades a los dígitos de los display utilizados
empezando por las unidades valor más pequeño hasta las decenas de millón que es un valor muy pesado.
En la línea 1 se inicia la función “displayNumber”.
En la línea 3 las variables correspondientes a los 8 dígitos son declaradas.
En la línea 4 la variable de dig1, almacenará las unidades y este será igual al “número” módulo de 10, es decir, esta
operación obtiene el dígito más a la derecha de “numero” dividiendo el número por 10 y tomando el resto. Por ejemplo, si
“número” es igual a 456, entonces dig1 será igual a 6, ya que 456 % 10 es igual a 6.
En la línea 5 el valor de dig2 se almacenan las decenas y este será igual al “número” entre 100, es decir, se obtiene el
segundo dígito de derecha a izquierda dividiendo el “número” por 100 (para eliminar los dos dígitos más a la derecha) y
luego dividiendo el resultado por 10 (para obtener el dígito en la posición deseada). Por ejemplo, si “número” es igual a
456, entonces dig2 será igual a 5, ya que (456 % 100) / 10 es igual a 5.
En la línea 6 el valor de dig3 se almacenan las centenas y este será igual al “número” entre 1000, es decir, esta operación
sigue el mismo principio que la anterior, pero ahora se divide por 1000 (para eliminar los tres dígitos más a la derecha) y
luego se divide por 100 (para obtener el dígito en la posición deseada). Por ejemplo, si “número” es igual a 456, entonces
dig3 será igual a 4, ya que (456 % 1000) / 100 es igual a 4.
REVISIÓN No.: 7
VIGENTE A PARTIR DE: 01 de Agosto del 2016
Las operaciones de las líneas 7 a la 11 siguen el mismo patrón, dividiendo el número por un múltiplo cada vez mayor de
10 y luego dividiendo el resultado por 10 para obtener el dígito correspondiente en cada posición.
En la línea 12 manda llamar a la función setDisplay, con los parámetros correspondientes a los dígitos definidos
en displayNumber.
1. void displayNumber(int count)
2. {
3. int dig1, dig2, dig3, dig4, dig5, dig6, dig7, dig8;
4. dig1 = count%10; /* Unidades */
5. dig2 = (count%100)/10; /* Decenas */
6. dig3 = (count%1000)/100; /* Centenas */
7. dig4 = (count%10000)/1000; /* Unidades de millar */
8. dig5 = (count%100000)/10000; /* Decenas de millar */
9. dig6 = (count%1000000)/100000; /* Centenas de millar */
10. dig7 = (count%10000000)/1000000; /* Unidades de millón */
11. dig8 = (count%100000000)/10000000; /* Decenas de millón */
12. setDisplay(dig1,dig2,dig3,dig4,dig5,dig6,dig7,dig8);
13. }

En la línea 14 comienza la función “setDisplay”


En la línea 16 se concatena la constante D8, más la variable “dig 8” del vector “números” y se imprime en la posición del
display
En la línea 17 se mantiene este número por 1 milisegundo.
En la línea 18 se concatena la constante D7, más la variable “dig 7” del vector “números” y se imprime en la posición del
display
En la línea 19 se mantiene este número por 1 milisegundo.
En la línea 20 se concatena la constante D5, más la variable “dig 5” del vector “números” y se imprime en la posición del
display
En la línea 21 se mantiene este número por 1 milisegundo.
En la línea 22 se concatena la constante D4, más la variable “dig 4” del vector “números” y se imprime en la posición del
display
En la línea 23 se mantiene este número por 1 milisegundo.
En la línea 24 se concatena la constante D2, más la variable “dig 2” del vector “números” y se imprime en la posición del
display
En la línea 25 se mantiene este número por 1 milisegundo.
En la línea 26 se concatena la constante D1, más la variable “dig 1” del vector “números” y se imprime en la posición del
display
En la línea 27 se mantiene este número por 1 milisegundo.
14. void setDisplay(int dig1, int dig2, int dig3, int dig4, int dig5, int dig6,
int dig7, int dig8)
15. {
16. GPIOC->ODR = D8+numeros[dig8];
17. HAL_Delay(1);
18. GPIOC->ODR = D7+numeros[dig7];
19. HAL_Delay(1);
20. GPIOC->ODR = D5+numeros[dig5];
21. HAL_Delay(1);
22. GPIOC->ODR = D4+numeros[dig4];
23. HAL_Delay(1);
24. GPIOC->ODR = D2+numeros[dig2];
25. HAL_Delay(1);
26. GPIOC->ODR = D1+numeros[dig1];
27. HAL_Delay(1);

Explique la o las llamadas a función presentes en el loop de control principal

REVISIÓN No.: 7
VIGENTE A PARTIR DE: 01 de Agosto del 2016
En la línea 1 se llama a la función GetTime(). Esta función se utiliza para obtener la hora actual del módulo de
tiempo real (RTC) y almacenarla en las variables seg, min y hr.
En la línea 2 llama a la función displayNumber() y pasa la variable hrs como argumento. La función
displayNumber() toma un valor entero y muestra ese valor en los displays de 7 segmentos.
En la línea 3 se llama a la función setDisplay() y pasa ocho argumentos de tipo entero. La función setDisplay()
se utiliza para configurar los dígitos de los displays de 7 segmentos según los valores pasados como argumentos.
En la línea 4 define una función llamada HAL_GPIO_EXTI_Callback que se llama cuando se produce una
interrupción externa en un pin GPIO específico (GPIO_Pin). Esta función se ejecuta en respuesta a una
interrupción y puede contener el código necesario para manejar la interrupción.
En la línea 5 define una función llamada adc_scan que no toma ningún argumento y devuelve un valor de tipo
uint32_t. Esta función se utiliza para realizar una conversión del convertidor analógico-digital (ADC) y devuelve
el valor digital convertido.
1. GetTime ();
2. displayNumber(hrs);
3. setDisplay(int dig1, int dig2, int dig3, int dig4, int dig5,int dig6,int dig7,int dig8);
4. HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
5. uint32_t adc_scan(void)

Proceso de interrupción y la subrutina de servicio de interrupción (Subrutina de servicio de interrupcion)

En la línea 1 se hace la llamada a la función que gestiona la generación interrupción de la línea EXTI.
En la línea 3 esta función gestiona la solicitud de interrupción de todas las interrupciones externas, y da como
parámetro de entrada el B1_Pin.
1. void EXTI15_10_IRQHandler(void)
2. {
3. HAL_GPIO_EXTI_IRQHandler(B1_Pin);
4. }

En la línea 1 se establece la función HAL_GPIO_EXTI_IRQHandler es la rutina de interrupción que se ejecuta


cuando se detecta una interrupción externa en uno de los pines GPIO configurados para ello. Recibe como
argumento el número de pin que generó la interrupción (GPIO_Pin).
En la línea 3 el bucle for se utiliza para generar un retraso o espera antes de continuar con el resto del código,
como filtro por software anti rebote para el push button.
En la línea 5 se verifica si la interrupción externa ha sido generada por el pin específico (GPIO_Pin) utilizando
la función __HAL_GPIO_EXTI_GET_IT().
En la línea 7 si la interrupción fue detectada, se borra la bandera de interrupción llamando a la función
_HAL_GPIO_EXTI_CLEAR_IT().
En la línea 8 e llama a la función HAL_GPIO_EXTI_Callback(), que se espera que sea la función de callback
(retorno de llamada) donde se manejará la interrupción externa específica.
1. void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
2. {
3. for(int a=0;a++;a<90000)
4. {}
5. if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
6. {
7. __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
8. HAL_GPIO_EXTI_Callback(GPIO_Pin);
9. }
10. }

Conversión del valor adquirido mediante el adc a horas, minutos y segundos


REVISIÓN No.: 7
VIGENTE A PARTIR DE: 01 de Agosto del 2016
En la línea 1 se utiliza una variable llamada Ext_int_counter a través de un switch case para determinar qué
conversión se está realizando según el número de interrupciones externas ocurridas. Dependiendo del valor de
Ext_int_counter, se realiza una conversión específica.
En la línea 3 se establece el caso 0 el cuál no tiene ninguna función.
En la línea 6 se establece el caso 1.
En la línea 7 el valor del ADC se divide por 68.28 para convertirlo a segundos (Ejemplo 4095 / 68.28 = 59.97 ≈
60).
En la línea 8 se asigna el resultado a sTime1.Seconds, que representa los segundos en la estructura del tiempo del
RTC.
En la línea 9 se utiliza la función HAL_RTC_SetTime() para actualizar la estructura de tiempo del RTC con los
nuevos valores.
En la línea 11 se establece el caso 2.
En la línea 12 el valor del ADC se divide por 68.28 para convertirlo a minutos (Ejemplo 4095 / 68.28 = 59.97 ≈
60).
En la línea 13 se asigna el resultado a sTime1.Minutes, que representa los minutos en la estructura del tiempo del
RTC.
En la línea 14 se utiliza la función HAL_RTC_SetTime() para actualizar la estructura de tiempo del RTC con los
nuevos valores.
En la línea 16 se establece el caso 2.
En la línea 17 el valor del ADC se divide por 170.7 para convertirlo a horas (Ejemplo 4095 / 170.7 = 23.98 ≈ 24).
En la línea 18 se asigna el resultado a sTime1.Hours, que representa las horas en la estructura del tiempo del
RTC.
En la línea 19 se utiliza la función HAL_RTC_SetTime() para actualizar la estructura de tiempo del RTC con los
nuevos valores.
En la línea 22 si no se efectúa ninguno de estos casos la variable Ext_int_counter se igualará a 0.

1. switch(Ext_int_counter)
2. {
3. case 0:
4. //Este caso no puede suceder
5. break;
6. case 1:
7. seg=adcValue/68.28;//Parámetro de control 4095 a 60
8. sTime1.Seconds=seg;//Segundos
9. HAL_RTC_SetTime(&hrtc, &sTime1,RTC_FORMAT_BIN);
10. break;
11. case 2:
12. min=adcValue/68.28;//Parámetro de control 4095 a 60
13. sTime1.Minutes=min;//Minutos
14. HAL_RTC_SetTime(&hrtc, &sTime1,RTC_FORMAT_BIN);
15. break;
16. case 3:
17. hr=adcValue/170.7;//Parámetro de control 4095 a 24
18. sTime1.Hours=hr;//Horas
19. HAL_RTC_SetTime(&hrtc, &sTime1,RTC_FORMAT_BIN);
20. break;
21. default:
22. Ext_int_counter = 0;
23. break;
24. }

REVISIÓN No.: 7
VIGENTE A PARTIR DE: 01 de Agosto del 2016
Nota: Adjunte el codigo completo del programa utilizado en archivo zip.

REVISIÓN No.: 7
VIGENTE A PARTIR DE: 01 de Agosto del 2016

También podría gustarte