Se você leu a seção 31 da Folha de dados, disponível aqui , as coisas podem ficar um pouco mais claras para você.
Aqui está um resumo do que eu sei:
PIO significa Entrada / Saída Paralela e oferece a funcionalidade de ler e gravar várias portas de registro por vez. Onde a folha de dados menciona um registro, por exemplo, PIO_OWER, a biblioteca do Arduino possui macros para acessá-las neste formato REG_PIO? _OWER onde? é A, B, C ou D para as diferentes portas disponíveis.
Eu ainda uso a lenta função pinMode () do Arduino para definir entrada / saída nos pinos, pois torna o código mais legível do que as chamadas baseadas em acrônimos, como REG_PIOC_OWER = 0xdeadbeef, mas depois use os registradores diretos para definir os pinos para os pinos. desempenho / sincronização. Até o momento, ainda não fiz nada com a entrada, portanto meus exemplos são todos baseados em saída.
Para uso básico, você usaria REG_PIO? _SODR para definir linhas de saída altas e REG_PIO? _CODR para defini-las baixas. Por exemplo, REG_PIOC_SODR = 0x00000002 definiria o bit 1 (numerado de zero) em PORTC (este é o pino digital devido 33) alto. Todos os outros pinos no PORTC permanecem inalterados. REG_POIC_CODR = 0x00000002 definiria o bit 1 em PORTC baixo. Novamente, todos os outros pinos permaneceriam inalterados.
Como isso ainda não é o ideal, ou sincronizado se você estiver trabalhando com dados paralelos, existe um registro que permite gravar todos os 32 bits de uma porta com uma única chamada. Esses são os REG_PIO? _ODSR, portanto REG_PIOC_ODSR = 0x00000002 agora definiria o bit 1 em PORTC alto e todos os outros bits em PORTC seriam baixos instantaneamente em uma única instrução da CPU.
Como é improvável que você esteja em uma situação em que precisa definir todos os 32 bits de uma porta ao mesmo tempo, será necessário armazenar o valor atual dos pinos, executar uma operação AND para mascarar os que deseja alterar, execute uma operação OR para definir os que você deseja definir como altos, depois execute sua gravação novamente e isso não é o ideal. Para superar isso, a própria CPU executará o mascaramento para você. Há um registro chamado OWSR (registro de status de gravação de saída) que mascara os bits que você grava nos ODSRs que não correspondem aos bits definidos no OWSR.
Portanto, agora, se chamarmos REG_PIOC_OWER = 0x00000002 (isso define o bit 1 do OWSR alto) e REG_PIOC_OWDR = 0xfffffffd (isso limpa todos os bits, exceto o bit 1 do OWSR) e, em seguida, chamamos REG_PIOC_ODSR = 0x00000002 novamente, desta vez apenas alteraria o bit 1 de PORTC e todos os outros bits permanecem inalterados. Preste atenção ao fato de que OWER habilita todos os bits definidos como 1 no valor que você escreve e que OWDR desativa todos os bits definidos como 1 no valor que você escreve. Embora tenha entendido isso quando o li, ainda consegui cometer um erro de código ao escrever meu primeiro código de teste, pensando que o OWDR desabilitou os bits que não estavam definidos como 1 no valor que escrevi.
Espero que isso tenha pelo menos um começo para você entender o PIO do CPU devido. Faça uma leitura e uma peça de teatro e, se tiver mais perguntas, tentarei respondê-las.
Edit: Mais uma coisa ...
Como você sabe quais bits dos PORTs correspondem a quais linhas digitais do Due? Confira: Due Pinout