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

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

Desconectado KALLITOS

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1256
Obtener el byte alto y byte bajo de un Int16
« en: 22 de Mayo de 2009, 00:33:02 »
Hola amigos, buscando en el foro encontre como pasar de int8 a int16 e int32, pero ahora me surge la duda de como obtener los dos bytes de un Int16.

Lo que pretendo hacer es por ejemplo hacer sumas sucesivas de un int16 y mostrar el byte alto en el puerto B y el byte bajo en el puerto D

Existe esta funcion en el CCS o hay que hacerla mnualmente, alguien sabe como?

Saludos.
« Última modificación: 22 de Mayo de 2009, 00:47:42 por KALLITOS »
A un microcontrolador hay que sacarle hasta el ultimo byte....(YO)

Cómo puede ser que un pic24EP512 me quede corto de memoria, señores de MICROCHIP saquen pics con más memoria flash

Más de 45 mil lineas de codigo y aun no termino el equipo, asu mare!!

S34ML08G1TFI200 no necesito mas memoria externa.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Obtener los dos byte de Int16
« Respuesta #1 en: 22 de Mayo de 2009, 00:42:34 »
Código: C
  1. int8 Data_h, Data_L;
  2. int16 DataLong;
  3.  
  4. Data_H=make8(DataLong,1);
  5. Data_L=make8(DataLong,0);
No contesto mensajes privados, las consultas en el foro

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Obtener los dos byte de Int16
« Respuesta #2 en: 22 de Mayo de 2009, 00:45:31 »
O por truncado:

Código: C
  1. int8 Data_h, Data_L;
  2. int16 DataLong;
  3.  
  4. Data_H=make8(DataLong,1);
  5. Data_L=DataLong;
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado ASTROCAR

  • PIC24F
  • *****
  • Mensajes: 664
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #3 en: 22 de Mayo de 2009, 07:42:12 »
Hola buenos dias en este post tambien hay informacion referente a lo tratado aca, si gusta puedes revisarlo.
http://www.todopic.com.ar/foros/index.php?topic=26043.0

Saludos.
Atten.
Alexander Santana.
Barcelona-Venezuela.
« Última modificación: 22 de Mayo de 2009, 21:30:21 por ASTROCAR »
EL APRENDER ES NADA; MEJOR ES COMPARTIR EL APRENDIZAJE

Conectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #4 en: 22 de Mayo de 2009, 08:47:17 »
El make8 sólo funciona con CCS. A mí me gusta más hacerlo de esta manera que es ANSI C:

Código: C
  1. int8 Data_H, Data_L;
  2. int16 DataLong;
  3.  
  4. Data_H=DataLong>>8;
  5. Data_L=DataLong & 0xFF;

Aunque si el truncado funciona como dice Bruno el programa es más sencillo, pero ojo, luego te puedes volver loco para entenderlo.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #5 en: 22 de Mayo de 2009, 12:16:04 »
El make8 sólo funciona con CCS. A mí me gusta más hacerlo de esta manera que es ANSI C:

Código: [Seleccionar]
int8 Data_H, Data_L;
int16 DataLong;
 
Data_H=DataLong>>8;
Data_L=DataLong & 0xFF;

Aunque si el truncado funciona como dice Bruno el programa es más sencillo, pero ojo, luego te puedes volver loco para entenderlo.


Cuidado Nocturno, acuérdate que ese tipo de instrucciones son lentas y en estos días de mini-concursos no nos podemos dar el lujo de gastar más microsegundos.  :mrgreen:

Cada rotación de bit implica más de una instrucción en ensamblador y MAKE8 solo usa 2 instrucciones máximo. Pero hice un descubrimiento, CCS optimizó el código e ignoró las 8 rotaciones e incluso ignoró la AND que aplicas:

Código: [Seleccionar]
.................... DataLong=0x0000;
0010:  BCF    03.5
0011:  CLRF   22
0012:  CLRF   21
.................... Data_H=0x01;
0013:  MOVLW  01
0014:  MOVWF  23
.................... Data_L=0x02;
0015:  MOVLW  02
0016:  MOVWF  24
.................... 
.................... //Proceso lento
.................... Data_H=DataLong>>8;
0017:  MOVF   22,W
0018:  MOVWF  23
.................... Data_L=DataLong & 0xFF;
0019:  MOVF   21,W
001A:  MOVWF  24
.................... 
.................... //Optimizado en ensamblador
.................... Data_H=make8(DataLong,1);
001B:  MOVF   22,W
001C:  MOVWF  23
.................... Data_L=DataLong; //casting implícito
001D:  MOVF   21,W
001E:  MOVWF  24

Por lo que el código MAKE8 y el código de rotaciones de Nocturno son exactamente lo mismo... después de ser optimizados.

