Autor Tema: ayuda string a int32  (Leído 165 veces)

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

Desconectado fitson

  • PIC10
  • *
  • Mensajes: 37
ayuda string a int32
« en: 07 de Septiembre de 2018, 09:57:42 »
Hola de nuevo,

Esta vez necesito ayuda y no he conseguido encontrar la solución. Necesito enviar un número grande por serial y este se trata de un entero de 32 bits pero por putty se envían char bytes y necesito que el pic interprete esta cadena de números como un entero grande y si es posible sin importar librerias.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 6942
Re:ayuda string a int32
« Respuesta #1 en: 07 de Septiembre de 2018, 10:22:01 »
¿ No lo podes enviar como hexadecimal, eso te lo facilitaria mucho ?

Si no vas a tener que almacenarlo en un array. Saber cuando caracteres son del numero, revisar si existe un menos por si es negativo, y luego empezar a sumar sobre un int.

Ejemplo, supongamos que te llegan caracteres:

Código: C
  1. "1234567"
  2.  
Vos en tu array lo acomodas para que quede:

Código: C
  1. array = {'1','2','3','4','5','6','7'};
  2.  
Les restas '0' a cada uno para dejarlos en BCD y no ASCII

Código: C
  1. array = {1,2,3,4,5,6,7};
  2.  
A partir de aca podes hacer de 2 formas, Sumar repetidamente o multiplicar.

Código: C
  1. // Multiplicar
  2. largoDeNumero = 6
  3. resultado = 0
  4. j = 1;
  5. for(i = (largoDeNumero + 1); i != 0; i--) {
  6.      resultado += array[i-1] * j;
  7.      j *= 10;
  8. }

Entonces resultado el primer loop toma la posicion 6 (la unidad) y a ese numero lo multiplica por 1, y lo suma a resultado. La segunda vuelta j vale 10, asi que la posicion 5 (las decenas ) la multiplica por 10 y la suma. La tercera vuelta j vale 100, y asi sigue...
Podria haber usado la potencia, pero no querias librerias extras. Asi que esta realizado con lo basico, y como ves lo importante es poner el numero en el array.


Ahora si el tema es sumar, es mas "rapido" computacionalmente, ya que no requiere tantas multiplicaciones.
Pero exige memoria.

Desconectado fitson

  • PIC10
  • *
  • Mensajes: 37
Re:ayuda string a int32
« Respuesta #2 en: 07 de Septiembre de 2018, 10:27:24 »
Interesante la manera en que manejas la string para recuperar el entero, ahora que mencionas lo de enviar el número en hexadecimal, te estas refiriendo en enviar el valor hexadecimal en formato string, es decir de esta forma? "HFAA0123" por poner un ejemplo.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 6942
Re:ayuda string a int32
« Respuesta #3 en: 07 de Septiembre de 2018, 14:06:18 »
Exacto, por que de ser asi ocurren podrias hacer ocurrir algunas cosas que harian mucho mas simple la aplciacion.

1- Si logras enviar en hexadecimal, y que se incluyan TODOS los valores, ejemplo:

Código: [Seleccionar]
7FAA0123
0000ABCD
Logras tener un largo "fijo", lo cual facilita el guardado, ya que ahora necesitas solo un array con 8 lugares. para guardar el numero y el signo va dentro del numero, distinto del decimal que puede ser:

Código: [Seleccionar]
1234
123456789
-123456

2- Teniendo los valores en hexa todo se vuelve mas simple. Supongamos que llega "7FAA0123"

Si es un numero le restas '0', Si es una letra le restas 'A' y le sumas 10 (asi queda la 0xA)
Ahora eso te quedaria asi:

Código: [Seleccionar]
array = {0x7,0xF,0xA,0xA,0x0,0x1,0x2,0x3};
Ahora hay que unirlo, podriamos usar un puntero, una union, etc.

Código: C
  1. int32 resultado;
  2. char *ptr = (char *)&resultado;
  3.  
  4. for(i = 0; i < sizeof array; i+=2) {
  5.   *ptr = (array[i] << 4) | array[i+1];
  6. }

Desconectado fitson

  • PIC10
  • *
  • Mensajes: 37
Re:ayuda string a int32
« Respuesta #4 en: 07 de Septiembre de 2018, 15:34:26 »
Sorry KILLERJC, podrias volver a explicar la parte 2.

Código: [Seleccionar]
2- Teniendo los valores en hexa todo se vuelve mas simple. Supongamos que llega "7FAA0123"

Si es un numero le restas '0', Si es una letra le restas 'A' y le sumas 10 (asi queda la 0xA)
Ahora eso te quedaria asi:
no llego a entenderlo del todo.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 6942
Re:ayuda string a int32
« Respuesta #5 en: 07 de Septiembre de 2018, 20:29:42 »
A vos te llega: 7FAA0123

Y tu resultado debe ser 0x7FAA0123, aunque en realidad si lo dividís en bytes seria algo así 0x7F 0xAA 0x01 0x23.

El problema esta en que lo que te llega esta en ASCII. El '7' tiene el valor 55 decimal o 0x37 en hexa. Pero nosotros necesitamos que quede solamente el 0x7, al restarle '0' ( 0x30) nos queda el resultado correcto. Esto con los numero va genial, pero con las letras debemos cambiar los valores a restar. la 0xA = 10 decimal, la 'A' es 65 decimal o 0x41 hexadecimal. Yo podria restarle '7' ( que es 55 ) y asi me da el valor correcto:

'A' - '7' = 65 - 55 = 10 = 0xA

Pero no es intuitivo, alguien que lea el programa va a pensar, ¿por que le resta la letra 7? Entonces es mas intuitivo hacerlo asi:

'A' - 'A' + 10 = 65 - 65 + 10 = 10 = 0xA

De esta forma al restarle 'A', mi 'A' queda en 0, mi 'B' queda en 1 y asi. Pero en realidad yo necesito que quede en 10, por eso le sumo el 10.
El resultado que va a darle el compilador es el mismo, PERO visualmente es mas simple de entender el otro.

Te dejo la tabla ASCII:
https://upload.wikimedia.org/wikipedia/commons/d/dd/ASCII-Table.svg

Luego de hacer eso que es simple de realizar, te queda asi:

array = {0x7,0xF,0xA,0xA,0x0,0x1,0x2,0x3};

Y son numeros que ocupan 1 byte cada uno, pero nosotros necesitamos unir esos numeros.
Hay 2 formas de verlo..

El 0x7 lo tengo que correr hacia la izquierda 28 veces y sumarlo, el 0xF correrlo 24 veces y sumarlo. Esto si pensaramos que el int32 es todo uno solo. Pero podriamos pensar que son 4 bytes seguidos. Y ese es la aproximacion que tome al usar punteros a char ( 1 byte ), pasando por los 4 bytes que le pertenecen al int32.
Y que en un PIC seria un SWAP mas una OR lo necesario por cada byte