Tu codigo solo te da un digito por que siempre estas cargando el mismo.
trama_serial[x]= getc();x siempre es 0 , por lo tanto lo ultimo que llega se guarda en:
trama_serial[0]= getc();quedando:
unidad_1 = ((trama_serial[0])-48);Todo lo demas es 0, me refiero a trama_serial[1], trama_serial[2], trama_serial[3] son siempre 0 y le restas 48 cuando estan en 0!. Por eso mi if() preguntando si es mayor a 9 para ponerlo en 0.
Veo que te esta complicando demasiado la vida el tema de tener que enviar un retorno de carro, para mi que no lo estas enviando. Se me ocurren 3 cosas:
- Enviar en hexadecimal ( te dejo 3 para que hagas la prueba ):
"68&12\n" = 36 38 26 31 32 0A
"24&55\n" = 32 34 26 35 35 0A
"78&56\n" = 37 38 26 35 36 0A
Envia esos 3 valores en hexadecimal y fijate si funciona. Si funciona es por que no estas enviando el LF o CR
- Usar este codigo que no necesita del \n: ( Que al menos a mi no me gustaria, por que vas a tener errores, lo se.. intenta mandar una letra de mas y vas a ver )
#include <16f628A.H>
#fuses NOMCLR
#fuses INTRC_IO
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES RESERVED //Used to set the reserved FUSE bits
#use delay (clock=4000000)
#use rs232(baud=9600, xmit=pin_B2, rcv=pin_B1)
#define display_1 PIN_B4
#define display_2 PIN_B5
#define display_3 PIN_B6
#define display_4 PIN_B7
unsigned char trama_serial[5], buffer[5], i;
int x=0;
char auxiliar;
#int_rda
void rda_isr(void)
{
if ( x < 5 )
{
buffer[x] = auxiliar; // En caso que sea otro tipo de valor procede a guardarlo aca
++x;
if ( x == 5 )
{
for ( i = 0; i < 5 ; ++i )
{
trama_serial[i] = buffer[i] - 48; // Guardo en trama serial el dato completo, de esa forma no cambia mientras va recibiendo, solo cuando recibio todo
if (trama_serial[i] > 9 )
{
trama_serial[i] = 0; // Proteccion por si envian cualquier caracter. Esto solo va a poner un 0 cuando no sea un numero
}
}
x=0;
}
}
}
void main(void)
{
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while (true)
{
///////////////////////////////////////////////////
//unidad_dis1 = (valor % 10); // Se extraen las unidades.
// decena_dis1 = (valor % 100)/10; // Se extraen las decenas.
////////////////////////////////////////////////////////////////////
output_low(Display_4); // Apago el display anterior
output_a(trama_serial[0]); // Pongo el dato mientras estan todos apagados asi no se ve el cambio
output_high(Display_1); // Activo el display
delay_ms(1); // Muestro
output_low(Display_1);
output_a(trama_serial[1]);
output_high(Display_2);
delay_ms(1);
output_low(Display_2);
output_a(trama_serial[3]);
output_high(Display_3);
delay_ms(1);
output_low(Display_3);
output_a(trama_serial[4]);
output_high(Display_4);
delay_ms(1);
}
}
Este ultimo codigo es igual, nomas que ahora toma los 5 que llegaron los procesa y los guarda. Y automaticamente agarra los 5 nuevos que viene.
- Cambiar el formato de la trama a otra parecida, supongamos asi:"a12&37"
Esto va a permitir esperar la "a" para saber cuando comienza la trama de nuevo ( es lo mismo que el \n , nomas que esta ves estoy usando algo que podes poner en el teclado facilmente)
Lo bueno de esto, es que ademas podes definir varios "tipos" de tramas segun la letra inicial. Suponete:
"b1237" ---------- Lo mismo que a12&37 pero esta ves sin el &, con la b sabemos que 2 son del primero y 2 del segundo
"c123&456" ------ Lo mismo que antes, pero con la c, esperamos esta ves 3 digitos por cada uno y separados por un &
"d123456" ------- Lo mismo que ocurriria con la b, pero esta ves para valroes de 3 digitos y sin &.
"e12" ------------- Cambiar unicamente los 2 primeros digitos
"f32" -------------- Cambiar unicamente los 2 ultimos digitos.
ETC, es una idea esta nomas.