Pero si el compilador no es optimizado habrá que buscar una instrucción integrada del compilador que haga el trabajo rudo más rápido como MAKE8.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #6 en: 22 de Mayo de 2009, 12:27:15 »
Muy buena data Migsantiago! Les hace bien los concursos  :D  :D  :D
No contesto mensajes privados, las consultas en el foro

Conectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #7 en: 22 de Mayo de 2009, 12:35:08 »
Pues si no me lo llegas a decir, yo habría pensado que la rotación >>8 se comportaba como el make8. Lo he visto muchas veces en CCS y he visto que es muy eficiente, pero claro, no sabía que el resto de los compiladores lo compilaba de otra manera. Gracias por el dato.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #8 en: 22 de Mayo de 2009, 13:58:25 »
El make8 sólo funciona con CCS. A mí me gusta más hacerlo de esta manera que es ANSI C:

Código: [Seleccionar]
int8 Data_H, Data_L;
int16 DataLong;
 
Data_H=DataLong>>8;
Data_L=DataLong & 0xFF;

Aunque si el truncado funciona como dice Bruno el programa es más sencillo, pero ojo, luego te puedes volver loco para entenderlo.


Cuidado Nocturno, acuérdate que ese tipo de instrucciones son lentas y en estos días de mini-concursos no nos podemos dar el lujo de gastar más microsegundos.  :mrgreen:

Cada rotación de bit implica más de una instrucción en ensamblador y MAKE8 solo usa 2 instrucciones máximo. Pero hice un descubrimiento, CCS optimizó el código e ignoró las 8 rotaciones e incluso ignoró la AND que aplicas:

Código: [Seleccionar]
.................... DataLong=0x0000;
0010:  BCF    03.5
0011:  CLRF   22
0012:  CLRF   21
.................... Data_H=0x01;
0013:  MOVLW  01
0014:  MOVWF  23
.................... Data_L=0x02;
0015:  MOVLW  02
0016:  MOVWF  24
.................... 
.................... //Proceso lento
.................... Data_H=DataLong>>8;
0017:  MOVF   22,W
0018:  MOVWF  23
.................... Data_L=DataLong & 0xFF;
0019:  MOVF   21,W
001A:  MOVWF  24
.................... 
.................... //Optimizado en ensamblador
.................... Data_H=make8(DataLong,1);
001B:  MOVF   22,W
001C:  MOVWF  23
.................... Data_L=DataLong; //casting implícito
001D:  MOVF   21,W
001E:  MOVWF  24

Por lo que el código MAKE8 y el código de rotaciones de Nocturno son exactamente lo mismo... después de ser optimizados.

Pero si el compilador no es optimizado habrá que buscar una instrucción integrada del compilador que haga el trabajo rudo más rápido como MAKE8.

Yo considero que si bien puede ser visto positivamente como una optimización, me parece completamente negativo por otro lado que el CCS optimice de ese modo el código. Técnicamente debería respetar a rajatabla al ANSI C y realizar las rotaciones(lo mísmo con la AND). Entiendo que nosotros estemos contentos por la optimización, pero desde el punto de vista de la estandarización, no me parece correcto. Lo digo porque, por ejemplo, tal vez alguien está migrando código C al uC y espera que dicha operación(rotación>>8) demore cierta cantidad de instrucciones o, tal vez, afecte a ciertos flags(como el STATUS,C).

Un saludo.

"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #9 en: 23 de Mayo de 2009, 11:36:15 »
Buscando en la ayuda de CCS encontré la forma de modificar el nivel de optimización:

Citar
#OPT
--------------------------------------------------------------------------------
Syntax:
 #OPT n
 
Elements:
 All Devices:  n is the optimization level 0-9
PIC18XXX:    n is the optimization level 0-11
 
Purpose:
 The optimization level is set with this directive.  This setting applies to the entire program and may appear anywhere in the file.  The PCW default is 9 for full optimization.  PIC18XXX devices may utilize levels 10 and 11 for extended optimization.  Level 9 may be used to set a PCW compile to look exactly like a PCM compile for example.  It may also be used if an optimization error is suspected to reduce optimization. 
 
Examples:
 #opt 5

