You are on page 1of 11

E.P.S.

de Ingeniería de Gijón
Ejemplos de Programación para Microcontroladores PIC
Módulos de Temporización hardware (TMR0 y TMR1 simultáneos)

Los elementos hardware de entrada y de salida para este ejemplo resultan


ser: dos pulsadores y 3 displays de 8 segmentos (7 de representación
numérica más el punto decimal) de ánodo común y se añade además un diodo
led como salida. Las conexiones realizadas a los pines del microcontrolador
PIC16F877 presente en la placa de prácticas denominada PICDEM2 (ó
PICDEM2 PLUS) serán las reflejadas en las figuras 1 y 2 que se adjuntan
con este enunciado.

En esta ejemplo se debe realizar un temporizador digital programable


descendente destinado a mostrar el tiempo restante para llegar al final de
cuenta (0.00), teniendo presente que se parte de un determinado tiempo
inicial que puede ser configurado por el usuario y que no puede ser
superior a 10 minutos.

El tiempo restante aparecerá permanentemente en los 3 displays citados


anteriormente. Se mostrarán minutos y segundos restantes (M.SS), salvo
en el último minuto en que se pasarán a mostrar segundos y décimas de
segundo que quedan (SS.D).

Para actuar sobre el citado temporizador descendente se dispone de 2


pulsadores, denominados:

• Marcha/Parada (M/P): conectado al pin 2 del puerto C (RC2)(*)


• Selección o Configuración (S): al pin 4 del puerto A (RA4)

El funcionamiento deseado para el temporizador será el siguiente:

1. Inicialmente, cuando se alimenta el circuito (Power On Reset) o


después de cualquier otro RESET, el temporizador aparecerá parado
y mostrando 0.00 a la espera de que le configuremos el tiempo de
partida.

2. Desde esa situación, las sucesivas actuaciones sobre el pulsador de


Selección S hará que se incrementen los segundos de 30 en 30. El
tiempo máximo configurable es de 10 minutos, si se alcanzara ese
valor y dado que disponemos de un solo display para mostrar minutos,
volvería a 0 la cuenta de minutos. La configuración del tiempo inicial

* En el supuesto de que se utilice la placa PICDEM 2 PLUS se debe sustituir RC2 por RB0

1
E.P.S. de Ingeniería de Gijón
Ejemplos de Programación para Microcontroladores PIC
sólo será posible si partimos del estado parado y mostrando 0.00
en los displays.

3. Después de configurar el tiempo, si se pulsa M/P, se iniciaría la


cuenta descendente partiendo siempre desde el valor previamente
configurado que estaría presente en los displays. Si en los displays
estuviera presente 0.00 (porque se partió del estado inicial o bien
porque así se configuró), se interpretará que el tiempo a temporizar
es de 10 minutos.

4. Cuando el temporizador está en marcha y mostrando la cuenta


descendente, será posible pararlo y ponerlo en marcha sucesivas
veces de manera alternativa mediante el pulsador M/P. Si el
temporizador está en marcha y se pulsa M/P de manera
ininterrumpida durante 2 segundos, pasaremos el estado inicial en
que se muestra 0.00 y el temporizador está parado.

5. Cuando el temporizador esté en marcha, las pulsaciones sobre S


serán ignoradas. Cuando el temporizador llegue al final de la cuenta
éste quedará parado y mostrando 0.00 en los displays. Dado que
desde el estado de configuración sería válido actuar tanto sobre el
pulsador de selección de tiempo (S) como el de puesta en marcha
(M/P), se considera más prioritario este último en el supuesto de que
ambos estén pulsados simultáneamente.

6. Durante el proceso de cuenta descendente, un diodo led conectado


al pin 4 del Puerto B (RB4) permanecerá encendido, quedando
apagado durante el resto del tiempo.

El microcontrolador dispondrá de un oscilador de frecuencia 4MHz.

2
E.P.S. de Ingeniería de Gijón
Ejemplos de Programación para Microcontroladores PIC

..... ..... .....


Selección
Control de Segmentos display
SISTEMA BASADO
4MHz EN MICROCONTROLADOR
PIC16F877 RB4
RA4 RC2
+5V +5V

