¿Cómo funcionan los registros IO de Arduino Due? En Arduino Uno acaba de establecer DDRx
, a continuación, PINx
leer, PORTx
escribir, me gustaría hacer lo mismo con un Arduino Due, pero tiene muchos más registros, tales como PIO_OWER
, PIO_OSER
, PIO_CODR
, PIO_SODR
, etc puedo encontrar ninguna correspondencia entre Arduino Uno y Arduino Debido registros.
También hay algunas funciones útiles, tales como pio_clear
, pio_set
, pio_get
, y otros, todos explican aquí:
http://asf.atmel.com/docs/3.19.0/sam3x/html/group__sam__drivers__pio__group.html
Ahora, creo que he entendido lo que hacen las tres funciones mencionadas, pero no otras, por ejemplo:
pio_configure (Pio *p_pio, const pio_type_t ul_type, const uint32_t ul_mask, const uint32_t ul_attribute)
No puedo entender qué ul_attribute
y qué ul_type
son.
arduino-due
c
port-mapping
Alex
fuente
fuente
Respuestas:
Si tiene una lectura de la sección 31 de la Hoja de datos, disponible desde aquí , las cosas pueden ser un poco más claras para usted.
Aquí hay un resumen de lo que sé:
PIO significa entrada / salida paralela y ofrece la funcionalidad para leer y escribir múltiples puertos de registro a la vez. Cuando la hoja de datos menciona un registro, por ejemplo PIO_OWER, la biblioteca Arduino tiene macros para acceder a ellos en este formato REG_PIO? _OWER where? es A, B, C o D para los diferentes puertos disponibles.
Todavía tiendo a usar la función lenta Arduino pinMode () para configurar la entrada / salida en los pines, ya que hace que el código sea más legible que las llamadas de registros basados en acrónimos como REG_PIOC_OWER = 0xdeadbeef, pero luego uso los registros directos para configurar los pines para rendimiento / sincronización. Hasta ahora, no he hecho nada con la entrada, por lo que mis ejemplos están basados en la salida.
Para un uso básico, usaría REG_PIO? _SODR para establecer líneas de salida altas y REG_PIO? _CODR para establecerlas bajas. Por ejemplo, REG_PIOC_SODR = 0x00000002 establecería el bit 1 (numerado desde cero) en PORTC (este es el pin 33 digital debido) alto. Todos los demás pines en PORTC permanecen sin cambios. REG_POIC_CODR = 0x00000002 establecería el bit 1 en PORTC bajo. Una vez más, todos los demás pines permanecerían sin cambios.
Como esto todavía no es óptimo, o está sincronizado si está trabajando con datos paralelos, hay un registro que le permite escribir los 32 bits de un puerto con una sola llamada. Estos son REG_PIO? _ODSR, por lo que REG_PIOC_ODSR = 0x00000002 ahora establecería el bit 1 en PORTC alto y todos los demás bits en PORTC se establecerían bajo instantáneamente en una sola instrucción de CPU.
Debido a que es poco probable que alguna vez se encuentre en una situación en la que necesite configurar los 32 bits de un puerto al mismo tiempo, necesitaría almacenar el valor actual de los pines, realizar una operación AND para enmascarar los que desea alterar, realice una operación OR para establecer las que desea establecer en alto, luego realice su escritura y nuevamente, y esto no es óptimo. Para superar esto, la CPU misma realizará el enmascaramiento por usted. Hay un registro llamado OWSR (registro de estado de escritura de salida) que enmascarará los bits que escriba en los ODSR que no coincidan con los bits establecidos en el OWSR.
Entonces, ahora si llamamos REG_PIOC_OWER = 0x00000002 (esto establece el bit 1 del OWSR alto) y REG_PIOC_OWDR = 0xfffffffd (esto borra todos los bits excepto el bit 1 del OWSR) y luego llamamos REG_PIOC_ODSR = 0x00000002 nuevamente, esta vez solo cambiaría el bit 1 de PORTC y todos los demás bits permanecen sin cambios. Preste atención al hecho de que OWER habilita cualquier bit que esté establecido en 1 en el valor que escribe y que OWDR deshabilita cualquier bit que esté establecido en 1 en el valor que escribe. Aunque entendí esto cuando lo leí, todavía me las arreglé para cometer un error de código al escribir mi primer código de prueba pensando que OWDR deshabilitó los bits que no estaban configurados en 1 en el valor que escribí.
Espero que esto al menos te haya ayudado a comprender el PIO de la CPU Due. Lee y juega, y si tienes más preguntas, intentaré responderlas.
Editar: Una cosa más ...
¿Cómo sabe qué bits de los PUERTOS corresponden a qué líneas digitales del Vencimiento? Mira esto: Debido Pinout
fuente
Hay una equivalencia bastante simple para el acceso directo directo al pin. A continuación se muestra un código de muestra que muestra cómo establecer un pin digital alto y luego bajo. El primero es para un Arduino Due, el segundo es para el Arduino Uno / Mega / etc.
Todo lo que se necesita para hacer eso debe incluirse de manera predeterminada, y si no,
#include <Arduino.h>
debe ser suficiente para lograrlo.En realidad, hay funciones disponibles que se pueden invocar una vez que tiene el
Pio
puntero para hacer la configuración / borrado / resistencias pullup / etc. usando llamadas de función de aspecto ligeramente más limpio. Se puede encontrar una lista completa en el archivo de cabecera.fuente
Este es un ejemplo de código que muestra un led en el pin 33. Código tomado de arriba - muchas gracias por las explicaciones muy útiles :) Este es el comienzo de un proyecto para hablar con una pantalla táctil TFT con descarga de datos de píxeles de color de 16 bits que necesita Acceso rápido a los puertos. Creo que tengo el código correcto, particularmente la línea que establece el pin bajo. El led está felizmente parpadeando.
fuente