Nombres de PUERTO y CONST en una matriz

uC: PIC18F46K20

Quiero escanear, en un bucle, diferentes puertos y probar diferentes pines en cada puerto.

Tengo diferentes tableros de destino, por lo que quiero poder configurar rápidamente cada tablero en arreglos CONST. Así que creé matrices como estas:

const char my_ports[4] = {PORTB, PORTB, PORTD, PORTA}; // <- this is the PROBLEM causing line
const char my_pins[4] = {3, 7, 1, 4};

para poder escanear esos puertos en un bucle:

// NEW version of the func.
void pin_update(void)
{
  for (k=0; k<=3; k++)
  {
    if (my_ports[k] & my_pins[k])
    {
     // and actions here ........
    }
  }
}

Pero el compilador aparece con un error:

        "my_ports[] ... constant expression required"

Usé el enfoque de pasar el nombre del puerto (por ejemplo, PORTB) en la versión anterior del código cuando cada pin se probó individualmente, por ejemplo. :

    pin_update(PORTB, 3);   
            // ...
    pin_update(PORTD, 1);   

// OLD version of the func:
void pin_update(char prt, char pn)
{
    if (prt & pn)
    {
     // and actions here ........
    }
}

y todo estuvo bien y el código funcionó correctamente. Pero como ve, PORTB está codificado en una lista de parámetros. Y ahora quiero ejecutar las 'actualizaciones de pines' anteriores en un bucle.

Entonces surgió el problema cuando quería enumerar los nombres de los puertos en la matriz CONST. Probé varias cosas con la transmisión a las direcciones de los puertos, etc., nada funcionó. Al compilador todavía no le gustó.

my_pinsparece sospechoso ¿Está seguro de que no quiere decir 1 << 3etc.?
no, 'my_pins[]' es una matriz de números de pin que se relacionan con 'my_ports[] de nombres de puertos (direcciones). Entonces, el ciclo 'for (k=0; k<=3; k++)' primero prueba si PORTB.3, luego PORTB.7, etc. Y funciona bien en código real en destino real.

Respuestas (2)

El compilador es correcto. PORTx no son constantes; dan como resultado el valor almacenado en el hardware. Debe almacenar un puntero al puerto y luego quitarle la referencia cuando corresponda.

const *char my_ports[4] = {&PORTB, &PORTB, &PORTD, &PORTA};
const char my_pins[4] = {3, 7, 1, 4};

 ...

void pin_update(void)
{
  for (k=0; k<=3; k++)
  {
    if (*(my_ports[k]) & my_pins[k])
    {
     // and actions here ........
    }
  }
}
Sí, es mejor, pero desafortunadamente al compilador tampoco le gusta eso: Advertencia ... conversión ilegal entre tipos de puntero: puntero a carácter volátil sin firmar -> puntero a carácter const sin firmar Así que probé esto: const char *my_ports[4] = {&PORTB , &PORTB, &PORTD, &PORTA}; y el compilador no se queja, pero la construcción del código es incorrecta. En el depurador miré la matriz y se veía así: my_ports [0] 0x81 [1] 0x0F [2] 0x81 [3] 0x0F NOTA: el archivo de encabezado del compilador XC8 para pic18f46k20 micro tiene esto: // Registro: PORTB extern volatile unsigned char PUERTO @ 0xF81; Volveré sobre esto pronto....
es decir, la dirección del puerto tiene una longitud INT, así que la cambié a: const unsigned int *my_ports[4] = {&PORTB, &PORTB, &PORTD, &PORTA}; Luego, en el depurador, vi esto: my_ports [0] 0x0F81 [1] 0x0F81 El compilador aún emite una advertencia similar sobre la conversión ilegal, pero al menos la matriz de punteros está bien. Sin embargo, tendré que depurar el código para ver si los valores de los pines se leen correctamente y luego, de alguna manera, arreglar el compilador que se queja también. Volveré con los resultados...

Gracias Ignacio por la dirección correcta.

Aquí está la solución final que realmente funciona bien: ningún compilador se queja y los resultados durante la ejecución del programa también son correctos, es decir, el código verifica correctamente los bits individuales de cada puerto.

volatile unsigned char* const my_ports[4] = {&PORTB, &PORTB, &PORTD, &PORTA};
const char my_pins[4] = {3, 7, 1, 4};

y la función que usa el pin_update() anterior está en la forma sin cambios de Ignacio:

    void pin_update(void)
    {
        for (k=0; k<=3; k++)
        {
            if (*(my_ports[k]) & my_pins[k])
            {
             // and actions here ........
            }
        }
    }

Así que ahora my_ports[] es una matriz de punteros constantes a caracteres volátiles sin firmar, y está bien porque las direcciones que contiene esta matriz son para direcciones de puertos de hardware reales de tipos de 'caracteres volátiles sin firmar' definidos en el archivo de encabezado PIC18F46K20 de la siguiente manera:

extern volatile unsigned char PORTB @ 0xF81; 
extern volatile unsigned char PORTC @ 0xF82; // etc...