S M/P
(selección) (marcha/parada)

Figura 1.- Elementos para la Práctica


VCC

R6 R5 R7
4K7 4K7 4K7
R2 R3 R4
RA1 Q1 RA2 Q1 RA3 Q1
BC557 BC557 BC557
1K2 1K2 1K2

DISP_C DISP_D DISP_U


S0 7 A S0 7 A S0 7 A
S1 6 B S1 6 B S1 6 B
S2 4 5 S7 S2 4 5 S7 S2 4 5 S7
C DP C DP C DP
S3 2 S3 2 S3 2
D D D
S4 1 S4 1 S4 1
E E E
S5 9 S5 9 S5 9
F F F
S6 10 A2 3 S6 10 A2 3 S6 10 A2 3
G G G
A1 8 A1 8 A1 8

HDSP-5301 HDSP-5301 HDSP-5301

VCC
J1 R1
GND 1 2 +5V RD0 1 16 S0
3 + + 4 RA1 RD6 2 15 S6
RA2 5 + + 6 RA3 RD4 3 14 S4
RD0 7 + + 8 RD1 RD3 4 13 S3
RD2 9 + + 10 RD3 RD1 5 12 S1
RD4 11 + + 12 RD5 RD5 6 11 S5
RD6 13 + + 14 RD7 RD2 7 10 S2
+ + RD7 8 9 S7

Conector IDC14
8x100 ohmios

Figura 2.- Esquema de la placa de Displays

3
E.P.S. de Ingeniería de Gijón
Ejemplos de Programación para Microcontroladores PIC
UNA POSIBLE SOLUCIÓN
(que por supuesto no es única)

Diagrama de Estados y transiciones del circuito:

Pulsación S

Pulsación en M/P

PARADO Y
CUENTA
CONFIGURANDO
DESCENDENTE

Fin de la cuenta
Pulsación M/P

Pulsado M/P
más de 2 s Pulsación M/P

PARADO
MOSTRANDO T
RESTANTE

Se codifican los 3 estados posibles para decidir, durante la ejecución del


programa, las acciones sobre las salidas y los posibles cambios de Estado
una vez leídas las entradas.

ESTADO: 0->b’00000000’ Parado y configurando


1->b’00000001’ Cuenta en modo descendente
2->b’00000010’ Parado y mostrando el tiempo restante

La precisión que necesitamos es de décimas de segundo puesto que es la


cantidad mínima a contabilizar. Emplearemos el TMR1 para que genere una
interrupción cada décima de segundo si tiene que contabilizar tiempo. El
empleo de TMR1 es más adecuado que TMR0 porque tiene la posibilidad de
ser detenido y además permite temporizaciones más largas. TMR1 debe
contabilizar tiempo en dos situaciones distintas:

• Si nos encontramos en el Estado 1 (Contando) para decrementar de


décima de segundo en décima

4
E.P.S. de Ingeniería de Gijón
Ejemplos de Programación para Microcontroladores PIC
• Si acabamos de pasar del Estado 1 al Estado 2 (Parado) por pulsación
sobre M/P para ver si este pulsador permanece más de 2 segundos
pulsado

Dada la disposición de los displays con una conexión común de las líneas de
control de los segmentos, el programa principal se dedicará a realizar un
barrido continuo de los mismos. El procedimiento de selección de un display
y su representación se realizará dentro de un subprograma que incluirá el
código correspondiente a un barrido completo de los 3 displays y la decisión
sobre la representación de minutos y segundos o de segundos y décimas
de segundo. La ejecución de ese subprograma tardará aproximadamente
15ms ya que retendremos la representación sobre cada display durante 5ms.
Esa temporización la realizaremos con el TMR0.

El subprograma de barrido recogerá los valores a representar de tres


posiciones cuyo nombre y contenido sería (con codificación en BCD):

DECIMAS 0 Décimas de segundo


SEGUNDOS Decenas de Segundo Unidades de Segundo
MINUTOS 0 Unidades de Minuto

Si nos encontramos en el Estado 1 y las Unidades de Minuto son 0 se


