Está en la página 1de 22

PRACTICA 1

TIMER 0 “MANEJO DE UNA PANTALLA LCD”


(RELOJ DE TIEMPO REAL).

Microelectrónica Programable

Vazquez Carrasco Fernando

6IM1
Objetivos

El alumno comprende la operación y configuración del timer 0 así como el


Manejo de una LCD de 16 caracteres x 1 línea, El funcionamiento de la LCD 16x1
además de diseñar e implementar un programa por medio del cual se pueda
visualizar un temporizador en el LCD de 16x1. Controlar el LCD de 16x1 por medio
del PIC16F877A para poder visualizar el temporizado.

Desarrollo teórico

Timer 0 y manejo de una LCD

El Timer0 es un temporizador/contador ascendente de 8 bits, cuando trabaja con el


reloj del PIC se le suele llama temporizador y cundo los pulsos los recibe de una
fuente externa a través de la patilla RA4/TOCKI se le llama contador, pero
digamos que es el mismo perro con dos collares diferentes. Para no liarnos con
las patillas y el nombre de los registros voy a mostrar los registros y patillas
implicadas solo en el TMR0 utilizando el PIC16f84, aunque podría ser otro
cualquiera ya que este temporizador viene incorporado en todos los PIC.

RA4/TOCKI: cuando el temporizador trabaje como contador, los pulsos externos


los recibirá a través de esta patilla.OSC1/CLKIN y OSC2/CLKOUT: son para
conectar el oscilador que nos determinará a la frecuencia que va a trabajar nuestro
PIC, los dos tipos de osciladores más usados son el XT(cristal de cuarzo) y el RC
(resistencia y condensador).

La siguiente figura muestra el esquema del temporizador Timer0 con todos los bits
que determinan su funcionamiento. Estos bits se almacenan en el registro
OPTION_REG.

Registro OPTION_REG

• RBPU - PORTB Pull-up enable bit (resistencia Pull Up del puerto PORTB)
• 0 - Resistencias pull-up del puerto PORTB están deshabilitadas.
• 1 - Pines del puerto PORTB pueden estar conectados a las resistencias pull-up.
• INTEDG - Interrupt Edge Select bit (bit selector de flanco activo de la interrupción externa)
• 0 - Interrupción por flanco ascendente en el pin INT (0-1).
• 1 - Interrupción por flanco descendente en el pin INT (1-0).
• T0CS - TMR0 Clock Select bit (bit selector de tipo de reloj para el Timer0)
• 0 - Los pulsos se llevan a la entrada del temporizador/contador Timer0 por el pin RA4.
• 1 - El temporizador utiliza los pulsos de reloj internos (Fosc/4).
• T0SE - TMR0 Source Edge Select bit (bit selector de tipo de flanco)
• 0 - Incrementa en flanco descendente en el pin TMR0.
• 1 - Incrementa en flanco ascendente en el pin TMR0.
• PSA - Prescaler Assignment bit (bit de asignación del pre-escalador)
• 0 - Pre-escalador se le asigna al WDT.
• 1 - Pre-escalador se le asigna al temporizador/contador Timer0.
• PS2, PS1, PS0 - Prescaler Rate Select bit (bit selector del valor del divisor de frecuencias)
• El valor del divisor de frecuencias se ajusta al combinar estos bits. Como se muestra en la
tabla a la derecha, la misma combinación de bits proporciona los diferentes valores del
divisor de frecuencias para el temporizador/contador y el temporizador perro guardián,
respectivamente.

Cuando el bit PSA está a 0, el pre-escalador se le asigna al


temporizador/contador Timer0, como se muestra en la siguiente figura.
Cuando el bit PSA está a 1, el pre-escalador se le asigna al temporizador perro
guardián como se muestra en la siguiente figura.

Aparte de lo dicho anteriormente, cabe destacar lo siguiente:

• Al asignarle el pre-escalador al temporizador/contador, el pre-escalador se pondrá a 0 con


