Autor Tema: Obtener el byte alto y byte bajo de un Int16  (Leído 11230 veces)

0 Usuarios y 3 Visitantes están viendo este tema.

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #15 en: 18 de Septiembre de 2015, 14:13:19 »
pero el resultado está bien!!!

1320 = 0x0528
en v8 te queda 0x05 = decimal 5
en v16 te queda 0x28 = decimal 40

saludos!
-
Leonardo Garberoglio

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #16 en: 18 de Septiembre de 2015, 16:00:25 »
Si asi es, esta bien. Una ves que lo tenga en el otro integrado lo junta y tiene le mismo numero.

La funcion que dice MGLSOFT creo que es

spi_write_16();

Lo raro que se lo nombra apenas en el manual

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2060
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #17 en: 18 de Septiembre de 2015, 17:38:59 »
La funcion que comenta el amigo MGLSOFT es spi_xfer(), para ser mas exacto y por medio de # USE SPI() configuras el modo y el numero de bits a transmitir, entre otros.  :mrgreen:

Saludos

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #18 en: 18 de Septiembre de 2015, 18:22:42 »
Si e visto que le pasa la posicion en dos partes desde el principio pero a esto le veo dos pegas

De que me sirve pasarle una posicion de memoria cuando lo que necesito es pasarle un contenido de esta (sus 2 punteros) una vec que llege a la 0x0528 del otro de que me va a servir me veo en las mismas lo que necesito es meterle el dato

y la otra es si pru1=1320 deja de ser puntero y lo que hace es combertirse en una posicion mediante make8 o lo que sea Como se yo que la 0x0528 No esta ocupada por el contenido de otra variable y asi acabar falseando datos O lo que es peor sea una zona reservada al micro. Esta ultima duda se me pasa tambien cuando veo "write_eeprom(posicion,pru1);"


Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #19 en: 18 de Septiembre de 2015, 18:34:48 »
Ok spi_xfer(pru1); Me lo a compilado dime que pongo ahora een el slave, damelo todo hecho porfa. Hoy me e pasado desallunando no e dejado los bares asta las 16:00 y estoy algo afectado
Hay algo para int32 La comunicacion siempre es de un bit ¿no? ¿Tendre que poner mas delays()?

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2060
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #20 en: 18 de Septiembre de 2015, 18:48:32 »
Berto, en los ejemplos que te hemos pasado trabajamos solo con datos (valores) en ningun caso son posiciones de memoria, tu querias dividir una varible de 16bits en dos de 8 bits y eso es precisamente lo que hacen los ejemplos dados. Tienes una confucion me parece o que es lo que quieres hacer?  :?

Saludos

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #21 en: 18 de Septiembre de 2015, 19:25:27 »
Si e visto que le pasa la posicion en dos partes desde el principio pero a esto le veo dos pegas

De que me sirve pasarle una posicion de memoria cuando lo que necesito es pasarle un contenido de esta (sus 2 punteros) una vec que llege a la 0x0528 del otro de que me va a servir me veo en las mismas lo que necesito es meterle el dato

y la otra es si pru1=1320 deja de ser puntero y lo que hace es combertirse en una posicion mediante make8 o lo que sea Como se yo que la 0x0528 No esta ocupada por el contenido de otra variable y asi acabar falseando datos O lo que es peor sea una zona reservada al micro. Esta ultima duda se me pasa tambien cuando veo "write_eeprom(posicion,pru1);"



nonononoononoo, 0x0528 = 1320, es el hexadecimal de 1320, no la posicion de memoria en que esta el 1320!

si quieres enviar 1320 decimal en 2 byte entonces la conversion es 40 decimal la parte baja y 5 decimal la parte alta. 5 * 256 + 40 =1320!!!

saludos!
-
Leonardo Garberoglio

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #22 en: 18 de Septiembre de 2015, 19:32:44 »
Si la palabra exacta es una confusion monunmental pero yo no recojo contenido Elgarbe tiene razon lo que leo mediante %d es 2 decimales.....
Claro no tiene porque ser una posicion de memoria El problema es que me esta dando el hexadecimal de 1320 (el dato en si) y el metodo
que abeis espusto vosotros 2 desde luego debe ser mas comodo si es mas lento internamente no lo se, pero si que te ahorra trabajo  Lo miro mañana mejor.

Saludos

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #23 en: 18 de Septiembre de 2015, 19:52:09 »
 Ok Elgarve    5 * 256 + 40 =1320!!! Gracias

pero en my caso va a ser   v16*256 + v8

v16 = (pru1 & 0xFF00) >> 8;  //v16 lo nombre con intencion de referirme a la parte alta lo que otros definen como Data_H
v8= (pru1 & 0x00FF);             //Data_L

Saludos


Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #24 en: 19 de Septiembre de 2015, 17:30:28 »
Hola de nuevo e variado un poco mas para el int32. Me e acomodado a hacer esto
---master
v4=make8(pru1,0);////....4
spi_write(v4);
.........
v8=make8(pru1,1);/////.....8
spi_write(v8);
......///pru1...int16

v4=make8(max1,0);///INT32.....4
spi_write(v4);
...........
v8=make8(max1,1);///.....8
spi_write(v8);
...........
v12=make8(max1,2);////....12
spi_write(v12);
.........
v16=make8(max1,3);////....16
spi_write(v16);
..........////...INT32_max1

----slave--------------
v4=spi_read();///...int16
.......
v8=spi_read();
......
v8=v8*256;+v4;///...int16

v4=spi_read();///....INT32
.......
v8=spi_read();
......
v12=spi_read();
.......
v16=spi_read();
.......
max1=(v16*16777216)+(v12*65536)+(v8*256)+v4;///....INT32

Pero esto no sirve con fload recivo los mismos hexadecimales si float es 62974.75 los datos son 'de vajo a alto 8E-75-FE-C0' son los mismos coinciden
pero no se montarlos dentro de una variable float para que me de 62974.75 Lo que hago solo sirve para enteros Estoy viendo tambien que esto lo deberia hacer
make16 v8=v8*256;+v4;
¿pero porque no me funciona esto?
pru1=make(v8,v4)//si utilizo esto el resultado no es correcto (aunque los pase a decimales)

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #25 en: 19 de Septiembre de 2015, 17:43:31 »
Yo quisiera saber si se puede hacer algo, Y de paso te olvidas del "tipo" de variable, algo como esto:

Código: C
  1. float   datoFloat
  2. int     dato16int
  3. long int dato32int
  4. short int dato8int
  5.  
  6.  
  7. void main()
  8. {
  9.         //Envio
  10.         EnviarSPI((shor int *)&datoFloat,sizeof(datoFloat));
  11.         EnviarSPI((shor int *)&dato16int,sizeof(dato16int));
  12.         EnviarSPI((shor int *)&dato32int,sizeof(dato32int));
  13.         EnviarSPI((shor int *)&dato8int,sizeof(dato8int));
  14.         //Recepcion
  15.         RecibirSPI((shor int *)&datoFloat,sizeof(datoFloat));
  16.         RecibirSPI((shor int *)&dato16int,sizeof(dato16int));
  17.         RecibirSPI((shor int *)&dato32int,sizeof(dato32int));
  18.         RecibirSPI((shor int *)&dato8int,sizeof(dato8int));
  19. }
  20.  
  21.  
  22.  
  23. void EnviarSPI(short int *ptr,short int largo)
  24. {
  25.         short int i;
  26.         for(i=0;i<largo;i++)
  27.                 spi_write(*ptr++);
  28. }
  29.  
  30. void RecibirSPI(short int *ptr,short int largo)
  31. {
  32.         short int i;
  33.         for(i=0;i<largo;i++)
  34.                 *ptr++ = spi_read();
  35. }

int = int16
short int = int8
long int = int32

Y los sizeof se pueden reemplazar directamente por la cantidad de bytes que posee el dato. Si es uno de 32 bits, entonces iria un 4. Si es de 16, iria un 2

Sino proba hacer esto en el esclavo

