Laboratorio Del Reloj
Laboratorio Del Reloj
Laboratorio Del Reloj
Resumen — Se realizó un reloj digital compuesto por una estos pines son identificados como TxCKI donde x es el
pantalla LCD 16x2, interruptores que permiten al usuario setear número temporizador contador PIC que será usado como
la hora del reloj, y un microcontrolador PIC16F877A que por contador.
medio del desbordamiento del temporizador TMR0 e
implementando una respectiva ecuación para calcular el tiempo El PIC16F877A tiene 3 temporizadores que son llamados
entre interrupciones se hace un preciso control en incremento de
timer0, timer1 y timer2, el tiempo que tarda el temporizador
los segundos con respecto a la vida real.
contador PIC en aumentar su valor de unidad en unidad, se
puede modificar por programa mediante el uso de prescalers,
Palabras clave — TMR0, Preescaler, Desbordamiento de
TIMER, Reloj digital. siendo de esta manera más provechoso.
● Fuente de alimentación DC
La figura 1 muestra los valores que hay que asignar a estos ● Multímetro
bits para obtener los diferentes valores de los prescaler para
el timer0 PIC. Se realizó la implementación (Fig.3) y programación
necesarias para lograr la visualización de un reloj digital en
una pantalla LCD 16x2, este está regulado por las
interrupciones generadas por el temporizador TMR0 del
PIC16F877A, el cual se logró con el código que se muestra a
continuación este código incluye una librería (Header)
utilizada para la LCD.
#define RS RD2
#define EN RD3
#define D4 RD4
#define D5 RD5
#define D6 RD6
Fig.2. Valor adecuado para cargar en TMR0. #define D7 RD7
void Lcd_Port(char a)
{
III. PROCEDIMIENTO Y DATOS EXPERIMENTALES if(a & 1)
D4 = 1;
Materiales: else
D4 = 0;
● 1 microcontrolador (PIC16F877A) if(a & 2)
● Teclado matricial 4x4 D5 = 1;
● 3 pulsadores else
D5 = 0;
● 1 Cristales de cuarzo de 4 MHz
● 2 condensadores cerámicos de 15 pf if(a & 4)
● LCD 16x2 D6 = 1;
else EN = 1;
D6 = 0; __delay_us(40);
EN = 0;
if(a & 8) Lcd_Port(temp);
D7 = 1; EN = 1;
else __delay_us(40);
D7 = 0; EN = 0;
} }
void Lcd_Cmd(char a)
{ void lcd_putc(char *a)
RS = 0; // => RS = 0 {
Lcd_Port(a); int i;
EN = 1; // => E = 1 for(i=0;a[i]!='\0';i++)
__delay_ms(4); lcd_write_char(a[i]);
EN = 0; // => E = 0 }
}
void lcd_shift_right()
lcd_clear() {
{ Lcd_Cmd(0x01);
Lcd_Cmd(0); Lcd_Cmd(0x0C);
Lcd_Cmd(1); }
}
void lcd_shift_left()
void lcd_gotoxy(char a, char b) {
{ Lcd_Cmd(0x01);
char temp,z,y; Lcd_Cmd(0x08);
if(a == 1) }
{
temp = 0x80 + b - 1; // TODO Insert appropriate #include <>
z = temp>>4;
y = temp & 0x0F; // TODO Insert C++ class definitions if appropriate
Lcd_Cmd(z);
Lcd_Cmd(y); // TODO Insert declarations
}
else if(a == 2) // Comment a function and leverage automatic documentation with slash
{ star star
temp = 0xC0 + b - 1; /**
z = temp>>4; <p><b>Function prototype:</b></p>
y = temp & 0x0F;
Lcd_Cmd(z); <p><b>Summary:</b></p>
Lcd_Cmd(y);
} <p><b>Description:</b></p>
}
<p><b>Precondition:</b></p>
void lcd_init()
{ <p><b>Parameters:</b></p>
Lcd_Port(0x00);
__delay_ms(20); <p><b>Returns:</b></p>
Lcd_Cmd(0x03);
__delay_ms(5); <p><b>Example:</b></p>
Lcd_Cmd(0x03); <code>
__delay_ms(11);
Lcd_Cmd(0x03); </code>
/////////////////////////////////////////////////////
Lcd_Cmd(0x02); <p><b>Remarks:</b></p>
Lcd_Cmd(0x02); */
Lcd_Cmd(0x08); // TODO Insert declarations or function prototypes (right here) to leverage
Lcd_Cmd(0x00); // live documentation
Lcd_Cmd(0x0C);
Lcd_Cmd(0x00);
Lcd_Cmd(0x06);
} #endif /* XC_HEADER_TEMPLATE_H */
void lcd_write_char(char a)
{ Código XC8 para el reloj
char temp,y;
temp = a&0x0F; #pragma config FOSC = XT // Oscillator Selection bits (XT oscillator)
y = a&0xF0; #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT
RS = 1; // => RS = 1 enabled)
Lcd_Port(y>>4); //Data transfer #pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT
disabled) lcd_gotoxy(2,1); //Ubicamos el cursor en fila2, columna 1
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR sprintf(arreglo_lcd," %d : %d : %d ",horas, minutos, segundos);
enabled) lcd_putc(arreglo_lcd); //Mostramos el valor de buffer_lcd
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit if(PORTBbits.RB5==0){
Serial Programming Enable bit (RB3/PGM pin has PGM function; horas++;
low-voltage programming enabled) __delay_ms(500);
#pragma config CPD = OFF // Data EEPROM Memory Code Protection if(horas==24){horas=0;}
bit (Data EEPROM code protection off) }
#pragma config WRT = OFF // Flash Program Memory Write Enable bits if(PORTBbits.RB6==0){
(Write protection off; all program memory may be written to by EECON minutos++;
control) __delay_ms(500);
#pragma config CP = OFF // Flash Program Memory Code Protection bit if(minutos==60){minutos=0;}
(Code protection off) }}
#define _XTAL_FREQ 4000000 if(y==0){
#include <xc.h> INTCONbits.GIE=1;
#include <stdio.h> //Incluimos stdio para escribir cadenas con formato lcd_gotoxy(1,1); //Ubicamos el cursor en fila 1, columna 1
en una variable lcd_putc("LA HORA ES: "); //mostramos una cadena de caracteres
#include "Lcd.h" //Incluimos la libreria LCD en la pantalla LCD
int horas=0,minutos=0, segundos=0,x=0,y=0,z=0; lcd_gotoxy(2,1); //Ubicamos el cursor en fila2, columna 1
char arreglo_lcd[20]; sprintf(arreglo_lcd," %d : %d : %d ",horas, minutos, segundos);
void main(void){ lcd_putc(arreglo_lcd); //Mostramos el valor de buffer_lcd
z=0;
}}}
TRISD=0;
TRISC=0; void __interrupt() pinb()//Función de interrupción
TRISBbits.TRISB4=1;//Pin 4 del Puerto B como entrada {
TRISBbits.TRISB0=0;//Pin 0 del Puerto B como salida if(INTCONbits.TMR0IF==1)//Si RBIF==1
PORTBbits.RB0=0;//RB0=0 {
TRISCbits.TRISC4=0;//Pin 4 del Puerto C como salida int a;//Variable con puerto B, requisito de Fabricante
PORTCbits.RC4=0;//RC4=0 a=PORTB;
INTCON=0;//Limpio registro INTCON x++;
INTCONbits.GIE=1;//Habilitación global de Interrupciones?? TMR0=61;
//INTCONbits.RBIE=1;//Habilitación de interrupciones por el puerto B if (x==20) {
INTCONbits.RBIF=0;//Bit de interrupción a 0 segundos=segundos+1;
INTCONbits.TMR0IE=1;//Permiso de interrupción por tmr0 x=0;}
lcd_init();
INTCONbits.TMR0IF=0;//RBIF a cero
OPTION_REG=0b00000111;//timer0 pic como temporizador, prescaler 256 }
//OPTION_REGbits.nRBPU=0;// Habilitación de resistencias de Pull-Up }
TMR0=61;//El timer0 PIC se inicia a 60 para temporizar 50ms
PORTBbits.RB0=0;
Este código permite un conteo que parte desde un preescaler
while(1){ de 256, El cual está dado por la configuración de los bit 0,1 y
if (segundos==60){segundos=0;minutos++; 2 del registro OPTION_REG, los cuales son: 111. Para
lcd_clear;}
obtener el tiempo requerido se usa la ecuación de la Fig.2, la
if(minutos==60){horas++;minutos=0;
lcd_clear; cual permite obtener un valor adecuado el cual se debe igualar
} al TMR0 para que cuando este llegue a 255 haya transcurrido
if (horas==24){horas=0; el tiempo que se requiere, el cual para este caso fue de 50 ms
lcd_clear;
} (Tretardo).
if(PORTBbits.RB4==0)
{z++; 8 0.050𝑠*4000000 𝐻𝑧
if(z==1){
𝑇𝑀𝑅0 = 2 − 4*256
−1
lcd_clear(); 𝑇𝑀𝑅0 ≈ 61
y=1;
INTCONbits.GIE=0;
Considerando que el tiempo de temporización es de 50 ms y
horas=0;minutos=0; segundos=0;}
que el reloj está en relación a los segundos, se calcularon las
if(z==2){
y=0; veces que debía transcurrir 50 ms para que fuera un segundo,
z=0; sabiendo que 1000 ms es 1 segundo:
}
__delay_ms(500);
} 𝑥 = 1000/50
if(y==1){ 𝑥 = 20
lcd_gotoxy(1,1); //Ubicamos el cursor en fila 1, columna 1
lcd_putc("LA HORA ES: "); //mostramos una cadena de caracteres
Donde x son las veces que debe transcurrir 50 ms para que sea
en la pantalla LCD un segundo. Por lo tanto cada que x sea igual a veinte ha
pasado un segundo. ● No podrían hacerse más de una interrupción, ya que
en programación no podría establecerse la prioridad
Cada que el TMR0 llega a 255 se realiza una interrupción por de la misma.
desbordamiento del temporizador, donde se realiza un
incremento de la variable x, la cual cuando sea 20 va a
incrementar otra variable denominada “segundos” y cuando REFERENCIAS
esta sea 60 va a incrementar otra denominada “minutos” y
[1] A. Machado, Temporizador / Contador PIC [En Línea]. 2021,11,
finalmente cuando minutos sea 60, “horas” se incrementará. 12.Disponible en:
Esto se logró con una serie de if 's que se muestra en el código https://es.scribd.com/presentation/461391336/TEMPORIZADO
R-CONTADOR-PIC.
del reloj, adicionalmente se puso otro para que no pase de 24
horas.
𝑇𝑡𝑒𝑚𝑝 = (4 * 𝑝𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟)/(𝐹𝑂𝑆𝐶)
𝑇𝑡𝑒𝑚𝑝 = (4 * 256)/(4𝑀ℎ𝑧)
−6
𝑇𝑡𝑒𝑚𝑝 = 256𝑥10 𝑠
V. CONCLUSIONES