cualquier escritura en el registro TMR0.
• Al asignar el pre-escalador al temporizador perro guardián, tanto el WDT como el
preescalador se pondrán a 0 con la instrucción CLRWDT.
• Al escribir en el registro TMR0, utilizado como un temporizador, no se inicia el
conteo de los pulsos inmediatamente, sino con retraso de dos ciclos de
instrucciones. Por consiguiente, es necesario ajustar el valor escrito en el registro
TMR0.
• Al poner el microcontrolador en el modo de reposo se apaga el oscilador de reloj.
No puede ocurrir el desbordamiento ya que no hay pulsos a contar. Es la razón
por la que la interrupción por el desbordamiento del TMR0 no puede“despertar” al
procesador del modo de reposo.
• Si se utiliza como un contador de reloj externo sin pre-escalador, la longitud de
pulso mínima o tiempo muerto entre dos pulsos deberá ser 2 Tosc + 20 nS (Tosc
es el período de señal de reloj del oscilador).
• Si se utiliza como un contador de reloj externo con pre-escalador, la longitud de
pulso mínima o tiempo muerto entre dos pulsos es sólo 10nS.
• El registro del pre-escalador de 8 bits no está disponible al usuario, lo que significa
que no es posible leerlo o escribir en él directamente.
• Al cambiar de asignación del pre-escalador del Timer0 al temporizador perro
guardián, es necesario ejecutar la siguiente secuencia de instrucciones escritas en
ensamblador para impedir reiniciar el microcontrolador

• Para utilizar el Timer0 apropiadamente, es necesario: Paso 1: Seleccionar el


modo:
• El modo de temporizador se selecciona por el bit TOSC del registro OPTION_REG
(TOSC: 0=temporizador, 1=contador).
• Cuando se asigna el pre-escalador al temporizador/contador se debe poner a cero
el bit PSA del registro OPTION_REG. El valor del divisor de frecuencias se
configura al utilizar los bits PS2-PS0 del mismo registro.
• Al utilizar una interrupción, los bits GIE y TMR0IE del registro INTCON deben estar
a uno.
Paso 2: Medir y contar Para medir tiempo:
• Reiniciar el registro TMR0 o escribir un valor conocido en él.
• El tiempo transcurrido(en microsegundos al utilizar el oscilador de 4MHz) se mide
al leer el registro TMR0.
• El bit de bandera TMR0IF del registro INTCON se pone a uno automáticamente
siempre que ocurra el desbordamiento del registro TMR0. Si está habilitada,
ocurre una interrupción.
Para contar pulsos:
• La polaridad de pulsos a contar en el pin RA4 se selecciona por el bit TOSE del
registro OPTION_REG (T0SE: 0=pulsos positivos, 1=pulsos negativos).
• Varios pulsos se pueden leer del registro TMR0. El pre-escalador y la interrupción
se utilizan de la misma forma que en el modo de temporizador.

LCD

Es una pantalla de cristal líquido o LCD es una pantalla delgada y plana formada por un
número de píxeles en color o monocromos colocados delante de una fuente de luz o
reflectora. A menudo se utiliza en dispositivos electrónicos de pilas, ya que utiliza cantidades
muy pequeñas de energía eléctrica.

Cada píxel de un LCD típicamente consiste en una capa de moléculas alineadas entre
dos electrodos transparentes, y dos filtros de polarización, los ejes de transmisión de cada uno
que están (en la mayoría de los casos) perpendiculares entre sí. Sin cristal líquido entre el
filtro polarizante, la luz que pasa por el primer filtro sería bloqueada por el segundo (cruzando)
polarizador.
La superficie de los electrodos que están en contacto con los materiales de cristal líquido es
tratada a fin de ajustar las moléculas de cristal líquido en una dirección en particular. Este
tratamiento suele ser normalmente aplicable en una fina capa de polímero que es
unidireccionalmente frotada utilizando, por ejemplo, un paño. La dirección de la alineación de
cristal líquido se define por la dirección de frotación.

La pantalla de LCD 16 x 1 (la que ocuparemos) es módulo muy básico y es muy


usada en varios dispositivos y circuitos. Estos módulos son preferibles en siete
segmentos. Las razones están: LCDs son económicos; fácilmente programable;
no tienen ninguna limitación de visualizar los caracteres especiales y hasta
personalizables (a diferencia de en siete segmentos), animaciones y así
sucesivamente. 16 x 1 en el LCD significa que puede mostrar 16 caracteres por
línea y hay una línea. En esta pantalla cada carácter se muestra en la matriz de 5
x 7 píxeles. Este LCD tiene dos registros, es decir, comandos ydatos. El registro
de comando almacena las instrucciones de mando a la pantalla LCD. Un comando
es una instrucción dada al LCD una tarea predefinida como inicializarlo claro de su
pantalla, ajuste la posición del cursor, controlar etc. El registro de datos almacena
los datos que se mostrará en la pantalla LCD. Los datos están el valor ASCII del
carácter que se mostrará en la pantalla LCD

