#include <18f2550.h>
#device adc = 10
#fuses nowdt,hs, put
#use delay(crystal = 20MHz)
#use fast_io(d)
#define punto pin_c7
// Arreglo para las variables de los dígitos.
int8 display[3] = {0,0,0};
float valor_adc;
void entero_a_bcd(int16 valor,int8 digitos_menos_1);
// Tabla para displays de 7 segmentos cátodo común.
int8 const tabla_7segs[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
#INT_TIMER1
// Servicio de interrupción por desborde del Timer 1
void sdi_timer1 (void)
{
// Realizar la lectura del conversor análogo a digital.
valor_adc = ((40.0 * read_adc()) / 65536);
set_timer1(0xBDC); // Recargar el Timer 1
}
void main (void)
{
int16 voltaje;
set_tris_d(0b11110000);
enable_interrupts(INT_TIMER1);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
set_timer1(0xBDC); // Cargar el timer1 con 3036 (500Ms. Aprox. 0.001% Error)
enable_interrupts(GLOBAL);
setup_adc_ports(sAN0|VREF_VREF); // Seleccionar canal 0 y usar VRef = 2.5V
setup_adc(ADC_CLOCK_INTERNAL); // Reloj ADC = interno
set_adc_channel(0); // Establecer el canal 0
delay_us(50);
while (true)
{
// Multiplicar por 100 el valor de "valor_adc"
voltaje = (valor_adc * 100);
// Obtener el valor para cada dígito, separando el número
// y convirtiéndolo con la tabla para displays de 7 segmentos.
entero_a_bcd(voltaje,3);
// Multiplexar los displays. (Con 4 ms se consiguió menor transición en las unidades)
output_d(1); // Activar display 1 y desactivar display 2 y 3
output_c(tabla_7segs[display[3]]); // Mostrar unidades.
delay_ms(2); // Retardo para mostrar las unidades.
output_d(2); // Activar display 2 y desactivar Display 1 y 3
output_c(tabla_7segs[display[2]]); // Mostrar decenas.
delay_ms(2); // Retardo para mostrar las decenas.
output_d(4); // Activar display 3 y desactivar Display 1 y 2
output_c(tabla_7segs[display[1]]); // Mostrar las centenas.
output_high(punto); // Apagar el punto.
delay_ms(2); // Retardo para mostrar las centenas.
output_d(8);
output_c(tabla_7segs[display[0]]); // Mostrar los millares.
output_low(punto); // Encender el punto.
delay_us(700);
}
}
// Subrutina para separar el número.
void entero_a_bcd(int16 valor, int8 digitos_menos_1)
{
int8 i;
// Limpiar variables del arreglo "display[]".
for(i=0;i<=digitos_menos_1;i++)
{
display[i] = 0;
}
i = digitos_menos_1;
// Separar los números.
while (valor > 0)
{
display[i--] = (valor % 10);
valor /= 10;
}
}