Vous êtes sur la page 1sur 9

Reloj Digital con Displays de 7 Segmentos y PIC 16F84A

En esta oportunidad quiero compartir con ustedes un sencillo reloj basado en un


Microcontrolador PIC de la serie 16F84A y usando display nodo comn de 7 segmentos.

Adicionalmente usa otros circuitos con la finalidad de expander el nmero de salidas, tanto
para control como para datos, y de esa forma podemos contar con ms displays y ms
opciones de Configuracin. Entre estos circuitos tenemos el conocido 74LS47, de cul
dejar el esquema mostrando la disposicin de sus pines (Figura 1), as como su tabla de
verdad (Figura 2). Para mayor informacin pueden consultar el datasheet de este
componente.

Disposicin de pines


Tabla de Verdad


Otro circuit usado es el 74LS138, el cul funcionar como selector de display para realizar el efecto
de barrido. No detallar tampoco a este componente puesto que no es el objetivo de este post,
pero si dejar algunas imgenes, que al igual que las anteriores, nos da una vista rpida de la
disposicin y el funcionamiento de este integrado.

Disposicin de pines


Tabla de Verdad


Tambin dejar el diagrama de pines de un display de 7 segmentos.


Ahora, una vez conocido el funcionamiento de los componentes individuales, a continuacin
muestro el diagrama total del reloj, en donde veremos como estos integrados interactuan entre s
para poder obtener nuestro sencillo reloj digital.
Las resistencias que van a los displays son de 330 (Naranja, Naranja, Marrn) y las que van a los
transistores son de 1K (Marrn, Negro, Rojo). Y claro, las resistencias que van a los pulsadores
son de 10K (Marrn, Negro, Naranja).

Antes que nada tenemos que conectar los componentes bsicos para el funcionamiento del
microcontrolador pic, que son las conexiones a tierra y 5 voltios, el reloj de 4MHz y los capacitores.

Luego podemos armar el siguiente diagrama esquemtico para tener en funcionamiento a nuestro
sencillo Reloj Digital.

Archivos adjuntos del proyecto:

