Skip to content

Instantly share code, notes, and snippets.

@jerivas
Last active December 24, 2015 15:29
Show Gist options
  • Save jerivas/6821004 to your computer and use it in GitHub Desktop.
Save jerivas/6821004 to your computer and use it in GitHub Desktop.
// Frecuencimetro digital
// Cuenta las veces que ocurre un flanco ascendente durante un segundo
// Y muestra el resultado en la LCD
// Ángel Moreno
// David Escobar
// Eduardo Rivas
#include "p18f4550.h"
#include "xc.h"
#include "stdlib.h"
#include "../utils/lcd.h" //Incluir cabeceras para manejo de LCD
//Directivas para activar los bits de configuracion
#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 depuracion disponible
#pragma config LVP = OFF //Fuente de ISCP apagada
#define t250ms CCP1IF //Pasaron 250ms
#define edge_detect INT1IF //Entrada en RB1
//Variables globales
unsigned char count = 0; //Contador para la base de tiempo
unsigned long freq = 0; //Contador de frecuencia (flancos por segundo)
char ascii_freq[8] = 0x30; //Representacion ASCII de la frecuencia
//Configuracion
void config() {
IRCF0 = 1; //configuracion del OSCCON F=8MHz
IRCF1 = 1;
IRCF2 = 1;
//Configuracion de interrupciones
IPEN = 1; //Habilita la prioridad de las interrupciones
PEIE = 1; //Habilita interrupciones periféricas
//Configuracion del modo comparador (generacion de eventos)
T3CON = 0x00; //Configurar TMR1 como fuente de reloj para los modulos ccp1/3
CCP1M3 = 1; //Generar una interrupcion al coincidir
CCP1M2 = 0;
CCP1M1 = 1;
CCP1M0 = 1;
CCPR1 = 62500; //Genera una interrupción cada 250ms
//Configuracion del comparador 1
CCP1IE = 1; //Habilitar interrcupciones para CCP1
CCP1IP = 1; //Configurar CCP1 como de alta prioridad
//Inicializacion de los puertos
ADCON1 = 0x0F; //Deshabilitar el ADC
CMCON = 0x07; //Deshabilitar comparador
PORTB = 0; //Limpiar PORTB
LATE = 0; //Limpiar PORTE
LATD = 0; //Limpiar PORTD
TRISB1 = 1; //PORTB1 como entrada
TRISE = 0; //PORTE como salida
TRISD = 0; //PORTD como salida
INTEDG1 = 1; //Interrupción en PORTB1 en flanco ascendente
INT1IE = 1; //Habilitar interrupciones por flanco en PORTB1
INT1IP = 0; //Configurar INT1 como de baja prioridad
//Configuracion del Timer 1
TMR1 = 0; //Limpiar el registro de trabajo de Timer1
T1CON = 0b10110001; //Configurar y encender TIMER1
//Inicializacion de los perifericos externos
LCD_Inicializar(); //Inicializa la pantalla LCD
}
//Función principal que no hace nada, todo se maneja por interrupciones
void main() {
config(); //Ejecutar la configuración
LCD_Posicion(3, 0);
LCD_Cadena("Frecuencia");
GIE = 1; //Habilitar interrupciones
while(1);
}
//Rutina de interrupción de alta prioridad para generar la base de tiempo
void interrupt time_base(void) {
//Generación de la base de tiempo de 1s
if (t250ms) { //Han transcurrido 250ms en el Timer1
t250ms = 0; //Limpiar la bandera de 250ms
count++; //Incrementar el conteo de la base de tiempo
if (count == 4) { //Paso 1 segundo? 250ms x 4
count = 0; //Reiniciar el conteo de tiempo
LCD_Posicion(0x05, 0x40); //Apuntar a la segunda fila de la LCD
ultoa(ascii_freq, freq, 10); //Convertir freq a ASCII
LCD_Cadena(ascii_freq); //Mostrar el valor de la frecuencia
LCD_Cadena("Hz "); //Añadir las unidades: Hz
TMR1 = 0; //Limpiar Timer1 para volver a contar
freq = 0; //Se limpia el contador de frecuencia cada segundo
}
return;
}
}
//Rutina de interrupción de baja prioridad para contar la frecuencia
void interrupt low_priority count_freq(void){
if (edge_detect) { //Se ha detectado un flanco en RB1
edge_detect = 0; //Limpiar la interrupción del flanco
++freq; //Aumentar el contador de frecuencia cada vez que hay flanco
return;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment