Skip to content

Instantly share code, notes, and snippets.

@jerivas
Created September 24, 2013 21:13
Show Gist options
  • Save jerivas/6691332 to your computer and use it in GitHub Desktop.
Save jerivas/6691332 to your computer and use it in GitHub Desktop.
//Cronómetro con centi-segundos
//Genera una frecuencia de 100 Hz, cada 100 pasos se cuenta 1 segundo
//El resultado se muestra en vivo en una LCD
//Eduardo Rivas, Carlos Zelada
#include <p18f4550.h> //Cabecera de Núcleo
#include <xc.h>
#include <delays.h>
#include <stdlib.h>
//Directivas para activar los bits de configuración
#pragma config FOSC = INTOSCIO_EC //Oscilador Interno, Puerto A RA6 activo,
#pragma config WDT = OFF //Watchdog timer apagado
#pragma config PBADEN = OFF //Parte baja del puerto B digitales
#pragma config MCLRE = ON //MCLRE Disponible
#pragma config DEBUG = ON //Modo de depuración disponible
#pragma config LVP = OFF //Fuente de ISCP apagada
//Cadena con el mensaje a mostrar. Nota: Debe tener espacio para albergar el
//cero terminador (un caracter extra)
char Mensaje[] = {'C','r','o','n','o','m','e','t','r','o',0x00};
char display[3];
int sec = 0;
int dsec = 0;
//Declaracion previa de las funciones
void LCD_Retardo_Corto();
void LCD_Retardo_Largo();
void LCD_Inicializar();
void LCD_Limpiar();
void LCD_Posicion(unsigned char x, unsigned char y);
void LCD_Caracter(unsigned char Caracter);
void LCD_display(unsigned char Caracter);
void LCD_Cadena(unsigned char *Cadena);
//Definiciones de pines de la LCD para referencia simplificada
#define LCD_RS LATE0
#define LCD_RW LATE1
#define LCD_E LATE2
#define LCD_DATA LATD
void main() {
//Inicializacion de los perifericos internos
ADCON1 = 0x0A; //Deshabilita el ADC
LATE = 0b00000000; //Se asegura que todo PORTE este a cero
LATD = 0b00000000; //Tambien PORTD se hace 0
TRISE = 0b00000000; //Coloca PORTE como salida
TRISD = 0b00000000; //Todo PORTD como salida tambien
IRCF0 = 1; //Ajusta el oscilador interno a 8MHz, necesario
IRCF1 = 1; //para que los delays sean más aproximados.
IRCF2 = 1;
//Inicializacion de los perifericos externos
LCD_Inicializar(); //Inicializa la pantalla LCD
//Imprime un mensaje de prueba
LCD_Cadena(Mensaje);
//Configuracion de generación de eventos con Timer1
CCP1CON = 0b0001011; //Mdoo Special Event Trigger
TMR1 = 0x0000; //Limpiar Timer1
CCPR1 = 2500; //Comparar contra 2500
T1CON = 0b00110001; //Timer1 en escala 1:8 y sincronizado
while(sec < 60){
if(CCP1IF == 1){
if (dsec == 99){
dsec = 0;
sec++;
} else {
dsec++;
}
LCD_Posicion(0x05, 0x40); //Columna 05, segunda fila
itoa(display, sec, 10); //Convertir segundos a ASCII
display[2] = 0; //Terminar cadena
LCD_Cadena(display); //Mostrar los segundos
LCD_Caracter(':'); //Mostrar 2 puntos
itoa(display, dsec, 10);//Convertir decenas de segundos a ASCII
display[2] = 0; //Terminar cadena
LCD_Cadena(display); //Mostrar las decenas de segundos
CCP1IF = 0;
}
}
}
//********************************************************
//Funcion usada para generar los retardos de la linea E de la pantalla LCD
void LCD_Retardo_Corto() {
Delay10TCYx(150);
}
//Funcion usada para generar los retardos de la inicializacion de la LCD
void LCD_Retardo_Largo() {
Delay10TCYx(250);
Delay10TCYx(250);
}
//Funcion de inicializacion de la pantalla LCD
void LCD_Inicializar() {
//Permite un cierto tiempo para que la pantalla inicialice internamente
LCD_Retardo_Largo();
//Envia el comando de inicializacion que establece el modo de 8 bits
LCD_RS = 0;
//Se enviara un comando
LCD_RW = 0;
//La operacion es de escritura
LCD_DATA = 0b00110000; //Comando que establece la interfase de 8 bits
LCD_E = 1;
LCD_Retardo_Corto(); //Pulsa la linea de Enable brevemente
LCD_E = 0;
LCD_Retardo_Corto();
//Espera a que la LCD procese el comando
LCD_Retardo_Largo();
//Envia el mismo comando por segunda vez
//(los puertos retienen sus valores anteriores)
LCD_E = 1;
LCD_Retardo_Corto();
LCD_E = 0;
LCD_Retardo_Corto();
//Espera nuevamente
LCD_Retardo_Largo();
//Envia el mismo comando por tercera vez
LCD_E = 1;
LCD_Retardo_Corto();
LCD_E = 0;
LCD_Retardo_Corto();
//Espera nuevamente
LCD_Retardo_Largo();
//Envia el comando que activa las 2 filas y establece la fuente grande
LCD_DATA = 0b00111100;
LCD_E = 1;
LCD_Retardo_Corto();
LCD_E = 0;
LCD_Retardo_Corto();
//El siguiente comando enciende el display completo y el cursor parpadeante
LCD_DATA = 0b00001111;
LCD_E = 1;
LCD_Retardo_Corto();
LCD_E = 0;
LCD_Retardo_Corto();
//Este comando indica al LCD que escriba hacia la derecha y que no desplace
//el texto al ir escribiendo
LCD_DATA = 0b00000110;
LCD_E = 1;
LCD_Retardo_Corto();
LCD_E = 0;
LCD_Retardo_Corto();
//Al final se limpia toda la pantalla
LCD_Limpiar();
}
//Funcion de limpieza de la pantalla LCD
void LCD_Limpiar() {
//Envia el comando que hace la operacion de limpieza
LCD_RS = 0;
//Se enviara un comando
LCD_RW = 0;
//La operacion es de escritura
LCD_DATA = 0b00000001;
LCD_E = 1;
LCD_Retardo_Corto();
LCD_E = 0;
LCD_Retardo_Corto();
}
//Funcion para establecer la posicion de escritura en la pantalla
void LCD_Posicion(unsigned char x, unsigned char y) {
unsigned char Direccion_DDRAM;
//Determina la direccion base de la DDRAM de acuerdo a la coordenada y
if (y == 0) Direccion_DDRAM = 0x00; //La fila 0 comienza en la direccion 0
else Direccion_DDRAM = 0x40; //La fila 1 comienza en la direccion 0x40
//Suma la coordenada x a la direccion base (aplica mascara)
Direccion_DDRAM += x & 0x0F;
//Una vez encontrada la direccion se envia el comando a la pantalla
LCD_RS = 0;
//Se enviara un comando
LCD_RW = 0;
//La operacion es de escritura
LCD_DATA = 0b10000000 | Direccion_DDRAM;
LCD_E = 1;
LCD_Retardo_Corto();
LCD_E = 0;
LCD_Retardo_Corto();
}
//Funcion de impresion de un caracter simple en la pantalla
void LCD_Caracter(unsigned char Caracter) {
LCD_RS = 1;
//Se enviara un dato
LCD_RW = 0;
//La operacion es de escritura
LCD_DATA = Caracter; //Coloca el caracter en el bus
LCD_E = 1;
LCD_Retardo_Corto(); //Provoca una pulsacion del enable
LCD_E = 0;
LCD_Retardo_Corto();
}
//Funcion de impresion de cadenas en pantalla LCD
void LCD_Cadena(unsigned char *Cadena) {
unsigned char i;
//Para imprimir una cadena simplemente se envian los caracteres de uno en
//uno hasta que se encuentra el cero terminador
for (i = 0; Cadena[i] != 0; i++)
LCD_Caracter(Cadena[i]);
}
//Funcion de impresion de un caracter simple en la pantalla
void LCD_display(unsigned char Caracter) {
LCD_RS = 1;
//Se enviara un dato
LCD_RW = 0;
//La operacion es de escritura
LCD_DATA = Caracter + 0x30; //Coloca el caracter en el bus
LCD_E = 1;
LCD_Retardo_Corto(); //Provoca una pulsacion del enable
LCD_E = 0;
LCD_Retardo_Corto();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment