¿Puedo pasar un registro de bits como argumento de función en el compilador Hi-Tech C para PIC16?

3

¿Hay alguna forma de pasar un bit del registro de un PIC como parámetro de función?

Tomando, por ejemplo, el PIC16F887, sus registros (SFR) y los bits individuales se definen como barbechos en el archivo de encabezado correspondiente ( ...\HI-TECH Software\PICC.80\include\pic16f887.h ):

volatile       unsigned char    PORTB       @ 0x006;

volatile       bit  RB3     @ ((unsigned)&PORTB*8)+3;

¿Cómo puedo pasar el bit RB3 como parámetro en una función para que me permita llamar a la función de esta manera?

setBitHigh (RB3);

¿Cuál sería el prototipo de la función?

Estoy usando el compilador HI-TECH C para PIC10 / 12/16 MCU (Modo PRO) V9.80.

EDITAR: La función setBitHigh es solo un ejemplo simplificado. De hecho, quiero pasar bits como parámetros a funciones más complejas y poder elegir en tiempo de ejecución qué bits debe usar la función.

    
pregunta m.Alin

3 respuestas

1

Quizás esto funcione, pero no es el estándar C:

void setBitHigh( bit *b ){
   b = 1;
}
setBitHigh( & RB3 );

Si no, no hay una forma directa de hacer lo que quieres. Por supuesto, puede devolver el valor de la función y luego asignarlo:

RB3 = newBitValue();

o puede pasar la función tanto la dirección de byte como el desplazamiento, y dejar que la función realice el trabajo sucio:

void setBitHigh( unsigned char *a, bit_offset b ){
   *a |= ( 1 << b );
}
setBitHigh( & PORTB, 3 );
    
respondido por el Wouter van Ooijen
1

Lo que realmente estás preguntando es una pregunta del compilador. Mire el conjunto de instrucciones PIC16 y verá que no hay forma de direccionar directamente los bits en la memoria de datos desde las direcciones computadas en tiempo de ejecución. Las direcciones son para bytes enteros de 8 bits.

Sin embargo, podría establecer una convención para pasar información que identifique un bit en particular. Independientemente de lo que haga, el PIC no tratará de forma nativa un bit individual de la descripción de su dirección, por lo que se requieren algunas instrucciones para leer o escribir un bit seleccionado en el tiempo de ejecución. Puede definir que las direcciones de bits tengan 3 bits extra bajos, que serían el desplazamiento de bits dentro del byte, o podría pasar una máscara del bit dentro de su byte, o una dirección de bytes y bits separada, solo para nombrar 3 posibles convenciones.

Sin embargo, piensa cuidadosamente por qué realmente quieres hacer esto. Dado el conjunto de instrucciones PIC, es mejor conocer el bit dentro de un byte en el momento de la compilación, ya que todas las instrucciones de direccionamiento de bits tienen un número de bit fijo codificado dentro de ellas. Quizás la mejor respuesta es dar un paso atrás y pensar en lo que realmente estás tratando de lograr, y llegar a un esquema que use el conjunto de instrucciones PIC en lugar de luchar contra él. Algunas cosas increíbles son posibles con un poco de planificación y preprocesamiento avanzado. Explique lo que está intentando lograr dos niveles más arriba, y tal vez podamos sugerir formas de hacer innecesario el direccionamiento de bits en tiempo de ejecución.

    
respondido por el Olin Lathrop
0

No hay ningún mecanismo en HT-PIC para pasar un bit de registro como parámetro. Hay una variedad de formas en las que se puede lograr un resultado de este tipo, que involucra varios compromisos con respecto a la velocidad de ejecución, el código del sitio de la llamada y el código del método llamado.

El enfoque más simple es probablemente pasar una máscara de bits como un parámetro y una dirección o un desplazamiento de dirección de E / S como un segundo. Si la dirección siempre estará en uno de los bancos superiores, o siempre en uno de los bancos inferiores, esto significará pasar dos bytes de parámetros.

Si los bits de interés de E / S siempre estarán dentro de un pequeño grupo de registros (por ejemplo, PORTA-PORTH), se podrían comprimir ambas piezas de información de manera razonablemente eficiente en un byte; Yo sugeriría que para codificar los bits 4-7, uno tenga los cuatro bits superiores representando una máscara de bits, tenga establecido el bit 3 y los bits 0-2 representen un desplazamiento de dirección de E / S. Para los bits 0-3, haga que los 4 bits superiores representen una máscara de bits desplazada a la izquierda 4 bits, el bit 3 se borre y que los bits 0-2 representen el desplazamiento de la dirección. Si uno puede permitirse un par de ubicaciones globales para mantener la dirección y la máscara de bits, entonces podría tener una rutina:

void calcIo(uint8_t portBit)
{
  ioPort = (&PORTA)+(portBit & 7);

  ioBit = portBit & 0xF0;
  if (!portBit & 8)
    ioBit = (ioBit << 4) | (ioBit >> 4); // Allow SWAPF
}

La última declaración de aspecto extraño debería permitir que el compilador use una instrucción condicional SWAPF en ioBit [la expresión (ioBit << 4) siempre será cero, si no estuviera allí, el compilador se sentiría obligado a enmascararlos bits].

    
respondido por el supercat

Lea otras preguntas en las etiquetas