Codigo:
////////////////////////////////////////////////////////////////////////
// Rutina de visualizacion de Float en displays de 7 seg
// Funciona con una maximo de 8 displays de anodo comun
// Representa Floats por lo que el numero de decimales no puede ser inferior a uno
//
// Conexiones:
// · RD0 -> Display 1º 7seg
// · RD1 -> Display 2º 7seg
// · RD2 -> Display 3º 7seg
// · RD3 -> Display 4º 7seg
// · RD4 -> Display 5º 7seg
// · RD5 -> Display 6º 7seg
// · RD6 -> Display 7º 7seg
// · RD7 -> Display 8º 7seg
//
// se conecta los pines RD mediante un transistor BC557 y una resistencia de base
// ya que la corriente total de los 7 seg supera la capacidad de salida de la RD del pic
//
// · RC0 -> a 7seg
// · RC1 -> b 7seg
// · RC2 -> c 7seg
// · RC3 -> d 7seg
// · RC4 -> e 7seg
// · RC5 -> f 7seg
// · RC6 -> g 7seg
// · RC7 -> Punto 7seg
//
// Se conectan las salidas RC al display a traves de una resistencia de un valor adecuado a la corriente
// exijida por el display para su correcto encendido
// Puede ser un valor aproximado entre 10 mAmp y 20 mAmp
// por lo que la resistencia debe ser de entre 100 y 330 Ohmios aproximadamente
//////////////////////////////////////////////////////////////////////
#include <16f877.h>
#include <stdlib.h>
#include <math.h>
#fuses XT,NOWDT,NOPROTECT
#use delay (clock=4000000)
#USE FAST_IO (C)
#USE FAST_IO (D)
// para hacer el barrido de los 8 displays
int muestra_digito[9]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; // Selecciona el display a visualizar
// tabla de salidas de excitacion de siete segmentos
// digitos a mostrar (0,1,2,3,4,5,6,7,8,9,Punto,E)
int tab7seg[12]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x98,0x7f,0x86}; // 7seg hex 0-9 anodo comun
// ajuste del tiempo que se queda encendido cada diodo de el display
// con este ajuste y el valor de tiempo de la interrupcion se quita el parpadeo
int tiempo =2;
visualizar_display(float f, int numero_total_digitos, int numero_de_decimales)
{
int32 x=0;
float f1;
int n=0;
int ceros=0;
char cadena[10];
char cadena8[4];
char cadena7[4];
char cadena6[4];
char cadena5[4];
char cadena4[4];
char cadena3[4];
char cadena2[4];
char cadena1[4];
char cadena0[4];
// en funcion del numero de decimales que queremos visualizar lo va a convertir
// en entero y para no perder la parte decimal lo multiplica antes por el valor
// correspondiente
if(numero_de_decimales ==1)
f1=f*10;
if(numero_de_decimales ==2)
f1=f*100;
if(numero_de_decimales ==3)
f1=f*1000;
if(numero_de_decimales ==4)
f1=f*10000;
if(numero_de_decimales ==5)
f1=f*100000;
if(numero_de_decimales ==6)
f1=f*1000000;
if(numero_de_decimales ==7)
f1=f*10000000;
// redondea por arriba el float una vez multiplicado
x=ceil(f1);
// pasa el entero a cadena
itoa(x,10,cadena);
// calcula la longitud de la cadena
n=strlen(cadena);
// Pasa cada cada caracter del número a entero, empleando punteros:
*cadena7=cadena[7]; // Unidades
*cadena6=cadena[6]; // Decenas
*cadena5=cadena[5]; // Centenas
*cadena4=cadena[4]; //.....
*cadena3=cadena[3];
*cadena2=cadena[2];
*cadena1=cadena[1];
*cadena0=cadena[0];
// si excede el numero de digitos del visualizador lo señaliza con E
if(n > numero_total_digitos)
{
output_c(tab7seg[11]); // Visualiza E en el display si se produce saturacion y sale de la rutina
output_d(muestra_digito[0]);
delay_ms(tiempo);
output_c(0xff);
return;
}
// muestra el punto decimal
if(numero_de_decimales > 0)
{
output_c(tab7seg[10]);
output_d(muestra_digito[numero_de_decimales]);
delay_ms(tiempo);
output_c(0xff);
}
// Si el valor es menor que 1, para que visualice el cero anterior a la coma
// y los posteriores
ceros = numero_de_decimales - n + 1;
/* truco para ver valor de variables
output_c(tab7seg[ceros]);
output_d(muestra_digito[7]); // se muestra en el ultimo digito
delay_ms(tiempo);
output_c(0xff);*/
if(ceros > 0 && f <1)
{
do{
output_c(tab7seg[0]);
output_d(muestra_digito[numero_de_decimales-ceros+1]); // posicion del cero anterior al punto
delay_ms(tiempo);
ceros--;
output_c(0xff);
}While(ceros != 0);
}
// las siguientes lineas ponen cada caracter en la salida
// y activan el display correspondiente
output_c(tab7seg[atoi(cadena0)]);
output_d(muestra_digito[n-1]); // digito de menor peso
delay_ms(tiempo);
output_c(0xff);
If(n==1)
return;
output_c(tab7seg[atoi(cadena1)]);
output_d(muestra_digito[n-2]);
delay_ms(tiempo);
output_c(0xff);
If(n==2)
return;
output_c(tab7seg[atoi(cadena2)]);
output_d(muestra_digito[n-3]);
delay_ms(tiempo);
output_c(0xff);
If(n==3)
return;
output_c(tab7seg[atoi(cadena3)]);
output_d(muestra_digito[n-4]);
delay_ms(tiempo);
output_c(0xff);
If(n==4)
return;
output_c(tab7seg[atoi(cadena4)]);
output_d(muestra_digito[n-5]);
delay_ms(tiempo);
output_c(0xff);
If(n==5)
return;
output_c(tab7seg[atoi(cadena5)]);
output_d(muestra_digito[n-6]);
delay_ms(tiempo);
output_c(0xff);
If(n==6)
return;
output_c(tab7seg[atoi(cadena6)]);
output_d(muestra_digito[n-7]);
delay_ms(tiempo);
output_c(0xff);
If(n==7)
return;
output_c(tab7seg[atoi(cadena7)]);
output_d(muestra_digito[n-8]);
delay_ms(tiempo);
output_c(0xff);
}
float y=0;
// rutina de interrupcion por desbordamiento
#int_RTCC
pulse()
{
visualizar_display(y,5,2);
set_rtcc(256);
}
// Programa Principal
main()
{
setup_counters(RTCC_INTERNAL, 0);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
set_rtcc(256);
set_tris_c(0x00);
set_tris_d(0x00);
// ejemplo de funcionamiento
y=0;
do{
y=y+0.1;
// para hacer pruebas considero que es el tiempo de ejecucion
// del programa de uso es de 10 mseg
// y simulo el programa asi
delay_ms(10);
}while(1);
}
Si alguien hace mas pruebas y obtiene errores por favor que los pegue y me indique donde y como, y si colabora a solucionarlo mejor.
Muchas gracias a Pocher por su colaboracion en este tema como en todos.