Código en C para Medir Tensión y Tiempo con PIC18 y Display LCD
A continuación se presenta un programa escrito en lenguaje C para microcontroladores PIC18, que utiliza una interrupción externa (INT0), el temporizador TMR0 y el convertidor analógico-digital (A/D) para medir tensión y tiempo, mostrando los resultados en un display LCD de 16x2.
1. Configuración de los pines del LCD
sbit LCD_RS at RD2_bit;
sbit LCD_EN at RD3_bit;
sbit LCD_D7 at RD7_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D4 at RD4_bit;
// Direcciones de los pines
sbit LCD_RS_Direction at TRISD2_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D7_Direction at TRISD7_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D4_Direction at TRISD4_bit;2. Variables globales
float tension;
float tempo;
char texto1[15];
char texto2[15];
unsigned int valor = 0, valor1 = 0;3. Rutina de interrupción
void interrupt() {
if (INTCON.INT0IF == 1) {
INTCON.INT0IF = 0;
INTCON.INT0IE = 0;
TMR0L = 0;
ADCON0.GO = 1; // Inicia la conversión A/D
T0CON.TMR0ON = 1; // Inicia la medida de tiempo
} else if (PIR1.ADIF == 1) {
T0CON.TMR0ON = 0;
valor1 = TMR0L; // Lee el contenido de TMR0L
// Calcula el tiempo (prescaler = 1)
tempo = 5.0e-7 * valor1;
// Lee ADRESL y ADRESH
valor = (ADRESH << 8);
valor = valor + ADRESL;
// Calcula la tensión
tension = ;
// Convierte tiempo y tensión a cadena
FloatToStr(tempo, texto1);
FloatToStr(tension, texto2);
// Representa los valores de tensión y tiempo
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1, 1, texto1);
Lcd_Out(2, 1, texto2);
PIR1.ADIF = 0;
INTCON.INT0IF = 0;
INTCON.INT0IE = 1;
}
}4. Función principal
void main() {
TRISB.RB0 = 1; // Configura terminales
TRISA.RA1 = 1; // Configura terminales
INTCON2.RBPU = 0; // Habilita resistencias pull-up
ADCON0 = 0x49; // Configuración del convertidor A/D
ADCON1 = 0xC4; // Configuración del convertidor A/D
Lcd_Init();
T0CON = 0x48; // Temporizador TMR0 apagado (off)
// Configuración del Timer 0
INTCON.TMR0IF = 0; // Pone el flag a 0
INTCON.TMR0IE = 1; // Habilita la interrupción del TIMER 0
// Habilita interrupciones INT0 y A/D
INTCON.INTEDG0 = 1;
INTCON.INT0IF = 0;
INTCON.INT0IE = 1;
INTCON.GIE = 1; // Habilita las interrupciones en general
while (1) {
asm nop;
}
}5. Observaciones
- La expresión de cálculo de la tensión (
tension = ;) aparece incompleta en el documento original; debe definirse la fórmula según la referencia de tensión y la resolución del convertidor A/D. - El valor de
tempose calcula con un prescaler igual a 1 y un periodo de instrucción de 0,5 µs. - Se recomienda verificar la configuración de
ADCON1según la tensión de referencia utilizada.