TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: LABmouse en 15 de Octubre de 2007, 16:26:50

Título: Manipular Byes y Nibles?... Imprimir cadena de Texto?
Publicado por: LABmouse en 15 de Octubre de 2007, 16:26:50
Hola amigos, una pregunta a ver si hay alguna forma mas corta de realizar este trabajo. Lo que intento hacer es manipular solo el nible mas bajo o mas alto de un INT8 de forma independiente, o manipular el byte mas bajo o mas alto de un INT16 de forma independiente.

Ejemplo:

INT16  VARIABLE1;
INT8    VALOR1;
INT8    VALOR2;

VARIABLE1=0X0000;
VALOR1=0X12;
VALOR2=0X34;

Ahora como le hago para que VARIABLE1 tome los valores 0x1234: es decir el contenido de VALOR1 en el Byte mas alto y el contenido de VALOR2 en el Byte mas bajo.




Bueno encontré esto, aunque es lo contrario que quiero hacer, pero es una LUZ

VALOR1= (VARIABLE1>>4);

De esa forma VALOR1 toma el valor del Byte mas bajo de VARIABLE1. pero yo quiero invertido, de una forma así rápida.



Hasta ahora se me ocurre de esta forma:

VARIABLE1=VALOR2;
VARIABLE1=SWAP(VARIABLE1);
VARIABLE1=VARIABLE1  ||   VALOR2;


SALUDOS!!

Título: Re: Como manipular bytes o nibles con CCS?
Publicado por: Nocturno en 15 de Octubre de 2007, 16:38:23
VARIABLE1 = make16(VALOR1,VALOR2);

o bien

VARIABLE1 = VALOR1<<8 + VALOR2;
Título: Re: Como manipular bytes o nibles con CCS?
Publicado por: jfh900 en 15 de Octubre de 2007, 16:40:15
Yo soy partidario de las estructuras, aqui tienes un ejemplo de uso:

http://www.todopic.com.ar/foros/index.php?topic=4867.msg36512#msg36512

Un saludo
Título: Re: Como manipular bytes o nibles con CCS?
Publicado por: LABmouse en 15 de Octubre de 2007, 16:41:06
 
VARIABLE1 = make16(VALOR1,VALOR2);

o bien

VARIABLE1 = VALOR1<<8 + VALOR2;

:shock: :shock: :shock:

Grande amigo!!!!!! Esta sorprendente esa forma... GRACIAS!!!  :-/ :-/


Yo soy partidario de las estructuras, aqui tienes un ejemplo de uso:

http://www.todopic.com.ar/foros/index.php?topic=4867.msg36512#msg36512

Un saludo

Pero con una estructura... Como le hago operaciones matemáticas usando el Byte completo??
Título: Re: Manipular Byes y Nibles?... Imprimir cadena de Texto?
Publicado por: LABmouse en 15 de Octubre de 2007, 17:10:27
otra pregunta de esas que se podrían denominar trucos de CCS, porque eso de Nocturno me dejo sorprendido.

Tengo esta variable:

char  ID_SISTEMA[8];

La quiero imprimir por RS232, y la única opción que conozco es usando un for que recorra todas las 8 posiciones del vecto.

Código: [Seleccionar]
   for(i=0;i<8;i++){
   printf("%C",ID_SISTEMA[i]);
   }

hay algún truco para imprimir si usar FOR??
Título: Re: Manipular Byes y Nibles?... Imprimir cadena de Texto?
Publicado por: jfh900 en 15 de Octubre de 2007, 17:47:11
Para manejar los nibles:

Código: [Seleccionar]
struct sNible
{
  bit bit0;
  bit bit1;
  bit bit2;
  bit bit3;
}

struct sByte
{
 struct sNible usNible1;
 struct sNible usNible2;
}

union
{
   struct sByte usByte;
   int nByte;
} uByte;

Para escribir o leer en uno de los nibles:

Código: [Seleccionar]
uByte.usByte.usNible1 = 5;
printf("Valor: %u", uByte.usByte.usNible2);

Para escribir o leer en el byte:

Código: [Seleccionar]
uByte.nByte = 10;
printf("Valor: %u", uByte.nByte);

Un saludo
Título: Re: Manipular Byes y Nibles?... Imprimir cadena de Texto?
Publicado por: RedPic en 15 de Octubre de 2007, 19:06:40
Yo acostumbro a extraer los dos nibles de un byte sobre variables de 8 bits ...

int8 X, nibleBajo, nibleAlto;

X =0xAB;
nibleBajo = X & 0x0F;
nibleAlto = X  >> 4;

Y en otro orden de cosas ...

char  ID_SISTEMA[8];

Si el contenido de ID_SISTEMA termina con el valor 0x00, o sea que el último char que contenga sea '\0' entonces puedes enviarlo simplemente como

printf("%s",ID_SISTEMA);


Título: Re: Manipular Byes y Nibles?... Imprimir cadena de Texto?
Publicado por: LABmouse en 15 de Octubre de 2007, 19:51:32
Y en otro orden de cosas ...

