Autor Tema: Manejar un entero de 32bits bit a bit  (Leído 126 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado CarlosF

  • PIC10
  • *
  • Mensajes: 1
Manejar un entero de 32bits bit a bit
« en: 21 de Febrero de 2021, 17:57:39 »
Saludos, hace un par de días inicié un proyecto personal de Emisión de Datos por Infrarrojo, utilizando el protocolo NEC. La cuestión es que buscando por internet me topé con un programa que hace precisamente lo que quiero, sin embargo el mismo está elaborado en el software de CCS, pero me interesa llevarlo a MikroC o MPLAB. El punto es que llevo traducido casi todo el programa, pero hay una instrucción en particular que no se como trasladarla a los otros softwares y es la siguiente.

#bit variable=byte.bit; (Que entiendo, en CCS esta instrucción crea una variable del nombre que escojamos y le asigna la dirección de un byte que en este caso es otra variable de tipo unsigned int32 que almacena el código Hexadecimal del dato que quiero enviar con el protocolo NEC, y bit es la posición del bit de ese dato).

Viéndose algo parecido a lo siguiente: 

#bit uno=codigo.31;

En el programa, lo se que hace es comparar el bit 31 del byte codigo y si este es un 1 o un 0 activa un PWM configurado para trabajar como el protocolo NEC indica. Algo como lo siguiente:

if(uno){...}
else{...}

Luego desplaza todo el dato del byte codigo hacia la izquierda una posición "codigo <<= 1;", quedando el bit 30 en la posición 31. y Así hasta que termine los 32 bits del codigo.

Mi pregunta es si existe una instrucción parecida o como la replico (#bit...) en MikroC o MPLAB.

Gracias de antemano.  :)

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 17812
    • MicroPIC
Re:Manejar un entero de 32bits bit a bit
« Respuesta #1 en: 22 de Febrero de 2021, 03:35:32 »
Para escribir esto en C estándar:
Código: [Seleccionar]
#bit uno = codigo.31;
podrías hacer:
Código: [Seleccionar]
uint_8 uno = (((1<<31) & codigo)>0)
Un saludo desde Sevilla, España.
Visita MicroPIC                                                                                        ɔ!doɹɔ!ɯ ɐʇ!s!ʌ

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5469
Re:Manejar un entero de 32bits bit a bit
« Respuesta #2 en: 24 de Febrero de 2021, 05:16:44 »
No estoy seguro de cómo funciona CCS, pero en otros compiladores se puede hacer algo así:
Código: C
  1. typedef union {
  2.    unsigned char byte;
  3.    struct {
  4.        unsigned b0:1;
  5.        unsigned b1:1;
  6.        unsigned b2:1;
  7.        unsigned b3:1;
  8.        unsigned b4:1;
  9.        unsigned b5:1;
  10.        unsigned b6:1;
  11.        unsigned b7:1;
  12.    };
  13. } BYTE;
  14.  
  15. BYTE a;
  16.  
  17. main() {
  18.    a.byte = 128;
  19.    a.b3 = 1;
  20. }
  21.  

Se puede ampliar sin problema para utilizar unsigned long para campos de 32 bits.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 17812
    • MicroPIC
Re:Manejar un entero de 32bits bit a bit
« Respuesta #3 en: 24 de Febrero de 2021, 05:51:16 »
Mucho más elegante, sin duda
Un saludo desde Sevilla, España.
Visita MicroPIC                                                                                        ɔ!doɹɔ!ɯ ɐʇ!s!ʌ

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8030
Re:Manejar un entero de 32bits bit a bit
« Respuesta #4 en: 24 de Febrero de 2021, 08:16:50 »
Si queres el test de un bit en CCS, usas:

bit_test(variable,bit);

La solucion que planteaste requiere definir todos los bits lo cual es feo, tedioso, y sin sentido jejej.

Respecto a las soluciones.
La solucion de Picuino es "mas elegante" hasta cierto punto, a veces entre compilador y compilador no hay nada que defina un comportamiento o el orden de los bits en un bitfield.
Ademas para este caso donde tenes que "barrer" el numero, no tiene mucho sentido, doy el ejemplo al final. Pero si solo quiere acceder a 1 solo bit, no tiene tampoco sentido hacer todo una estructura para eso. Tal ves para otros casos si.

Otra solucion pero enviandolo desde el bit 0 seria (es destructivo para la variable codigo):

Código: C
  1. for ( x=0; x<32 ; x++, codigo >>= 1){
  2.   if(codigo%2) {
  3.     enviar_cero();
  4.   }else{
  5.     enviar_uno();
  6.   }
  7. }

Por supuesto el for tambien lo podria usar para el otro caso que dio Nocturno (esta vez "codigo" no se modifica, y podes hacerlo en ambas direcciones)

Código: C
  1. for ( x=0; x<32 ; x++){
  2.   if((1<<x) & codigo) {
  3.     enviar_uno();
  4.   }else{
  5.     enviar_cero();
  6.   }
  7. }


En cambio enviarlo con struct seria algo así (se resume ya que serian 32 lineas):

Código: C
  1. enviar(a.b0);
  2. enviar(a.b1);
  3. enviar(a.b2);
  4. ....
  5. enviar(a.b31);

Bastante mas y menos elegante ahora. Pero lo que contas es como lo hiciste antes... Ya que podrias haber hecho lo mismo en CSS


Código: C
  1. for ( x=0; x<32 ; x++){
  2.   if(bit_test(codigo,x)) {
  3.     enviar_uno();
  4.   }else{
  5.     enviar_cero();
  6.   }
  7. }


 

anything