Código ASCII

Pines
Microcontrolador PIC16F877A

Este potente microcontrolador de 8 bits basado en FLASH CMOS (ejecución de


instrucciones de 200 nanosegundos) pero fácil de programar (solo 35 instrucciones de
una sola palabra) incluye la potente arquitectura PIC® de Microchip en un paquete de 40
o 44 pines y es compatible hacia arriba con el Dispositivos PIC16C5X, PIC12CXXX y
PIC16C7X. El PIC16F877A cuenta con 256 bytes de memoria de datos EEPROM,
autoprogramación, un ICD, 2 comparadores, 8 canales de convertidor analógico a digital
(A/D) de 10 bits, 2 funciones de captura/comparación/PWM, el puerto serial síncrono
puede configurarse como interfaz periférica en serie de 3 hilos (SPI™) o como bus de
circuito interintegrado (I²C™) de 2 hilos y un transmisor receptor asíncrono universal
(USART). Todas estas características lo hacen ideal para aplicaciones A/D de nivel más
avanzado en aplicaciones automotrices, industriales, de electrodomésticos y de consumo
Datasheet del LCD 16x1
Esquemático

Puesto en marcha
Código del microcontrolador

1. ;INSTITUTO POLITECNICO NACIONAL.


2. ;CECYT 9 JUAN DE DIOS BATIZ.
3. ;
4. ;MANEJO DE UNA LCD.
5. ;
6. ;GRUPO: 6IM1.
7. ;
8. ;INTEGRANTES:
9. ;1.- Vazquez Carrasco Fernando
10. ;
11. ;reloj de tiempo real con Timer 0.
12. ;---------------------------------------------------------------------------------------------
13.
14. list p=16f877A;
15.
16. ;#include "c:\archivos de programa\microchip\mpasm suite\p16f877a.inc";
17. #include "c:\program files (x86)\microchip\mpasm suite\p16f877a.inc";
18.
19. ;Bits de configuración.
20. __config _XT_OSC & _WDT_OFF & _PWRTE_ON & _BODEN_OFF & _LVP_OFF & _CP_OFF;
ALL
21. ;---------------------------------------------------------------------------------------------
22. ;
23. ;fosc = 4 Mhz.
24. ;Ciclo de trabajo del PIC = (1/fosc)*4 = 1 µs.
25. ;t int =(256-R)*(P)*((1/3579545)*4) = 1 ms ;// Tiempo de interrupcion.
26. ;R=131, P=8.
27. ;frec int = 1/ t int = 1KHz.
28. ;---------------------------------------------------------------------------------------------
29. ;
30. ; Registros de proposito general Banco 0 de memoria RAM.
31. ;
32. ; Registros propios de estructura del programa
33.
34. resp_w equ 0x20;
35. resp_status equ 0x21;
36. res_pclath equ 0x22;
37. res_fsr equ 0x23;
38. presc_1 equ 0x24; .001 100 5
39. presc_2 equ 0x25; t int = t intb * presc_1 * presc_2
40. banderas equ 0x26;
41. cont_milis equ 0x27;
42. uni_seg equ 0x28;
43. dec_seg equ 0x29;
44. uni_min equ 0x2a;
45. dec_min equ 0x2b;
46. uni_hor equ 0x2c;
47. dec_hor equ 0x2d;
48. uniseg_Ascii equ 0x2e;
49. decseg_Ascii equ 0x2f;
50. unimin_Ascii equ 0x30;
51. decmin_Ascii equ 0x31;
52. unihor_Ascii equ 0x32;
53. dechor_Ascii equ 0x33;
54. ;---------------------------------------------------------------------------------------------
55. ;Def. de constantes a utilizar.
56. ;Cod. de caracteres alfanuméricos en 7 segmentos.
57. Car_A equ b'01110111';
58. Car_b equ 0xc7;
59. Car_0 equ 0x3f;
60. Car_1 equ 0x06;
61.
62. dig5_LCD equ 0x84;
63.
64. ;banderas del registro banderas.
65. ban_int equ .0; //
66. sin_bd1 equ .1;
67. sin_bd2 equ .2;
68. sin_bd3 equ .3;
69. sin_bd4 equ .4;
70. sin_bd5 equ .5;
71. sin_bd6 equ .6;
72. sin_bd7 equ .7;
73. ;---------------------------------------------------------------------------------------------
74. ;
75. ;Asignaciòn de los bits de los puertos de I/O.
76. ;Puerto A.
77. RS_LCD equ .0; // Señal de control Comando o dato de la LCD.
78. Enable_LCD equ .1; // Señal de ingreso de informacion a la LCD.
79. Sin_UsoRA2 equ .2; // Sin Uso RA2.
80. Sin_UsoRA3 equ .3; // Sin Uso RA3.
81. Led_Rojo equ .4; // Led de op.
82. Sin_UsoRA5 equ .5; // Sin Uso RA5.
83.
84. proga equ b'101100'; // Programaciòn inicial del puerto A.
85.
86. ;Puerto B.
87. Sin_UsoRB0 equ .0; // Sin Uso RB0.
88. Sin_UsoRB1 equ .1; // Sin Uso RB1.
89. Sin_UsoRB2 equ .2; // Sin Uso RB2.
90. Sin_UsoRB3 equ .3; // Sin Uso RB3.
91. Sin_UsoRB4 equ .4; // Sin Uso RB4.
92. Sin_UsoRB5 equ .5; // Sin Uso RB5.
93. Sin_UsoRB6 equ .6; // Sin Uso RB6.
94. Sin_UsoRB7 equ .7; // Sin Uso RB7.
95.
96. progb equ b'11111111'; // Programaciòn inicial del puerto B.
97.
98. ;Puerto C.
99. D0_LCD equ .0; // Bit D0 de la LCD.
100. D1_LCD equ .1; // Bit D1 de la LCD.
101. D2_LCD equ .2; // Bit D2 de la LCD.
102. D3_LCD equ .3; // Bit D3 de la LCD.
103. D4_LCD equ .4; // Bit D4 de la LCD.
104. D5_LCD equ .5; // Bit D5 de la LCD.
105. D6_LCD equ .6; // Bit D6 de la LCD.
106. D7_LCD equ .7; // Bit D7 de la LCD.
107.
108. progc equ b'00000000'; // Programaciòn inicial del puerto C como entrada.
109.
110. ;Puerto D.
111. Sin_UsoRD0 equ .0; // Sin Uso RD0.
112. Sin_UsoRD1 equ .1; // Sin Uso RD1.
113. Sin_UsoRD2 equ .2; // Sin Uso RD2.
114. Sin_UsoRD3 equ .3; // Sin Uso RD3.
115. Sin_UsoRD4 equ .4; // Sin Uso RD4.
116. Sin_UsoRD5 equ .5; // Sin Uso RD5.
117. Sin_UsoRD6 equ .6; // Sin Uso RD6.
118. Sin_UsoRD7 equ .7; // Sin Uso RD7.
119.
120. progd equ b'11111111'; // Programaciòn inicial del puerto D como entradas.
121.
122. ;Puerto E.
123. Sin_UsoRE0 equ .0; // Sin Uso RE0.
124. Sin_UsoRE1 equ .1; // Sin Uso RE1.
125. Sin_UsoRE2 equ .2; // Sin Uso RE2.
126.
127. proge equ b'111'; // Programaciòn inicial del puerto E.
128. ;---------------------------------------------------------------------------------------------
129.
130. ;====================
131. ;== Vector reset ==
132. ;====================
133. org 0x0000;
134. vec_reset clrf pclath;
135. goto prog_prin;
136. ;---------------------------------------------------------------------------------------------
137.
138. ;==============================
139. ;== Vector de interrupcion ==
140. ;==============================
141. org 0x0004;
142. vec_int movwf resp_w;resp. el estado del reg. w.
143. movf status,w;
144. movwf resp_status;resp. banderas de la alu.
145. clrf status;
146. movf pclath,w;
147. movwf res_pclath;
148. clrf pclath;
149. movf fsr,w;
150. movwf res_fsr;
151.
152. btfsc intcon,tmr0if;
153. call rutina_int;
154.
155. sal_int movlw .131;
156. movwf tmr0;
157.
158. movf res_fsr,w;
159. movwf fsr;
160. movf res_pclath,w;
161. movwf pclath;
162. movf resp_status,w;
163. movwf status;
164. movf resp_w,w;
165.
166. retfie;
167. ;---------------------------------------------------------------------------------------------
168.
169. ;==================================
170. ;== Subrutina de Interrupciones ==
171. ;==================================
172. rutina_int incf cont_milis,f;
173. ; 100 5
174. incf presc_1,f; t int = t intb * presc_1 * presc_2
175.
176. movlw .100;
177. xorwf presc_1,w;
178. btfsc status,z;
179. goto sig_int;
180. goto sal_rutint;
181.
182. sig_int clrf presc_1;
183. incf presc_2,f;
184. movlw .10;
185. xorwf presc_2,w;
186. btfss status,z;
187. goto sal_rutint;
188. clrf presc_1;
189. clrf presc_2;
190.
191. sal_rutext bsf banderas,ban_int;
192.
193. sal_rutint bcf intcon,t0if;
194. return;
195. ;---------------------------------------------------------------------------------------------
196.
197. ;===========================
198. ;== Subrutina de inicio ==
199. ;===========================
200. prog_ini bsf status,RP0; Ponte en el banco 1 de ram.
201. movlw 0x82;
202. movwf option_reg ^0x80;
203. movlw proga;
204. movwf trisa ^0x80;
205. movlw progb;
206. movwf trisb ^0x80;
207. movlw progc;
208. movwf trisc ^0x80;
209. movlw progd;
210. movwf trisd ^0x80;
211. movlw proge;
212. movwf trise ^0x80;
213. movlw 0x06;
214. movwf adcon1 ^0x80;
215. bcf status,RP0; Ponte en el banco 0 de ram.
216.
217. movlw 0xa0;
218. movwf intcon;
219.
220. movlw .131;
221. movwf tmr0;
222.
223. clrf banderas;
224.
225. clrf portc;
226. movlw 0x03;
227. movwf porta;
228.
229. clrf resp_w;
230. clrf resp_status;
231. clrf res_pclath;
232. clrf res_fsr;
233. clrf presc_1;
234. clrf presc_2;
235. clrf banderas;
236. clrf cont_milis;
237. clrf uni_seg;
238. clrf dec_seg;
239. clrf uni_min;
240. clrf dec_min;
241. clrf uni_hor;
242. clrf dec_hor;
243.
244. return;
245. ;---------------------------------------------------------------------------------------------
246.
247. ;==========================
248. ;== Programa principal ==
249. ;==========================
250. prog_prin call prog_ini;
251.
252. call ini_lcd;
253.
254. call ini_time;
255. Loop_prin call esp_int;
256. call Cuenta_tiempo;
257. call Arma_tiempo;
258. call Muestra_tiempo;
259.
260. goto Loop_prin;
261. ;---------------------------------------------------------------------------------------------
262.
263. ;=================================================
264. ;== Subrutina de espera de int. de 0.5 segundo ==
265. ;=================================================
266. esp_int nop;
267. btfss banderas,ban_int;
268. goto esp_int;
269. bcf banderas,ban_int;
270.
271. return;
272. ;--------------------------------------------------------------------------------------------------
273.
274. ;=====================================
275. ;== Subrutina de cuenta de tiempo ==
276. ;=====================================
277. Cuenta_tiempo incf uni_seg,f;
278.
279. movlw .10;
280. subwf uni_seg,w;
281. btfss status,Z;
282. goto salte_cta;
283.
284. clrf uni_seg;
285. incf dec_seg,f;
286. movlw .6;
287. subwf dec_seg,w;
288. btfss status,Z;
289. goto salte_cta;
290. clrf uni_seg;
291. clrf dec_seg;
292.
293. salte_cta return;
294. ;--------------------------------------------------------------------------------------------------
295.
296. ;======================================
297. ;== Subrutina de armado del tiempo ==
298. ;======================================
299. Arma_tiempo movf uni_seg,w;
300. addlw 0x30;
301. movwf uniseg_Ascii;
302.
303. movf dec_seg,w;
304. addlw 0x30;
305. movwf decseg_Ascii;
306.
307. return;
308. ;--------------------------------------------------------------------------------------------------
309.
310. ;=============================================
311. ;== Subrutina muestra el tiempo en la LCD ==
312. ;=============================================
313. Muestra_tiempo bcf porta,RS_LCD; coloca la LCD en Formato comandos
314. movlw 0x8a;
315. movwf portc;
316. call pulso_enable;
317.
318. bsf porta,RS_LCD;
319. movf decseg_Ascii,w;
320. movwf portc;
321. call pulso_enable;
322.
323. movf uniseg_Ascii,w;
324. movwf portc;
325. call pulso_enable;
326.
327. return;
328. ;--------------------------------------------------------------------------------------------------
329.
330. ;=============================================
331. ;== Subrutina de inicialización del tiempo en la LCD ==
332. ;=============================================
333. ini_time bcf porta,RS_LCD; coloca la LCD en Formato comandos
334. movlw 0x84;
335. movwf portc;
336. call pulso_enable;
337.
338. bsf porta,RS_LCD;
339. movlw '0';
340. movwf portc;
341. call pulso_enable;
342. movlw '0';
343. movwf portc;
344. call pulso_enable;
345. movlw ':';
346. movwf portc;
347. call pulso_enable;
348. movlw '0';
349. movwf portc;
350. call pulso_enable;
351. movlw '0';
352. movwf portc;
353. call pulso_enable;
354. movlw ':';
355. movwf portc;
356. call pulso_enable;
357. movlw '0';
358. movwf portc;
359. call pulso_enable;
360. movlw '0';
361. movwf portc;
362. call pulso_enable;
363.
364. return;
365. ;--------------------------------------------------------------------------------------------------
366.
367. ;===================================
368. ;== Subrutina de inicialización de la LCD ==
369. ;===================================
370. ini_lcd bcf porta,RS_LCD; coloca la lcd en formato comandos
371.
372. movlw 0x38;
373. movwf portc;
374. call pulso_enable;
375. movlw 0x0c;
376. movwf portc;
377. call pulso_enable;
378. movlw 0x01;
379. movwf portc;
380. call pulso_enable;
381. movlw 0x06;
382. movwf portc;
383. call pulso_enable;
384. movlw 0x80;
385. movwf portc;
386. call pulso_enable;
387.
388. bsf porta,RS_LCD;
389.
390. return;
391. ;---------------------------------------------------------------------------------------------
392.
393. ;======================================
394. ;== Subrutina de retardo de medio segundo ==
395. ;======================================
396. pulso_enable bcf porta,Enable_LCD;
397. call retardo_1ms;
398. bsf porta,Enable_LCD;
399.
400. call ret_40ms;
401.
402. return;
403. ;---------------------------------------------------------------------------------------------
404.
405. ;=====================================
406. ;== Subrutina de retardo de 1 mili segundo ==
407. ;=====================================
408. retardo_1ms clrf cont_milis;
409. esp_int1ms movlw .1;
410. subwf cont_milis,w;
411. btfss status,Z;
412. goto esp_int1ms;
413.
414. return;
415. ;---------------------------------------------------------------------------------------------
416.
417. ;================================================
418. ;== Subrutina de retardo de 40 mili segundos ==
419. ;================================================
420. ret_40ms clrf cont_milis;
421. esp_int40ms movlw .40;
422. subwf cont_milis,w;
423. btfss status,Z;
424. goto esp_int40ms;
425.
426. return;
427. ;---------------------------------------------------------------------------------------------
428.
429. end
Conclusiones
Con esta práctica desarrollamos dos conocimientos, las interrupciones principalmente el Timer 0,
además de utilizar una pantalla LCD 16x1 el cual es como una evolución a uso de un conjunto de
displays.

Cabe aclarar que el funcionamiento del circuito es similar al de una práctica que realizamos en el
semestre anterior, sin embargo tenemos algunas modificaciones, como el hecho de utilizar
interrupciones en lugar de retardos, y otra es implementar el LCD que funciona usando el código
ASCII para mostrar en la pantalla los caracteres que queramos (en este caso serían los numero y el
– para la separación de las horas, minutos y segundos). Eso evitando la conexión de múltiples
displays facilitando armado y con una mayor cantidad de posibilidades como lo es imprimir texto
de forma correcta si la limitantes de los displays.

También podría gustarte