mostrarán Segundos y Décimas, con el punto decimal en el display del
centro. En caso contrario, aparecerán minutos y segundos y el punto decimal
en el display de la izquierda. Para saber qué punto hay que sacar usaremos el
bit 0 de una posición denominada PUNTO. Si PUNTO<0> = 1 entonces
activamos el pto decimal del display de la izquierda (M.SS) y si el citado bit
está a 0 activaremos el punto del display del centro (SS.D).

A la hora de establecer los cambios de Estado a partir de las entradas,


resulta necesario detectar cambios en los pulsadores ya que no sirve la
simple lectura de los mismos. Por tal motivo, se utiliza una posición auxiliar
denominada ANTES que almacenará en sus 2 bits menos significativos la
lectura anterior (en el paso por la anterior exploración de los pulsadores)
que se produce cada 15 ms aproximadamente (un barrido).

b7 b6 b5 b4 b3 b2 b1 b0
ANTES RA4 “antes” RC2 “antes”
(S) (M/P)
selección marcha/parada

5
E.P.S. de Ingeniería de Gijón
Ejemplos de Programación para Microcontroladores PIC
Antes de dar como válida una pulsación de cualquiera de los pulsadores, se
establece una temporización que permita descartar posibles rebotes, esto
se consigue llamando 7 veces al subprograma de barrido para así completar
unos 105 ms (7 x 15ms) de espera antes de volver a examinar el estado de
los pulsadores y asegura así la desaparición de rebotes.

CÁLCULOS PARA LAS TEMPORIZACIONES:

TMR1: para temporizar una décima de segundo

0,1s = (4/4MHz) x Prescaler de TMR1 x (65536 - Precarga TMR1)

Si elegimos: Prescaler de TMR1 = 8 (valor máximo)

entonces despejando: Precarga de TMR1 = 53036 -> 0xCF2C

TMR0: para temporizar 5ms

5ms = (4/4MHz) x Prescaler de TMR0 x (256 - Precarga TMR0)

Elegimos: Prescaler de TMR0 = 128

y despejando: Precarga de TMR0 = 217 -> 0xD9

Algoritmo utilizado:

INICIALIZACIÓN

• Dirección de datos en los Puertos:


• PORTA (RA1, RA2 y RA3 son las salidas para selección del
display, el resto entradas). De momento se ponen las salidas a 1
para desactivar todos los displays
• PORTB (RB4 como salida para controlar el led que indica estado
de temporización). Apagamos el led con un 0
• PORTC (como entrada, aunque sólo usamos RC2)
• PORTD (salida ya que se usa para manejo de los segmentos:
RD0 el a, RD1 el b, ..., RD6 el g y RD7 el punto decimal)
• TMR0: definido en modo temporizador y con prescaler de 128
• TMR1: modo temporizador, prescaler de 8 y parado inicialmente
• Precarga de TMR1: TMR1H con 0xCF y TMR1L con 0x2C

6
E.P.S. de Ingeniería de Gijón
Ejemplos de Programación para Microcontroladores PIC
• INTERRUPCIONES: habilitar las de TMR1 y borrar el flag
TMR1IF
• Inicializamos las variables:
• DECIMAS, MINUTOS y SEGUNDOS a cero
• ESTADO a cero (parado y listo para configurar)
• Estado anterior de los pulsadores (bits 0 y 1 de la posición
ANTES a uno para indicar que se consideran no pulsados en el
arranque)

BUCLE DEL PROGRAMA PRINCIPAL

• Llamada al Subprograma de Barrido de los Displays


• Leemos el Estado de los pulsadores RA4 y RC2 simultáneamente y
lo guardamos en una posición que llamamos AHORA, están en dos
puertos distintos y no los podríamos leer simultáneamente:
RA4 (S) -> AHORA<1> y RC2 (M/P) -> AHORA<0>
• Si el ESTADO es el 0 (parado y configurando) entonces
Si el pulsador M/P está pulsado (AHORA<0> a 0) entonces
Si antes estaba a 1 (ANTES<0> =1) entonces
Llamamos a subprograma de espera para descartar
posibles rebotes (CALL T_REBOTES)
Si sigue RC2 a 0 (era una pulsación) entonces
Cambiamos ESTADO a 1 (contando)
Ponemos TMR1 en marcha (TMR1ON=1)
Ponemos a cero DECIMAS
Si MINUTOS=0 y SEGUNDOS=0 es porque
están seleccionados 10 minutos y cargamos
D’10’ en MINUTOS para empezar
Vamos al final del bucle ya que M/P está
pulsado y es más prioritario que S
si no (es que se trataba de un rebote en RC2)
Cargamos estado actual del pulsador:
AHORA<0> a 1
Si el pulsador S está pulsado (AHORA<1> = 0) entonces
Si antes estaba a 1 (ANTES<1> = 1) entonces
Llamamos a subprograma de espera para descartar
posibles rebotes (CALL T_REBOTES)
Si sigue RA4 a 0 (era una pulsación) entonces
Sumamos 30 a SEGUNDOS
Si SEGUNDOS = 60 entonces
SEGUNDOS=0

7
E.P.S. de Ingeniería de Gijón
Ejemplos de Programación para Microcontroladores PIC
MINUTOS=MINUTOS+1
Si MINUTOS=10 entonces
MINUTOS=0
si no sigue RA4 a 0 (en RA4 había rebote)
Cargamos estado actual de este pulsador:
AHORA<1>=1
• Si el ESTADO es el 1 (Contando) entonces
Si el pulsador M/P está pulsado (AHORA<0>=0) entonces
Si antes estaba a 1 (ANTES<0> =1) entonces
Llamamos a subprograma de espera para descartar
posibles rebotes (CALL T_REBOTES)
Si sigue RC2 a 0 (era una pulsación) entonces
Cambiamos ESTADO a 2 (Parado)
Dejamos TMR1 en marcha para contar 2
segundos de pulsación continua (ya que se
acaba de detectar cambio)
Ponemos T_PULSADO=0 contador de
interrupciones de TMR1 para saber si
llegamos a 20 (2s pulsado)
si no sigue RC2 a 0 (era un rebote en RC2)
Cargamos estado actual de este pulsador:
AHORA<0>=1
• Si el ESTADO es el 2 (Parado) entonces
Si el pulsador M/P está pulsado (AHORA<0>=0) entonces
Si antes estaba a 1 (ANTES<0> =1) entonces
Llamamos a subprograma de espera para descartar
posibles rebotes (CALL T_REBOTES)
Si sigue RC2 a 0 (era una pulsación) entonces
Cambiamos ESTADO a 1 (Contando)
Ponemos TMR1 en marcha (TMR1ON=1)
si no sigue RC2 a 0 (era un rebote)
Cargamos estado actual de este pulsador:
AHORA<0>=1
• Registramos estado actual de pulsadores en ANTES para el
siguiente paso de muestreo:
ANTES <- AHORA
• Si el ESTADO es el 1 (temporizando) entonces
Encendemos el led conectado al pin 4 del puerto B
si no
Apagamos el led
• Vamos al principio del bucle del programa principal

8
E.P.S. de Ingeniería de Gijón
Ejemplos de Programación para Microcontroladores PIC
PROGRAMA DE TRATAMIENTO DE LA INTERRUPCIÓN DE TMR1

• Si no está el flag TMR1IF a 1 nos salimos directamente del


programa de tratamiento
• Salvaguarda del contexto (W, STATUS y PCLATH)
• Precarga de nuevo de TMR1 en TMR1H y TMR1L
• Si el Estado es Contando (ESTADO =1) entonces:
Llamada a subprograma de DECREMENTO
• Si el Estado es Parado (ESTADO=2) entonces es porque se entró
en él y no se dejó de pulsar M/P (RC2)
Si RC2=0 (es que sigue pulsado) entonces
T_PULSADO=T_PULSADO+1
Si (T_PULSADO =20) entonces es que van 2 s pulsado
Cambiamos ESTADO a 0 (parado y configurando)
Paramos TMR1 (TMR1ON=0)
Ponemos a cero DECIMAS, SEGUNDOS y
MINUTOS
si no (RC2 ya no está pulsado) entonces
Paramos TMR1 (TMR1ON=0) porque no hay que seguir
contando, se interrumpieron los 2s de pulsación continua
• Se pone el flag a cero (TMR1IF=0)
• Recuperación del contexto (PCLATH, STATUS y W)
• Retorno de programa de tratamiento de interrupción