Así que pidiéndole una optimización nula (#opt 0) y compilando el mismo ejemplo yo pensaba que haría las 8 rotaciones... pero no, no las hizo, optimizó el código de todas formas quedando el ensamblador como en el primer ejemplo.

Desconozco si ANSI C incluye optimizaciones obligatorias como la rotación de múltiplos de 8 bits que equivale a un byte fácilmente movible de memoria ram, pero como comenta Bruno, tal vez uno quiere que se haga la rotación para consumir más tiempo o levantar banderas.

Por otro lado, existen funciones de generación de tiempos bien definidas (delay_xx), y el acceso a banderas de estado es innecesario en el lenguaje C por lo que todavía veo útil la optimización obligatoria.
« Última modificación: 23 de Mayo de 2009, 11:38:25 por migsantiago »

Desconectado KALLITOS

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1256
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #10 en: 23 de Mayo de 2009, 22:54:50 »
Ok amigos, gracias a tooooodos  :mrgreen:

Muchas gracias por responder, es justo lo que buscaba, además parece que va a servirle a muchos.

Saludos!!
A un microcontrolador hay que sacarle hasta el ultimo byte....(YO)

Cómo puede ser que un pic24EP512 me quede corto de memoria, señores de MICROCHIP saquen pics con más memoria flash

Más de 45 mil lineas de codigo y aun no termino el equipo, asu mare!!

S34ML08G1TFI200 no necesito mas memoria externa.

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Primero read luego write
« Respuesta #11 en: 18 de Septiembre de 2015, 13:46:24 »
Hola a todos Necesito mandar un INT16 a otro micro madiante protocolo SPI El problema es que nisiquiera logro partirlo en 2 INT8 Las instrucciones en este
o cualquier otro foro parecen simples pero llevo ya 3 dias con lo mismo y nada funciona Esto es lo que e probado entre otras cosas:

//DECLARACIONES
int16 pru1=1320;                   
int8 v8,v16;   
int8 posicion;

//......................................

v8=make8(pru1,0);
v16=make8(pru1,1);

//FRACASO 2.................................

posicion=&pru1
v8=make8(posicion,0);
v16=make8(posicion,1);

//FRACASO 3................................

v8=make8(*(&pru1),0);
v16=make8(*(&pru1),1);

//FRACASO 4................................

v8=pru1>>8;
v16=pru1 & 0xff;

//En todos los casos el RESULTADO ES V8=40  V16=5

Me gustaria saber que es lo que hago mal ¿make8 necesita alguna libreria? E oido ablar de macros en referencia a make16
desde luego el que yo e hecho en make8 no es valido      #define make8(Variable,Bit)  *(&Variable+Bit)
Si fuese por esto cual es el macro adecuado para lo que yo necesito

saludos

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2060
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #12 en: 18 de Septiembre de 2015, 14:01:50 »
Yo probe esto y funciona en CCS.

Citar
#include <18F252.h>
#device adc=10

#fuses XT, nowdt,
#use delay(clock= 4000000)     //Ajusta las rutinas de retardo para operar a 32Mhz( 4 x 8Mhz), con el pll activado

#use RS232(baud=9600,xmit=pin_c6,rcv=pin_c7)

void main()
{
   int16 dato= 0x3479;
   int low_long, high_long;
   
   low_long= make8(dato,0);
   high_long= make8(dato,1);
   
   printf("%X %X", high_long, low_long);
   
   while(true);
}

Espero te sea util.

Saludos

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Primero read luego write
« Respuesta #13 en: 18 de Septiembre de 2015, 14:06:32 »
Hola a todos Necesito mandar un INT16 a otro micro madiante protocolo SPI El problema es que nisiquiera logro partirlo en 2 INT8 Las instrucciones en este
o cualquier otro foro parecen simples pero llevo ya 3 dias con lo mismo y nada funciona Esto es lo que e probado entre otras cosas:

//DECLARACIONES
int16 pru1=1320;                   
int8 v8,v16;   
int8 posicion;

//......................................

v8=make8(pru1,0);
v16=make8(pru1,1);

//FRACASO 2.................................

posicion=&pru1
v8=make8(posicion,0);
v16=make8(posicion,1);

//FRACASO 3................................

v8=make8(*(&pru1),0);
v16=make8(*(&pru1),1);

//FRACASO 4................................

v8=pru1>>8;
v16=pru1 & 0xff;

//En todos los casos el RESULTADO ES V8=40  V16=5

Me gustaria saber que es lo que hago mal ¿make8 necesita alguna libreria? E oido ablar de macros en referencia a make16
desde luego el que yo e hecho en make8 no es valido      #define make8(Variable,Bit)  *(&Variable+Bit)
Si fuese por esto cual es el macro adecuado para lo que yo necesito

saludos

Hay un modo e SPI de CCS en que puedes enviar hasta 16 bits e un solo mensaje, buscalo...
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re: Obtener el byte alto y byte bajo de un Int16
« Respuesta #14 en: 18 de Septiembre de 2015, 14:10:47 »
v8 = (pru1 & 0xFF00) >> 8;
v16= (pru1 & 0x00FF);

en v8 te queda la parte alta y en v16 la parte baja. Eso no funciona?

sds.
-
Leonardo Garberoglio