Autor Tema: como convertir el dato(2 byte) en ascii recibido en RCREG a decimal,C serial  (Leído 2003 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado jbte

  • PIC10
  • *
  • Mensajes: 7
buenas tardes, lo que pasa es que estoy enviado  un dato  desde labview al  pic16f887 , el envia  algunas eces  1byte otras 2 byte dependiendo dle numero que sea(0-100),
en el micro se recibe con RCREG cuando se activa RCIF ,  pero este dato  queda en ascii y lo necesito trabajar endecimal, yo se que si es un solo byte le resto 48 pero como son dos bytes los que se reciben por aparte no se como trabajarlos, cada byte se almacena en la posicion de un vector  luego el numero completo estaria
en la posicion BufferIn[0] y BufferIn[1] del vector.

ejemplo : labview envia el numero 50 y el pic recibe BufferIn[0]=53 y BufferIn[1]=48 en ascii

como puedo concatenar estos dos datos(bytes) que estan en ascci y volverlos a numero decimal y se asigno RCREG   una variable unsigned char solo toma un byte  y no los dos y sigue siendo ascii.

muchas gracias si me pueden colaborar.


unsigned char n;
int a=0,b;
unsigned char array[1];
volatile char BufferIn[20]={0};
volatile unsigned char pos=0;
unsigned char bytein;
 unsigned char var = 3;
 unsigned char buffer;

#define  _XTAL_FREQ  4000000
void putch (unsigned char byte);
unsigned char getch(void);
unsigned char getche(void);
void putUART(const char c);

void  main()
{
    ANSEL=1;
    ANSELH=0;
    TRISC=0b10000000;
   PORTC=0;
    OPTION_REG=0XC0;
    INTCON=0B11010000;
    TXSTA=0X20; //trasmir habilita tx
    RCSTA=0X90;// para poder transmitir o recibir
    SPBRG=25;

    RCIE=1;
        PEIE=1; //enable RX interrupt
        GIE=1;


while(1){ printf("\r%d%d \n",BufferIn[0]-48,BufferIn[1]-48);

}
}
void ISR(void){
if(RCIF){
        /*El registro "RCREG" tiene el byte recibido*/
        bytein=RCREG;
        BufferIn[pos]=bytein;
        pos++;
        if(pos>1) pos=0; // colocarlo e dos bytes vector dos posiciones
       
        RCIF=0; //Limpia bandera de interrupcion
    }}

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: como convertir el dato(2 byte) en ascii recibido en RCREG a decimal,C serial
« Respuesta #1 en: 31 de Octubre de 2014, 14:44:39 »
No entiendo cual es el problema xD

Si es el primer byte, le restas 48 y lo multiplcas por 10

Código: [Seleccionar]
if(RCIF){
        /*El registro "RCREG" tiene el byte recibido*/
        BufferIn=(RCREG - 48);              // Recibo el byte
        if(pos>1) {                               // Caso que sea el segundo byte
        amostrar = temp + BufferIn;       // Tus unidades, utilizo una variable mas asi solo se actualiza cuando llegaron todos los datos y usas "amostrar" en el printf
        pos=0;                                    // ya estan los 2 bytes
        }
        else {                                      // Caso primer byte, cada vez q entra aca resetea el valor del registro temp con el nuevo valor
        temp = BufferIn * 10;               // Tus decenas, si es 0, queda en 0
        pos++;
        }
        RCIF=0; //Limpia bandera de interrupcion
    }}

Otro cambio en tu codigo y hacerlo simple seria:

Código: [Seleccionar]
while(1){ printf("\r%d \n",(((BufferIn[0]-48)*10) +BufferIn[1]-48));
Ahora que leo en tu condicion no sabes cuantos datos van a llegar :/ Y es el mayor problema por que no sabes si es una unidad o una decena. Con lo cual el codigo hasta ahora puede hacer cualquier cosa, en espcial si mandas un dato de 1 byte y luego otro de 2.

Se me ocurren algunas ideas para determinar cual es el primero...
1- Usar una trama al final que indique cuando termino, entonces podes mandar 100 datos si queres (Ej. 0x35 0xFF - 5). O una inicial indicando la cantidad bytes tambien. (Ej. 0xF3 0x32 0x31 0x35 - 215) De todas formas un temproizador para que no se quede esperando por siempre.
2- Usar el metodo que usas, pero al recibir uno que actue un temporizador, y de no recibir ningun dato en un tiempo establecido que lo tome como un byte.
3- Si usas como maximo 2 bytes, mandar 2 bytes, si queres mandar un "5", mandas primero un "0" y luego un "5" y asi tenes 05 o 5... O mandar un byte 0xFF y comprobas que al estar fuera de escala significa que el dato no lo mas en cuenta y es igual a 0. (Es complicarse mas si es que podes mandar un 0)
« Última modificación: 31 de Octubre de 2014, 15:01:52 por KILLERJC »

Desconectado jbte

  • PIC10
  • *
  • Mensajes: 7
Re: como convertir el dato(2 byte) en ascii recibido en RCREG a decimal,C serial
« Respuesta #2 en: 31 de Octubre de 2014, 18:58:07 »
muchas gracias por la idea. ya lo termine y puedo concatenar haasta 3 bytes (3 digitos), desde labview envio un@ para identificar la trama y otro@ para finalizarla  y leo lo que hay entre ellos  y lo guardo en un vector y ahi si se cual es unidades decenas o centenas.
aca dejo el codigo  muchas gracias.

while(1)
    {
__delay_ms(800);

if(BufferIn[1]==49){ // longitud 1byte

    printf("\r%d %d %d %d \n",BufferIn[0],BufferIn[1]-48,BufferIn[2]-48,BufferIn[3]);// trama por separado
b=(BufferIn[2]-48) ;
printf("\r%d \n",b);
}

if(BufferIn[1]==50){//longitud 2 byte
printf("\r%d %d %d %d %d \n",BufferIn[0],BufferIn[1]-48,BufferIn[2]-48,BufferIn[3]-48,BufferIn[4]);// trama por separado
b=(((BufferIn[2]-48)*10) +BufferIn[3]-48);
printf("\r%d \n",b);
}

if(BufferIn[1]==51){ longitud 3byte
printf("\r%d %d %d %d %d %d \n",BufferIn[0],BufferIn[1]-48,BufferIn[2]-48,BufferIn[3]-48,BufferIn[4]-48,BufferIn[5] ); // trama por separado
b=(((BufferIn[2]-48)*100) +((BufferIn[3]-48)*10)+((BufferIn[4]-48)) ); //unidades decennas*10 centenas *100 3 bytes separados asi los concateno
printf("\r%d \n",b);

}

//----------------------------------------------------------
if(RCIF){
        /*El registro "RCREG" tiene el byte recibido*/
        bytein=RCREG;
       bytein=RCREG;
        BufferIn[pos]=bytein;
        pos++;               //vario posicion vector

        if(BufferIn[0]==64 && BufferIn[1]==49){  // si el primera posicion del vector[0] es el identificador de la trama [1]==49 es # bytes 1 (1 digito)
        if(pos>3) pos=0; // colocarlo e dos bytes vector 4 posiciones
        }

        if(BufferIn[0]==64 && BufferIn[1]==50){// si el primera posicion del vector[0] es el identificador de la trama [1]==49 es # bytes 2 (2 digito)
        if(pos>4) pos=0; // colocarlo e dos bytes vector 5 posiciones
        }

        if(BufferIn[0]==64 && BufferIn[1]==51){// si el primera posicion del vector[0] es el identificador de la trama [1]==49 es # bytes 3 (3 digito)
        if(pos>5) pos=0; // colocarlo e dos bytes vector 6 posiciones
        }

        RCIF=0; //Limpia bandera de interrupcion
    }

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: como convertir el dato(2 byte) en ascii recibido en RCREG a decimal,C serial
« Respuesta #3 en: 31 de Octubre de 2014, 19:19:33 »
podrias usar un switch case, y no tantos if
Y te recuerdo el temporizador, mas que nada por que si en algun momento falla la conexcion y se envia mal un caracter o directamente se corta, el micro va a estar esperando sin sentido. Aunque esto es como para ya una version final y no tanto como para probar :P

Código: [Seleccionar]
switch ( BufferIn[1] ) {
case 49:
  // Codigo para cuando vale 49
  break;
case 50:
  // Codigo para cuando vale 50
  break;
case 51:
  // Codigo para cuando vale 51
  break; 
default:
  // Codigo para cuando recibe cualquier otro valor.
  break;
}

Desconectado jbte

  • PIC10
  • *
  • Mensajes: 7
Re: como convertir el dato(2 byte) en ascii recibido en RCREG a decimal,C serial
« Respuesta #4 en: 31 de Octubre de 2014, 19:31:59 »
Gracias.

Desconectado Thulsa Doom

  • PIC24F
  • *****
  • Mensajes: 771
    • https://electronicadicto.wordpress.com/
Re: como convertir el dato(2 byte) en ascii recibido en RCREG a decimal,C serial
« Respuesta #5 en: 01 de Noviembre de 2014, 08:55:43 »
Buenas al igual me meto donde no me llaman.
no he leído el pos en su totalidad pero según creo el pic recibe el dato en un array unidimensional y nunca es el mismo tamaño.
¿estoy en lo cierto?
si es así podrías utilizar una función de c estándar para calcular el tamaño del array.

strlen te devuelve el tamaño del array recibido y en función del tamaño puede hacer tu código para que trabaje de forma automática con los distintos tamaños de los datos.
luego puedes restar cada posición del array por -48, para ello yo utilizaría un bucle for con el valor de bucle el valor dado por strlen y por último convertir con la función de c estándar atoi el array a un número char, c18 tiene unas librerías para esto

no sé es una idea.

saludos
« Última modificación: 01 de Noviembre de 2014, 08:59:52 por Thulsa Doom »
Más códigos y desarrollos en https://electronicadicto.wordpress.com/ date una vuelta y curiosea un rato...

Desconectado jbte

  • PIC10
  • *
  • Mensajes: 7
Re: como convertir el dato(2 byte) en ascii recibido en RCREG a decimal,C serial
« Respuesta #6 en: 01 de Noviembre de 2014, 15:06:19 »
gracias por interesarse enn el tema, lo que pasa es que no se recibe unpaquete de varios byte sino que se recibe cada byte, si recibiera un paquete de varios byte ahi si puedo hacer lo que usted dice.
ya que  con RCREG solo se recibe un bytew ala vez.

Desconectado Thulsa Doom

  • PIC24F
  • *****
  • Mensajes: 771
    • https://electronicadicto.wordpress.com/
Re: como convertir el dato(2 byte) en ascii recibido en RCREG a decimal,C serial
« Respuesta #7 en: 01 de Noviembre de 2014, 15:23:08 »
Vale entendido
Más códigos y desarrollos en https://electronicadicto.wordpress.com/ date una vuelta y curiosea un rato...