char  ID_SISTEMA[8];

Si el contenido de ID_SISTEMA termina con el valor 0x00, o sea que el último char que contenga sea '\0' entonces puedes enviarlo simplemente como

printf("%s",ID_SISTEMA);


GRANDIOSO!!!!!  :-/
Título: Re: Manipular Byes y Nibles?... Imprimir cadena de Texto?
Publicado por: jfh900 en 15 de Octubre de 2007, 19:52:16
Efectivamente querido Diego podemos llegar al mismo punto por varios caminos. Ahora bien en efectividad son mucho mejores las estructuras dado que trabajas directamente en memoria y en tu caso implica utilizar registros intermedios (mas intrucciones y mas lento). Por lo demas el resultado es el mismo.

Un saludo.
Título: Re: Manipular Byes y Nibles?... Imprimir cadena de Texto?
Publicado por: MGLSOFT en 15 de Octubre de 2007, 21:37:55
Creo que ambos metodos son validos, las estructuras con seguridad le dan elegancia al programa, mientras el metodo del string esta muy original.
Cada uno podra ser utilizado mejor cuando dispongamos de poca ROM o RAM, aunque con los micros de hoy dia eso creo no es un problema... :mrgreen:
Título: Re: Manipular Byes y Nibles?... Imprimir cadena de Texto?
Publicado por: Nocturno en 16 de Octubre de 2007, 01:18:30
Efectivamente querido Diego podemos llegar al mismo punto por varios caminos. Ahora bien en efectividad son mucho mejores las estructuras dado que trabajas directamente en memoria y en tu caso implica utilizar registros intermedios (mas intrucciones y mas lento). Por lo demas el resultado es el mismo.

Un saludo.
¿Has visto cómo se compila esa operación con estructuras?. Muchas veces me he llevado la sorpresa que el compilador al final utiliza las mismas instrucciones de una manera o de otra.
Título: Re: Manipular Byes y Nibles?... Imprimir cadena de Texto?
Publicado por: RedPic en 16 de Octubre de 2007, 07:20:34
Y no solo eso (que compile igual con distinto código) sino que las conclusiones a las que llegues, que tal o cual forma de escribir tu código genera mas o menos código máquina, va a depender muy mucho de la versión del compilador que uses, y quizás lo aprendido para una 4.239 no tiene nada que ver con una 4.240 ya que los amables señores creadores del compilador han cambiado la forma de compilar ésta o aquella instrucción.

 
Título: Re: Manipular Byes y Nibles?... Imprimir cadena de Texto?
Publicado por: MGLSOFT en 16 de Octubre de 2007, 09:25:23
Y no solo eso (que compile igual con distinto código) sino que las conclusiones a las que llegues, que tal o cual forma de escribir tu código genera mas o menos código máquina, va a depender muy mucho de la versión del compilador que uses, y quizás lo aprendido para una 4.239 no tiene nada que ver con una 4.240 ya que los amables señores creadores del compilador han cambiado la forma de compilar ésta o aquella instrucción.

 

Heyy Diego!!
Quien tiene esas versiones del software???
Vas mas adelantado que los fabricantes del software!!! :D :D
Título: Re: Manipular Byes y Nibles?... Imprimir cadena de Texto?
Publicado por: jfh900 en 16 de Octubre de 2007, 12:36:08
Y no solo eso (que compile igual con distinto código) sino que las conclusiones a las que llegues, que tal o cual forma de escribir tu código genera mas o menos código máquina, va a depender muy mucho de la versión del compilador que uses, y quizás lo aprendido para una 4.239 no tiene nada que ver con una 4.240 ya que los amables señores creadores del compilador han cambiado la forma de compilar ésta o aquella instrucción.

Efectivamente en ciertos compiladores (y no quiero hacer referencia a ninguno, jejejejeje) se puede esperar cuanlquier cosa dado la cantidad de bug's que aparecen en funciones que iban bien y de repente fallan. Pero una de los principios de las estructuras es que estas se crean en memoria y se trabaja directamente sobre ellas, en definitiva no es mas ni menos que poner etiquetas a las posiciones de memoria. Si algún compilador no trabaja así con las estructuras mejor tirarle.

Y como una imagen vale más que mil palabras, aquí va la simulación y los correspondientes asm para ver la diferencia:

Código: [Seleccionar]
#include <16F84A.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading

#use delay(clock=4000000)
#use rs232(baud=9600)

typedef int1 bit;

struct sNible
{
  bit bit0;
  bit bit1;
  bit bit2;
  bit bit3;
};

struct sByte
{
 struct sNible usNible1;
 struct sNible usNible2;
};

union
{
   struct sByte usByte;
   int nByte;
} uByte;

void main()
{
   int numero;
   int8 X, nibleBajo, nibleAlto;

   uByte.usByte.usNible1 = 5;
   numero = uByte.usByte.usNible2;
   
   uByte.nByte = 10;
   printf("Valor: %u", uByte.nByte);
   
   X =0xAB;
   nibleBajo = X & 0x0F;
   nibleAlto = X  >> 4;
}

Y el listado en ASM:

Código: [Seleccionar]
.................... void main()
.................... {
*
007E:  CLRF   04
007F:  BCF    03.7
0080:  MOVLW  1F
0081:  ANDWF  03,F
0082:  BSF    03.5
0083:  BCF    05.0
0084:  BCF    03.5
0085:  BSF    05.0
....................    int numero;
....................    int8 X, nibleBajo, nibleAlto;
.................... 
....................    uByte.usByte.usNible1 = 5;
0086:  MOVLW  05
0087:  MOVWF  11
....................    numero = uByte.usByte.usNible2;
0088:  MOVF   12,W
0089:  MOVWF  13
....................     
....................    uByte.nByte = 10;
008A:  MOVLW  0A
008B:  MOVWF  11
....................    printf("Valor: %u", uByte.nByte);
008C:  CLRF   17
008D:  MOVF   17,W
008E:  CALL   004
008F:  INCF   17,F
0090:  MOVWF  0C
0091:  MOVWF  1A
0092:  CALL   012
0093:  MOVLW  07
0094:  SUBWF  17,W
0095:  BTFSS  03.2
0096:  GOTO   08D
0097:  MOVF   11,W
0098:  MOVWF  18
0099:  MOVLW  1B
009A:  MOVWF  19
009B:  GOTO   049
....................     
....................    X =0xAB;
009C:  MOVLW  AB
009D:  MOVWF  14
....................    nibleBajo = X & 0x0F;
009E:  MOVF   14,W
009F:  ANDLW  0F
00A0:  MOVWF  15
....................    nibleAlto = X  >> 4;
00A1:  SWAPF  14,W
00A2:  MOVWF  16
00A3:  MOVLW  0F
00A4:  ANDWF  16,F
.................... }
00A5:  SLEEP

Como se puede apreciar cuando trabajamos con estructuras, trabajamos directamente con posiciones de memoria sin utilizar registros intermedios.

Un saludo
Título: Re: Manipular Byes y Nibles?... Imprimir cadena de Texto?
Publicado por: Nocturno en 16 de Octubre de 2007, 13:04:06
Jesús, tengo que discrepar.

Las direcciones de memoria apuntan a bytes, no a nibbles. Cualquier cosa que hagas con nibbles requerirá de alguna argucia para diseccionar un byte.
Fíjate cómo compila tu ejemplo esta instrucción:
....................    uByte.usByte.usNible1 = 5;
0086:  MOVLW  05
0087:  MOVWF  11

El valor que hubiera en el nibble alto de uByte estaría machacado.
Título: Re: Manipular Byes y Nibles?... Imprimir cadena de Texto?
Publicado por: RedPic en 16 de Octubre de 2007, 13:04:50
Heyy Diego!!
Quien tiene esas versiones del software???

Que es un ejmplo, hombreeeeee  ja, ja, ja  :D :D :D
Título: Re: Manipular Byes y Nibles?... Imprimir cadena de Texto?
Publicado por: jfh900 en 16 de Octubre de 2007, 13:09:22
Jesús, tengo que discrepar.

Las direcciones de memoria apuntan a bytes, no a nibbles. Cualquier cosa que hagas con nibbles requerirá de alguna argucia para diseccionar un byte.
Fíjate cómo compila tu ejemplo esta instrucción:
....................    uByte.usByte.usNible1 = 5;
0086:  MOVLW  05
0087:  MOVWF  11

El valor que hubiera en el nibble alto de uByte estaría machacado.

Pues o el compilador o trata mal las estructuras o no son soportadas para nibbles, ya que los dos nibbles los ha separado como dos bytes. El caso es que no da ningún error ni advierte de nada. Bueno, esto da idea de como funciona CCS.

La prueba definitiva es:

uByte.usByte.usNible1 = A;
uByte.usByte.usNible2 = B;
printf("Valor: %X", uByte.nByte);

Deberia devolver en el LCD: "AB"

Un saludo
Título: Re: Manipular Byes y Nibles?... Imprimir cadena de Texto?
Publicado por: Nocturno en 16 de Octubre de 2007, 13:35:39
¿Puedes compilar ese ejemplo y pegar el resultado?, seguramente compilará bien, pero operando con los bytes para separar sus nibbles.
Mi experiencia con CCS es que es bastante "listo". Si antes no ha tenido cuidado de no machacar el byte, será porque ha visto que no había un valor establecido con anterioridad.
Título: Re: Manipular Byes y Nibles?... Imprimir cadena de Texto?
Publicado por: RedPic en 16 de Octubre de 2007, 13:38:50
Compila tambien con las instrucciones puestas al contrario, para ver si trata un solapamiento de medios bytes

uByte.usByte.usNible2 = B;
uByte.usByte.usNible1 = A;
printf("Valor: %X", uByte.nByte);