SUBPROGRAMA DE DECREMENTO

• Si DECIMAS no es 0 entonces
DECIMAS=DECIMAS-1
Si DECIMAS=0 entonces
Si SEGUNDOS=0 entonces
Si MINUTOS=0 entonces
Es que hemos llegado al final de la
temporización y lo que hacemos es:
Parar el TMR1 (TMR1ON=0)
Pasar el ESTADO 0 (parado y configurando)
si no (DECIMAS=0)
DECIMAS=9
Si las unidades de SEGUNDOS no son 0 entonces
unidades de SEGUNDOS = unidades de SEGUNDOS-1
si no (unidades de SEGUNDOS=0)
unidades de SEGUNDOS=9

9
E.P.S. de Ingeniería de Gijón
Ejemplos de Programación para Microcontroladores PIC
Si las decenas de SEGUNDOS no son 0 entonces
dec. de SEGUNDOS = dec. de SEGUNDOS –1
si no (decenas de SEGUNDOS=0)
dec. de SEGUNDOS = 5
Si MINUTOS no es 0
MINUTOS=MINUTOS-1
• Retorno de Subprograma de Decremento

SUBPROGRAMA DE BARRIDO DE LOS DISPLAYS

• Al principio preparamos para que se muestre M.SS:


• IZQ = MINUTOS (los minutos en el display de la izquierda)
• CENTRO = Dec. SEGUNDOS (las decenas de seg. en el centro)
• DCHA = Unid. SEGUNDOS (las unidades de seg. a la dcha.)
• Punto = b’00000001’ (el pto. decimal en el display izquierdo)
• Si ESTADO no es el 0 (estamos contando o mostrando T actual)
entonces
Si MINUTOS=0 entonces (hay que mostrar SS.D)
IZQ = Dec. SEGUNDOS
CENTRO = Unid. SEGUNDOS
DCHA = DECIMAS
Punto = b’00000000’

• Pasamos ahora a activar los displays


• Sacamos Display de la derecha:
• Activación del display con RA3=0, RA2=1 y RA1=1
• Tomamos posición DCHA
• Búsqueda en la tabla de los led a iluminar y los sacamos al
PORTD (Subprograma TABLALED)
• Espera durante 5 ms (llamada a Subprograma ESPERA)
• Establecemos un tiempo muerto: apagamos todos los
segmentos

• Mostramos el display del centro: ídem con posición CENTRO


(RA3=1, RA2=0 y RA1=1)
Si Punto<0> = 0 activamos también punto decimal del display
• Display de la izquierda: ídem con posición IZQ (RA3=1, RA2=1 y
RA1=0)
Si Punto<0> = 1 activamos también punto decimal del display
• Retorno de subprograma de Barrido de Displays

10
E.P.S. de Ingeniería de Gijón
Ejemplos de Programación para Microcontroladores PIC
SUBPROGRAMA TABLALED

• Entramos en el subprograma llevando en W el dígito BCD que


queremos representar
• Nos desplazamos en una tabla de búsqueda que nos devuelve los
segmentos a iluminar (las salidas correspondientes deben estar a
0) para representar tal dígito
• Sacamos el valor al PORTD
• Retorno de subprograma

SUBPROGRAMA ESPERA

• Se precarga TMR0 con 0xD9


• Se sitúa el flag T0IF a 0
• Esperamos a que T0IF se ponga a 1
• Retorno de subprograma

SUBPROGRAMA T_REBOTES
(Subprograma de temporización de 105 ms con barrido simultáneo de los
displays de 7 segmentos)

• Cargamos un contador con un valor 7


• Decrementamos el contador
• Si el contador no llegó a 0 entonces
Llamamos a subprograma de barrido de los displays (15ms)
• si llegó a cero (hemos repetido 7 veces) entonces
Retornamos del subprograma

11

You might also like