El cdigo est escritor en ensamblador. Pueden usar el mplab para recompilarlo y usarlo de
acuerdo a sus necesidades.
view plainprint?
1. __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
2. LIST P=16F84A
3. INCLUDE <P16F84A.INC>
4.
5. M_UNI equ H'1D' ; Registro para las unidades de los minutos.
6. M_DEC equ H'1C' ; Registro para las decenas de los minutos.
7.
8. H_UNI equ H'1F' ; Registro para las unidades de las horas.
9. H_DEC equ H'1E' ; Registro para las decenas de las horas.
10.
11. S_UNI equ H'20' ; Registro para las unidades de los segundos.
12. S_DEC equ H'21' ; Registro para las decenas de los segundos.
13.
14. BARR equ H'1B' ; Registro para almacenar el nmero de barridos.
15. PAUSE equ H'1A' ; Registro para almacenar el tiempo de barrido.
16.
17. ;Algunas definiciones de registros y pines
18. ;-----------------------------------------
19. #DEFINE REINICIO PORTA,0 ; Pulsador conectado a RA0.
20. #DEFINE MINUTO PORTA,1 ; Pulsador conectado a RA1.
21. #DEFINE HORA PORTA,2 ; Pulsador conectado a RA2.
22. #DEFINE DISPLAY PORTB ; El display est conectado al Puerto B.
23.
24. ORG 0
25.
26. Inicio
27. bsf STATUS,RP0 ; Acceso al Banco 1.
28. clrf DISPLAY ; Lnea del LED configurada como salida.
29. movlw b'00011111' ; Las 5 lneas del Puerto A se configuran como entrada.
30. movwf PORTA
31. bcf STATUS,RP0 ; Acceso al Banco 0.
32. ;Inicializacin de Registros
33. ;---------------------------
34. clrf S_UNI
35. clrf S_DEC
36. clrf M_UNI
37. clrf M_DEC
38. clrf H_UNI
39. clrf H_DEC
40. clrf BARR
41. ;---------------------------
42.
43. Principal
44. clrf BARR ; Limpiamos el registro de barridos
45. ;Para el botn de reinicio no importa los rebotes
46. ;------------------------------------------------
47. VerificarPulsadorReset
48. btfss REINICIO ; Pulsador reposo?, Pulsador=1?
49. call InicializarRegistros
50. ;------------------------------------------------------------------------------
51.
52. ;Para el botn de incremento de minutos si importan los rebotes
53. ;--------------------------------------------------------------
54. VerificarPulsadorMinutos
55. btfsc MINUTO ; Pulsador presionado?, (Pulsador)=0?
56. goto VerificarPulsadorHoras ; No vuelve a leerlo
57. call Temporizador ; Espera a que se estabilicen los niveles de tensin.
58. btfsc MINUTO ; Comprueba si es un rebote.
59. goto VerificarPulsadorHoras ; Era un rebote y sale.
60. goto SoloMinutosEnUno ; Salta a la subrutina para incrementar los minutos en 1
61. ;------------------------------------------------------------------------------
62.
63. ;Para el botn de incremento de horas tambin importan los rebotes
64. ;-----------------------------------------------------------------
65. VerificarPulsadorHoras
66. ;------------------------------------------------------------------------------
67. btfsc HORA ; Pulsador presionado?, (Pulsador)=0?
68. goto SoloSegundosEnUno ; No vuelve a leerlo
69. call Temporizador ; Espera a que se estabilicen los niveles de tensin.
70. btfsc HORA ; Comprueba si es un rebote.
71. goto SoloSegundosEnUno ; Era un rebote y sale fuera.
72. call SoloHorasEnUno
73. ;------------------------------------------------------------------------------
74.
75. SoloSegundosEnUno
76. call IncrementarSegundosEnUno
77.
78. Mostrar
79. call ValidarTiempo
80. call Barrido
81. ;------------------------------------------------------------------------------
82.
83. Fin
84. goto Principal
85. ;------------------------------------------------------------------------------
86.
87. SoloMinutosEnUno
88. call IncrementarMinutosEnUno
89. goto Mostrar
90.
91. SoloHorasEnUno
92. call IncrementarHorasEnUno
93. goto Mostrar
94.
95. ;*************************************
96. ; Subrutina de Incremento de Registros
97. ;*************************************
98.
99. ;------------------------------------------------------------------------------
100. IncrementarSegundosEnUno
101. incf S_UNI,f ; Incrementa el valor de S_UNI
102. movfw S_UNI ; Carga W con el valor del regustro S_UNI
103. sublw D'10' ; Resta 10 para verificar si S_UNI=10?
104. btfsc STATUS, Z ; Verifica si el resultado fu cero
105. call IncrementarSegundosEnDiez ; Si es cero, entonces acarreamos uno
106. return
107. ;------------------------------------------------------------------------------
108.
109. IncrementarSegundosEnDiez
110. clrf S_UNI ; El acarreo implica limpiar el registro anterior
111. incf S_DEC,f ; Incrementa el valor de S_DEC
112. movfw S_DEC ; Carga W con el valor del regustro S_DEC
113. sublw D'6' ; Resta 6 para verificar si S_UNI=6?
114. btfsc STATUS, Z ; Verifica si el resultado fu cero
115. call IncrementarMinutosEnUno ; Si es cero, entonces acarreamos uno
116. return
117. ;------------------------------------------------------------------------------
118.
119. IncrementarMinutosEnUno
120. clrf S_DEC ; El acarreo implica limpiar el registro anterior
121. incf M_UNI,f ; Incrementa el valor de M_UNI
122. movfw M_UNI ; Carga W con el valor del regustro M_UNI
123. sublw D'10' ; Resta 10 para verificar si S_UNI=10?
124. btfsc STATUS, Z ; Verifica si el resultado fu cero
125. call IncrementarMinutosEnDiez ; Si es cero, entonces acarreamos uno
126. return
127. ;------------------------------------------------------------------------------
128.
129. IncrementarMinutosEnDiez
130. clrf M_UNI ; El acarreo implica limpiar el registro anterior
131. incf M_DEC,f ; Incrementa el valor de M_DEC
132. movfw M_DEC ; Carga W con el valor del regustro M_DEC
133. sublw D'6' ; Resta 6 para verificar si S_UNI=6?
134. btfsc STATUS, Z ; Verifica si el resultado fu cero
135. call IncrementarHorasEnUno ; Si es cero, entonces acarreamos uno
136. return
137. ;------------------------------------------------------------------------------
138.
139. IncrementarHorasEnUno
140. clrf M_DEC ; El acarreo implica limpiar el registro anterior
141. incf H_UNI,f ; Incrementa el valor de H_UNI
142. movfw H_UNI ; Carga W con el valor del regustro H_UNI
143. sublw D'10' ; Resta 6 para verificar si S_UNI=10?
144. btfsc STATUS, Z ; Verifica si el resultado fu cero
145. call IncrementarHorasEnDiez ; Si es cero, entonces acarreamos uno
146. return
147. ;------------------------------------------------------------------------------
148.
149. IncrementarHorasEnDiez
150. clrf H_UNI ; El acarreo implica limpiar el registro anterior
151. incf H_DEC,f ; Incrementa el valor de H_DEC
152. movfw H_DEC ; Carga W con el valor del regustro H_DEC
153. sublw D'10' ; Resta 6 para verificar si S_UNI=10?
154. btfsc STATUS, Z ; Verifica si el resultado fu cero
155. clrf H_DEC ; Si es cero, entonces acarreamos uno
156. return
157. ;------------------------------------------------------------------------------
158.
159. ;*********************************
160. ; Subrutina de Barrido de Displays
161. ;*********************************
162.
163. ;------------------------------------------------------------------------------
164.
165. Barrido
166. btfss REINICIO ; Pulsador reposo?, Pulsador=1?
167. call InicializarRegistros
168. incf BARR, f ; Incrementa en 1 el registro de barridos
169. ;Unidades de segundos
170. ;--------------------
171. movlw b'00001111' ; Activamos el primer display
172. movwf DISPLAY ; Movemos el dato al puerto B
173. movf S_UNI,0 ; Mueve M_UNI al registro W
174. iorlw b'00000000' ; Aplicamos la mscara
175. movwf DISPLAY ; Mostramos en el puerto B
176. call Temporizador ; Pausa para establecer niveles de tensin correctamente
177. movlw B'00001111' ; Cargamos el valor adecuado a W para limpiar los registros
178. movwf DISPLAY ; Limpiamos el display para evitar que los dgitos se repitan
179. ;------------------------------------------------------------------------------
180. ;Decenas de segundos
181. movlw b'00011111' ; Activamos el segundo display
182. movwf DISPLAY ; Movemos el dato al puerto B
183. movf S_DEC,0 ; Mueve S_DEC al registro W
184. iorlw b'00010000' ; Aplicamos la mscara
185. movwf DISPLAY ; Mostramos en el puerto B
186. call Temporizador ; Pausa para establecer niveles de tensin correctamente
187. movlw B'00011111' ; Cargamos el valor adecuado a W para limpiar los registros
188. movwf DISPLAY ; Limpiamos el display para evitar que los dgitos se repitan
189. ;------------------------------------------------------------------------------
190. ;Unidades de minutos
191. movlw b'00101111' ; Activamos el tercer display
192. movwf DISPLAY ; Movemos el dato al puerto B
193. movf M_UNI,0 ; Mueve M_UNI al registro W
194. iorlw b'00100000' ; Aplicamos la mscara
195. movwf DISPLAY ; Mostramos en el puerto B
196. call Temporizador ; Pausa para establecer niveles de tensin correctamente
197. movlw B'00101111' ; Cargamos el valor adecuado a W para limpiar los registros
198. movwf DISPLAY ; Limpiamos el display para evitar que los dgitos se repitan
199. ;------------------------------------------------------------------------------
200. ;Decenas de minutos
201. movlw b'00111111' ; Activamos el cuarto display
202. movwf DISPLAY ; Movemos el dato al puerto B
203. movf M_DEC,0 ; Mueve M_UNI al registro W
204. iorlw b'00110000' ; Aplicamos la mscara
205. movwf DISPLAY ; Mostramos en el puerto B
206. call Temporizador ; Pausa para establecer niveles de tensin correctamente
207. movlw B'00111111' ; Cargamos el valor adecuado a W para limpiar los registros
208. movwf DISPLAY ; Limpiamos el display para evitar que los dgitos se repitan
209. ;------------------------------------------------------------------------------
210. ;Unidades de horas
211. movlw b'01001111' ; Activamos el quinto display
212. movwf DISPLAY ; Movemos el dato al puerto B
213. movf H_UNI,0 ; Mueve M_UNI al registro W
214. iorlw b'01000000' ; Aplicamos la mscara
215. movwf DISPLAY ; Mostramos en el puerto B
216. call Temporizador ; Pausa para establecer niveles de tensin correctamente
217. movlw B'01001111' ; Cargamos el valor adecuado a W para limpiar los registros
218. movwf DISPLAY ; Limpiamos el display para evitar que los dgitos se repitan
219. ;------------------------------------------------------------------------------
220. ;Decenas de horas
221. movlw b'01011111' ; Activamos el sexto display
222. movwf DISPLAY ; Movemos el dato al puerto B
223. movf H_DEC,0 ; Mueve M_UNI al registro W
224. iorlw b'01010000' ; Aplicamos la mscara
225. movwf DISPLAY ; Mostramos en el puerto B
226. call Temporizador ; Pausa para establecer niveles de tensin correctamente
227. movlw B'01011111' ; Cargamos el valor adecuado a W para limpiar los registros
228. movwf DISPLAY ; Limpiamos el display para evitar que los dgitos se repitan
229. ;------------------------------------------------------------------------------
230. ;Verificar barrido
231. movfw BARR ; carga W con el nmero de barridos
232. sublw D'50' ; Resta 50 para comparar si es igual a 50
233. btfsc STATUS, Z ; Verifica si el resultado fu 0, o sea si BARR=50?
234. return ; Se complet el nmero de barridos
235. goto Barrido
236. ;------------------------------------------------------------------------------
237.
238. ValidarTiempo
239. movfw H_UNI ; Carga el registro W con el valor del registro H_UNI
240. sublw D'4' ; Resta 4 para verificar si es que el valor de W=4?
241. btfsc STATUS, Z ; Verifica si el resultado fu cero
242. goto ValidarHora ; Ahora llamamos al subrutina para verificar el siguiente dgito d
e la hora
243. return
244. ;------------------------------------------------------------------------------
245.
246. ValidarHora
247. movfw H_DEC ; Carga el registro W con el valor del registro H_DEC
248. sublw D'2' ; Resta 2 para verificar si es que el valor de W=2?
249. btfsc STATUS, Z ; Verifica si el resultado fu cero
250. goto InicializarRegistros ; Al llamar a esta subrutina quiere decir que la hora=24, lo
cul implica un reinicio
251. return
252. ;------------------------------------------------------------------------------
253.
254. InicializarRegistros
255. clrf S_UNI
256. clrf S_DEC
257. clrf M_UNI
258. clrf M_DEC
259. clrf H_UNI
260. clrf H_DEC
261. return
262. ;------------------------------------------------------------------------------
263.
264. Temporizador
265. movlw D'255' ; w = 50 decimal
266. movwf PAUSE ; K = w
267.
268. Kloop
269. decfsz PAUSE,f ; K = K - 1 , salta a la siguiente instruccin si es cero.
270. goto Kloop
271. return
272. ;------------------------------------------------------------------------------
273.
274. END ; Fin del programa.

Vous aimerez peut-être aussi