TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado 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:
-
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
-
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);
-
Hola Ariel
Aquí la función que buscas.
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
-
:)
Te has enfrentado en duelo al dedo más rápido del condado :D
-
:)
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:
-
:)
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.
-
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;
-
Que va yo llegue primero :D
Interesante ese make8 no lo conocia, gracias por la informacion! :mrgreen:
Saludos
-
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)
-
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);
-
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));
-
Que mas aitopes!
Bajate el ejemplo
-
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.
-
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!
-
Alli esta la mascara del zorro no te preocupes por ello!!! :D
Saludos
-
Pues la curiosidad me podía, así que he compilado los dos ejemplos. Júzgalo tú mismo:
.................... 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
.................... 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
-
Wowwww!!!
Terrible diferencia.
Ya lo tengo funcionando con tu sistema....y anda de maravillas. 8)
Gracias!
-
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:
-
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:
.................... 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:
-
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.
-
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.