P: ¿Se pueden asignar pines individuales de diferentes puertos de un microcontrolador a un registro y cambiar sus valores al cambiar el valor del registro?
Escenario: He usado algunos pines de cada puerto (8 bits) del microcontrolador. Ahora quiero conectar un dispositivo que necesita un bus de 8 bits (supongamos D0 a D7 EN SECUENCIA), es decir, necesito 8 pines del controlador para poder conectarlos de manera individual
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 puedo 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 decir
unsigned char dataReg = 0xFA;
en mi dispositivo desde el controlador, tengo que realizar operaciones con bits en el valor que se enviará y establecer cada pin de acuerdo con 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, volviendo a la pregunta principal, para evitar estos cálculos individuales en cada bit en diferentes puertos, ¿se pueden asignar pines individuales de diferentes puertos de un microcontrolador a un registro y cambiar sus valores al cambiar el valor del registro?
Respuestas:
Parece que su pregunta se reduce a tener un valor de 8 bits en el firmware y querer leerlo y escribirlo desde y hacia una colección arbitraria de pines de puerto.
No hay 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, debe tratar cada bit por separado, y el código se vuelve dependiente del orden de bits del micro. De todos modos, este podría ser el camino a seguir si todos los 8 bits se dispersan de forma completamente independiente. Si es así, es poco lo que puede hacer sino crear un código especial para cada bit.
La mejor manera de hacer esto, especialmente si puede agrupar los bits en algunos fragmentos contiguos en los puertos físicos es usar enmascaramiento, desplazamiento y OR. Por ejemplo, si los tres bits bajos del byte interno están en los bits <6-4> de un puerto, cambie a la derecha ese valor del puerto en 4 y AND con 7 para colocar esos bits en su posición final. Desplazar y enmascarar (o enmascarar y desplazar) bits de otros puertos en su lugar y ensamblar el byte final de 8 bits OR colocando los resultados en él.
Este tipo de twiddling de bits de bajo nivel es más fácil de hacer en ensamblador que C. Probablemente pondría las rutinas de lectura y escritura de bytes en un solo módulo ensamblador y haría que la interfaz se pueda llamar desde C.
fuente
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, literalmente, definir su propio registro (1-8 bits) y conectarlo a cualquier pin que desee, o incluso a circuitos internos.
Por ejemplo, aquí he creado un registro de control de 6 bits. 5 de los bits van directamente a los pines, mientras que el sexto bit lo estoy usando para XOR con la entrada de un séptimo pin.
En el chip, puedo elegir asignar estos pines a cualquiera de los pines GPIO disponibles. (Son los grises uno la imagen)
fuente
Puedes probar lo siguiente. Escriba una estructura propia que se asigne a los pines respectivos de los 2 puertos (que se utilizarán). Ahora, actualizar el valor en este registro establecerá / restablecerá los pines de esos 2 puertos. ¡Solo intenta y dinos si funcionó!
Estoy seguro de que esto debería funcionar.
fuente
Si he entendido la pregunta correctamente, es bastante fácil en C:
Declaración de tipo genérico, se puede reutilizar para cualquier registro:
Entonces, para definir un puerto que queremos abordar:
Y para girar directamente un pin en ese puerto:
En codigo:
Registro completo:
Vale la pena leer sobre estructuras, uniones, typedefs y enumeraciones, ¡todo esto hace la vida mucho más agradable en embebido y en general!
fuente