TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: aitopes en 05 de Diciembre de 2009, 17:43:31

Título: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: aitopes en 05 de Diciembre de 2009, 17:43:31
Hola!
El problema que tengo es bien simple: tengo una variable de 16bits, y quiero trabajar con los dos bytes que la componen por separado.  Supongamos que la variable tipo Word es C y que A y B son dos variables tipo int8:

¿De que manera puedo hacer que A contenga el byte alto y B el byte bajo de C?  

Debe ser la pavada más grande del mundo, pero no me acuerdo de haberlo usado nunca  :lol:
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: RALF2 en 05 de Diciembre de 2009, 18:04:06
Que tal aitopes!
Bueno una forma seria usar desplazamiento de los bytes pa leer el byte bajo y luego el alto y creo que con Sprintf se puede tambien pero no recuerdo!  :?

Saludos
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: Nocturno en 05 de Diciembre de 2009, 18:11:12
Esto en Ansi C
A = C>>8;
B = C & 0xFF;

Y en CCS también sirve esto:
A = make8(C,1);
B = make8(C,0);
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: migsantiago en 05 de Diciembre de 2009, 18:11:41
Hola Ariel

Aquí la función que buscas.

Código: [Seleccionar]
make8( )

--------------------------------------------------------------------------------

 

Syntax:
 i8 = MAKE8(var, offset)

 
 
Parameters:
 var is a 16 or 32 bit integer.

offset is a byte offset of 0,1,2 or 3.
 
Returns:
 An 8 bit integer
 
Function:
 Extracts the byte at offset from var. Same as: i8 = (((var >> (offset*8)) & 0xff) except it is done with a single byte move.
 
Availability:
 All devices
 
Requires:
 Nothing

 Examples:
 int32 x;

int y;

y = make8(x,3);  // Gets MSB of x

Example Files:
 None

Also See:
 make16(), make32()

jaja me ganó Manolo por segundos
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: Nocturno en 05 de Diciembre de 2009, 18:12:40
:)

Te has enfrentado en duelo al dedo más rápido del condado  :D
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: aitopes en 05 de Diciembre de 2009, 18:14:25
:)

Gracias!
Al final, lo he hecho como dice Santiago.

Ya puestos a preguntar....si quiero los 4 bits mas altos o mas bajos de un Byte no me queda otra que trabajar "a pedal", no hay una funcion como esta para eso, no?  :lol:
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: migsantiago en 05 de Diciembre de 2009, 18:18:25
:)

Te has enfrentado en duelo al dedo más rápido del condado  :D

jajaja es que estoy usando el tocuhpad de la aspire one y me cuesta trabajo mover el mouse  :D

Ya puestos a preguntar....si quiero los 4 bits mas altos o mas bajos de un Byte no me queda otra que trabajar "a pedal", no hay una funcion como esta para eso, no?  :lol:

Mi no entender...  :z)

Hay otra forma de obtener los bytes sin tener que rotarlos o sin usar make8 y sería usando casting de apuntadores, por ejemplo si quisieras obtener los 3 bytes altos de un int32 depositándolos en otro int32.
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: Nocturno en 05 de Diciembre de 2009, 18:23:21
Utilizando los operadores de máscara y desplazamiento, como en el primer ejemplo que he puesto, puedes obtener también el nibble alto o el bajo de un byte:

nibble_alto = C >> 4;
nibble_bajo = C & 0xF;

Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: RALF2 en 05 de Diciembre de 2009, 18:26:39
Que va yo llegue primero   :D
Interesante ese make8 no lo conocia, gracias por la informacion!  :mrgreen:

Saludos
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: aitopes en 05 de Diciembre de 2009, 18:30:49
Utilizando los operadores de máscara y desplazamiento, como en el primer ejemplo que he puesto, puedes obtener también el nibble alto o el bajo de un byte:

nibble_alto = C >> 4;
nibble_bajo = C & 0xF;



La neurona no termina de arrancarme hoy... :)

Quiero hacer que (por ejemplo) los 4 bits más bajos del puerto A tengan la mitad mas alta de una variable int8 ....

¿como hago para lograrlo sin "toquetear" los otros bits?

(Hoy viene pesada la tarde...ja ja ja)
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: Nocturno en 05 de Diciembre de 2009, 18:54:10
Al principio del programa defines esto:
#byte PORTA xxx // en las xxx pones la dirección de memoria del puerto A

Y luego haces lo siguiente, asumiendo que tu variable se llama V
PORTA = (PORTA & 0xF0) | (V >> 4);
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: aitopes en 05 de Diciembre de 2009, 18:59:36
Joder!
Buenisimo!

Te voy a decir como lo hacia solo para que te rias un rato... ;)

   output_bit (PIN_C7 ,bit_test(byte_bajo, 7));
   output_bit (PIN_C6 ,bit_test(byte_bajo, 6));
   output_bit (PIN_C5 ,bit_test(byte_bajo, 5));
   output_bit (PIN_C4 ,bit_test(byte_bajo, 4));
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: RALF2 en 05 de Diciembre de 2009, 19:05:15
Que mas aitopes!
Bajate el ejemplo

Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: Nocturno en 05 de Diciembre de 2009, 19:07:09
Joder!
Buenisimo!

Te voy a decir como lo hacia solo para que te rias un rato... ;)

   output_bit (PIN_C7 ,bit_test(byte_bajo, 7));
   output_bit (PIN_C6 ,bit_test(byte_bajo, 6));
   output_bit (PIN_C5 ,bit_test(byte_bajo, 5));
   output_bit (PIN_C4 ,bit_test(byte_bajo, 4));


No es para reírse, hombre, es la forma más lógica de hacerlo si no tienes dominado los operadores de máscara.
De todas formas, habría que compilar las dos opciones para ver cuál ocupa menos.
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: aitopes en 05 de Diciembre de 2009, 19:11:14
Joder!
Buenisimo!

Te voy a decir como lo hacia solo para que te rias un rato... ;)

   output_bit (PIN_C7 ,bit_test(byte_bajo, 7));
   output_bit (PIN_C6 ,bit_test(byte_bajo, 6));
   output_bit (PIN_C5 ,bit_test(byte_bajo, 5));
   output_bit (PIN_C4 ,bit_test(byte_bajo, 4));


No es para reírse, hombre, es la forma más lógica de hacerlo si no tienes dominado los operadores de máscara.
De todas formas, habría que compilar las dos opciones para ver cuál ocupa menos.

O cual es más rápido...en mi caso me va a interesar la velocidad. Pero por ahora no importa. Cuando el proyectin esté mas avanzado, quizas esta partecita pueda hacerse en ASM y a otra cosa.

Pero por el momento me sirve de mucho la ayuda que me han dado. Me bajo el ejemplo de RALF2 y tomo nota del método de la máscara ;)

Gracias!
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: RALF2 en 05 de Diciembre de 2009, 19:15:55
Alli esta la mascara del zorro no te preocupes por ello!!!   :D

Saludos
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: Nocturno en 05 de Diciembre de 2009, 19:32:11
Pues la curiosidad me podía, así que he compilado los dos ejemplos. Júzgalo tú mismo:

Código: [Seleccionar]
....................    output_bit (PIN_C7 ,bit_test(byte_bajo, 7));
69A4:  MOVLB  1
69A6:  BTFSC  xE5.7
69A8:  BRA    69AE
69AA:  BCF    F8B.7
69AC:  BRA    69B0
69AE:  BSF    F8B.7
69B0:  BCF    F94.7
....................    output_bit (PIN_C6 ,bit_test(byte_bajo, 6));
69B2:  BTFSC  xE5.6
69B4:  BRA    69BA
69B6:  BCF    F8B.6
69B8:  BRA    69BC
69BA:  BSF    F8B.6
69BC:  BCF    F94.6
....................    output_bit (PIN_C5 ,bit_test(byte_bajo, 5));
69BE:  BTFSC  xE5.5
69C0:  BRA    69C6
69C2:  BCF    F8B.5
69C4:  BRA    69C8
69C6:  BSF    F8B.5
69C8:  BCF    F94.5
....................    output_bit (PIN_C4 ,bit_test(byte_bajo, 4));
69CA:  BTFSC  xE5.4
69CC:  BRA    69D2
69CE:  BCF    F8B.4
69D0:  BRA    69D4
69D2:  BSF    F8B.4
69D4:  BCF    F94.4

Código: [Seleccionar]
....................    PORTC = (PORTC & 0xF0) | (byte_bajo >> 4);
69D6:  MOVF   F82,W
69D8:  ANDLW  F0
69DA:  MOVWF  xE6
69DC:  SWAPF  xE5,W
69DE:  MOVWF  00
69E0:  MOVLW  0F
69E2:  ANDWF  00,F
69E4:  MOVF   00,W
69E6:  IORWF  xE6,W
69E8:  MOVWF  F82
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: aitopes en 05 de Diciembre de 2009, 19:52:37
Wowwww!!!
Terrible diferencia.
Ya lo tengo funcionando con tu sistema....y anda de maravillas.  8)

Gracias!
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: MGLSOFT en 07 de Diciembre de 2009, 08:24:30
Ademas es la mas segura!!
Imaginate que tienes una interrupcion por tiempo que utiliza el valor del resultado de una u otra operacion.
Como la interrupcion puede caer en cualquier momento, en el primer caso supongamos cae en el momento que estas haciendo el tercer output_bit.
La variable a usar estara actualizada a medias, es decir el bit 1 y 2 estaran actualizados y el bit 3 y 4 no.
Puede que no afecte pero si lo hace puede hacer un gran lio en tu programa, y dificil de encontrar el problema.

En el segundo caso puede ocurrir la interrupcion tambien en cualquier momento, pero solo puede encontrar el valor completo actualizado o no, pero no podra ofrecerte dudas en que paso !! :lol: :lol:
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: aitopes en 07 de Diciembre de 2009, 08:41:04
Hola Marcos!  :mrgreen:

Si, es cierto lo que decis. No se si es ABSOLUTAMENTE segura, por que no se trata de "una sola instruccion", tal como dice Manolo, son un puñado:

Código: [Seleccionar]
....................    PORTC = (PORTC & 0xF0) | (byte_bajo >> 4);
69D6:  MOVF   F82,W
69D8:  ANDLW  F0
69DA:  MOVWF  xE6
69DC:  SWAPF  xE5,W
69DE:  MOVWF  00
69E0:  MOVLW  0F
69E2:  ANDWF  00,F
69E4:  MOVF   00,W
69E6:  IORWF  xE6,W
69E8:  MOVWF  F82

Podria caer al medio de todo eso y tambien causar problemas. Pero coincido con tu punto de vista: al ser menos cantidad, las posibilidades son menores. De todos modos, hasta ahora no estoy usando interrupciones en este proyecto, y no creo que me hagan falta.  :lol:
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: Nocturno en 07 de Diciembre de 2009, 08:54:43
Pero aunque te caiga la interrupción por ahí en medio, no te encontrarás un dato incongruente en el puerto, porque todos los bits se escriben en un sólo paso.
Título: Re: CCS: ¿Como tomar cada byte que compone un word?
Publicado por: Suky en 07 de Diciembre de 2009, 09:09:52
Exactamente, fíjense que en el método de Manolo, el puerto se salva en la primera instrucción, si cayera una interrupción se guardaría en el salvado de contexto y nada cambiaría ;-)




Saludos.