Código: C
  1. int8 *ptr;
  2.  
  3. // Cada ves que necesites escribir o leer
  4.  
  5. ///...int16
  6. ptr = (int8 *)&dato16int; //Aca el nombre de tu variable de 16 bits
  7. *ptr++ =spi_read();
  8. *ptr=spi_read();
  9.  
  10. ///....INT32
  11. ptr = (int8 *)&dato32int
  12. *ptr++=spi_read();
  13. *ptr++=spi_read();
  14. *ptr++=spi_read();
  15. *ptr=spi_read();
  16.  
  17. /// Si es float es igual que el de int32 para el caso de CCS.

Y deberia andar, si no estoy tan errado, ademas produciria un codigo mucho mas corto que hacer multiplicaciones y rotaciones. A no ser que se de cuenta el compilador que las rotaciones esas no debe realizarlas.

EDIT:

Usar union

Código: C
  1. union FloatData {
  2.         float data;
  3.         int8 bytes[4];
  4. }
  5.  
  6. void main()
  7. {
  8.         union FloatData datoFloat;
  9.         datoFloat.data = 1.23456;
  10.         int8 i;
  11.         // Envio
  12.         for(i=0;i<4;i++)
  13.                 spi_write(datoFloat.bytes[i]);
  14.  
  15.         //Recepcion
  16.         for(i=0;i<4;i++)
  17.                 datoFloat.bytes[i] = spi_read();
  18.        
  19. }
« Última modificación: 19 de Septiembre de 2015, 19:10:46 por KILLERJC, Razón: Mas posibles soluciones »

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #26 en: 19 de Septiembre de 2015, 20:12:21 »
EDIT:

Usar union

Código: C
  1. union FloatData {
  2.         float data;
  3.         int8 bytes[4];
  4. }
  5.  
  6. void main()
  7. {
  8.         union FloatData datoFloat;
  9.         datoFloat.data = 1.23456;
  10.         int8 i;
  11.         // Envio
  12.         for(i=0;i<4;i++)
  13.                 spi_write(datoFloat.bytes[i]);
  14.  
  15.         //Recepcion
  16.         for(i=0;i<4;i++)
  17.                 datoFloat.bytes[i] = spi_read();
  18.        
  19. }

 ((:-)) ((:-))
Esa, creo yo, es la mejor manera, o por lo menos la mas entendible/eficiente!
muy buena!

sds
-
Leonardo Garberoglio

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #27 en: 20 de Septiembre de 2015, 05:29:04 »
Si a por lo ultimo es a por lo que e ido acavo de probarlo pero le falta ago o me falta algo amy Cuando declaro la estructura (eso a mi me parece lo que es) El compilador me da un monton de errores en lineas que no tienen nada que ver con ella Si cambio 'struct' por 'union' pasa lo mismo.
No puedo olvidarme del "tipo" de variable, cuando justo lo que necesito es este "tipo" es imprescindible Aunque ahora me dedique a hacer pruebas a lo bestia pasando datos descomunales a intencion de hacerlo lo mas rapido posible (Esto no es necesario en proyecto original, pero si el float)

Volviendo al principio que es EnviarSPI((shor int *)&datoFloat,sizeof(datoFloat)); ¿fucion,macro,define?  EnviarSPI No esta declarado en ningun sitio
¿que es lo que hace darte el tamaño de float?

Gracias por vuestra atencion

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #28 en: 20 de Septiembre de 2015, 07:59:08 »
No se si son validas las declaraciones de los tipos, yo normalmente me manejo con uint8_t, uint16_t, uint32_t, float. Pero bueno por eso aclare en el primer post sobre la converson de las unidades, si es que es eso.

Citar
Si a por lo ultimo es a por lo que e ido acavo de probarlo pero le falta ago o me falta algo amy Cuando declaro la estructura (eso a mi me parece lo que es) El compilador me da un monton de errores en lineas que no tienen nada que ver con ella Si cambio 'struct' por 'union' pasa lo mismo.
No puedo olvidarme del "tipo" de variable, cuando justo lo que necesito es este "tipo" es imprescindible Aunque ahora me dedique a hacer pruebas a lo bestia pasando datos descomunales a intencion de hacerlo lo mas rapido posible (Esto no es necesario en proyecto original, pero si el float)

No es una estructura. En una estructura los datos no comparten el mismo espacio de datos, Si fuera una estructura tendrias en memoria algo asi:

Float ( ocupa 4 byte, y supongamos que tiene los valores 0x11223344 ) + el array de 4 que supongo que tiene 0xAA,0xBB,0xCC,0xDD

0x11 22 33 44 AA BB CC DD

Conla union se ocupa el espacio de lo mas grande declarado adentro, PERO comparten la misma memoria Tuvieramos el caso de que el float fuera 0x11 0x22 0x33 0x44

0x11 (igual a bytes[0]) , 0x22 (byets[1]) , 0x33 (bytes[2]) , 0x44(bytes[3])

Por lo demas es igual que una estructura, como definirlo etc. Lo que veo que me falt es un " ; " al final de la declaracion de la union, esta seria la correcta para que compares:

Código: C
  1. union FloatData {
  2.         float data;
  3.         int8 bytes[4];
  4. };

Citar
Volviendo al principio que es EnviarSPI((shor int *)&datoFloat,sizeof(datoFloat)); ¿fucion,macro,define?  EnviarSPI No esta declarado en ningun sitio
¿que es lo que hace darte el tamaño de float?

La funcion Enviar SPI esta escrita justo abajo del main(), incluso agregue la de Enviar y Recibir que son casi lo mismo, lo mas seguro es que le falta el prototipo al comienzo:

void EnviarSPI(short int *ptr,short int largo);

Es lo unico que puede decirte por lo que no esta esta declarado.

Para que se entienda lo que intente hacer con esa funcion. Normalmente un puntero aumenta segun el tipo que sea. Supongamos que tengo un puntero a un int8 y un int16

int8 *ptr8 = &variable8bits;   // Supone que la direccion es de 16 bits, pero puedo acceder a la misma hasta en bytes y esta en 0x11223344
int16 *ptr16 = &variable16bits; // y este en 0x22334455

Entonces le asigno la direccion de cada variable asi con *ptr8 , *ptr16 accedo al contenido de esa variable. Pero que ocurre cuando uno hace un

ptr8++;
ptr16++;

Los valores de las direcciones van a quedar:

ptr8 esto es igual a 0x11223345
ptr16 esto es igual a 0x22334457

ptr8 aumento 1 byte, y ptr16 aumento 2 bytes, si hubiera tenido un puntero a un float o un int 32, aumentarian de a 4 bytes.
Entonces lo que hago es:

EnviarSPI((shor int *)&datoFloat,sizeof(datoFloat));

Pasarle la direccion de inicio pero forzar a que el puntero sea de 1 byte (y no de 4 como es un float), entonces al aumentar lo hago de a 1 solo byte por ves y no 4 como seria un float, Y como ya perdi el "tamaño" es decir no se exactamente de cuantos bytes es lo que meti dentro ( 16,24,32) entonces envio un sizeof() que basicamente me dice la cantidad de bytes que ocupa ese dato. Finalmente:

Código: C
  1. short int i;
  2.         for(i=0;i<largo;i++)
  3.                 spi_write(*ptr++);

Procedo a enviarlo, suponete que el float tiene por bytes 0x11 0x22 0x33 0x44 y en la direccion 0x123456
Entonces el primer *ptr++ es 0x11 ubicado en 0x123456 , por el ++ aumenta a 0x12357
Lo cual el segudo *ptr++ es 0x22 y asi en adelante, hasta que se completen los 4 bytes pasados por el sizeof()


Fue lo que se me ocurrio en el momento, todo lo hice desde el gedit de Ubuntu, por decirlo asi el Bloc de notas de Windows, asi que no habia una correccion de sintaxis, ni pruebas, ni nada por el estilo.
Tambien pense en hacer uno con un void pointer para evitar el cast (short int *) fuera de la funcion de recepcion/envio, pero estaba seguro que iba a ser mas problemas.

PD: Deberias probar la solucion de RALF de hacerlo con spi_xfer() tambien
« Última modificación: 20 de Septiembre de 2015, 19:52:05 por KILLERJC »

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #29 en: 21 de Septiembre de 2015, 16:20:06 »
Por fin Valido creo que tengo todo.
NOTA Practica 10, Teoria 3 (Lo digo por mi claro).


 

anything