¿Se pueden asignar pines individuales de diferentes puertos de un microcontrolador a un registro y se pueden cambiar sus valores al cambiar el valor del registro?

12

P: ¿Se pueden asignar pines individuales de diferentes puertos de un microcontrolador a un registro y se pueden cambiar sus valores al cambiar el valor del registro?

Escenario: He agotado algunos pines de cada puerto (8 bits) del microcontrolador. Ahora quiero conectar un dispositivo que necesita un bus de 8 bits (supongamos que D0 a D7 EN SECUENCIA), es decir, necesito 8 pines del controlador para poder conectarlos uno a uno

portx0  -> D0 // x is the name of port followed by bit location on that port
portx1  -> D1
...
portx7  -> D7

pero no tengo un puerto completo de 8 pines que pueda conectar con este dispositivo, más bien tengo algunos pines de portx, algunos de porty y algunos pines de portz. El nuevo escenario de conexión es como (conexión del microcontrolador al dispositivo respectivamente)

portx0  -> D0
portx1  -> D1
portx2  -> D2
porty4  -> D3
porty5  -> D4
porty6  -> D5
porty7  -> D6
portz1  -> D7

En esta condición, si quiero enviar un valor, diga

unsigned char dataReg = 0xFA;

a mi dispositivo desde el controlador Tengo que realizar operaciones a nivel de bits en el valor a enviar y configurar cada pin según el valor en el registro individualmente. Por ejemplo

portx0 = ((dataReg & 0x01) >> 0 );  // Masking and shifting as bit position
portx1 = ((dataReg & 0x02) >> 1 );
portx2 = ((dataReg & 0x04) >> 2 );
porty4 = ((dataReg & 0x08) >> 3 );
porty5 = ((dataReg & 0x10) >> 4 );
porty6 = ((dataReg & 0x20) >> 5 );
porty7 = ((dataReg & 0x40) >> 6 );
portz1 = ((dataReg & 0x80) >> 7 );

Ahora, llegando a la pregunta principal, para evitar estos cálculos individuales en cada bit en puertos diferentes, ¿pueden los pines individuales de un puerto diferente de un microcontrolador asignarse a un registro y sus valores cambiarse al cambiar el valor del registro?

    
pregunta Osaid

4 respuestas

6

Parece que tu pregunta se reduce a tener un valor de 8 bits en el firmware, y querer leer y escribir eso desde y hacia una colección arbitraria de pines de puerto.

No hay una forma directa de hardware para hacer esto. Debe escribir dos rutinas, una para leer el valor de 8 bits y otra para escribirlo. Otros han mencionado el uso de sindicatos, pero esa es una mala idea. Con las uniones, tiene que tratar cada bit por separado, y el código se vuelve dependiente del orden de bits del micro. Este podría ser el camino a seguir de todos modos si todos los 8 bits se dispersan de forma completamente independiente. Si es así, es poco lo que puede hacer, pero hacer un código especial para cada bit.

La mejor manera de hacerlo, especialmente si puede agrupar los bits en unos pocos trozos contiguos en los puertos físicos es usar enmascaramiento, desplazamiento y ORing. Por ejemplo, si los tres bits bajos del byte interno están en los bits < 6-4 > de un puerto, desplace a la derecha ese valor de puerto en 4 y Y con 7 para obtener esos bits en su posición final. Desplace y enmascare (o enmascare y desplace) los bits de otros puertos en su lugar y reúna el último byte de 8 bits ORENTANDO los resultados en él.

Este tipo de giros de bits de bajo nivel es más fácil de hacer en un ensamblador que en C. Probablemente pondría las rutinas de lectura y escritura en un solo módulo del ensamblador y haría que la interfaz sea llamable desde C.

    
respondido por el Olin Lathrop
4

En general esto no es posible. Que yo sepa, no es posible con los PIC.

Sé que solo hay un microcontrolador que puede hacer esto, el Cypress PSoC . Es un sistema altamente configurable en chip. Una de las muchas cosas que le permite hacer es definir literalmente su propio registro (1-8 bits) y conectarlo a los pines que desee, o incluso a los circuitos internos.

Porejemplo,aquíhecreadounregistrodecontrolde6bits.5delosbitsvandirectamentealospines,mientrasqueel6°bitloestoyusandoparaXORconlaentradadeun7°pin.

En el chip, puedo elegir asignar estos pines a cualquiera de los pines GPIO disponibles. (Son los grises uno la imagen)

    
respondido por el Rocketmagnet
-1

Puedes probar lo siguiente. Escriba una estructura propia que se asigne a los respectivos pines de los 2 puertos (que se usarán). Ahora, la actualización del valor en este registro establecerá / restablecerá los pines de esos 2 puertos. ¡Solo prueba y haznos saber si funcionó!

Confío en que esto debería funcionar.

    
respondido por el Rahul Ranjan
-1

Si he entendido la pregunta correctamente, es bastante fácil en C:

Declaración de tipo genérico, puede reutilizarse para cualquier registro:

typedef union    // Generic 8-bit register Type
{
  uint8 reg; // Whole register
  struct
  {
    unsigned  bit7     : 1;  // Bit 7 
    unsigned  bit6     : 1;  // Bit 6 
    unsigned  bit5     : 1;  // Bit 5 
    unsigned  bit4     : 1;  // Bit 4 
    unsigned  bit3     : 1;  // Bit 3 
    unsigned  bit2     : 1;  // Bit 2 
    unsigned  bit1     : 1;  // Bit 1 
    unsigned  bit0     : 1;  // Bit 0 
  } bit;
} typ_GENERIC_REG8;

Entonces, para definir un puerto que queremos abordar:

#define MCU_GPO_PORTx   (*(volatile typ_GENERIC_REG8 *)(0x12345678)) // Number is address

Y para girar directamente un pin en ese puerto:

#define MCU_PORTx_PINn  (MCU_GPO_PORTx.bit.bit0)

En el código:

MCU_PORTx_PINn = 1; // Set pin high

Registro completo:

MCU_GPO_PORTx.reg = 0xF; // All pins high

Vale la pena leer sobre estructuras, uniones, typedefs y enums: todo esto hace que la vida sea mucho más agradable en incrustado & en general!

    
respondido por el John U

Lea otras preguntas en las etiquetas