如果您已阅读数据表第31节(可从此处获得),则可能对您而言更清楚了。
以下是我所知道的摘要:
PIO代表并行输入/输出,并提供一次读取和写入多个寄存器端口的功能。数据表中提到了一个寄存器,例如PIO_OWER,Arduino库具有用于以REG_PIO?_OWER格式访问它们的宏。对于不同的可用端口,是A,B,C或D。
我倾向于仍然使用缓慢的Arduino pinMode()函数来设置引脚上的输入/输出,因为它使代码比诸如REG_PIOC_OWER = 0xdeadbeef之类的基于首字母缩写的寄存器调用更具可读性,但是随后使用直接寄存器来设置引脚性能/同步。到目前为止,我还没有对输入进行任何操作,因此我的示例全部基于输出。
对于基本用法,可以使用REG_PIO?_SODR将输出线设置为高电平,而使用REG_PIO?_CODR将其设置为低电平。例如,REG_PIOC_SODR = 0x00000002会将PORTC(这是Due数字引脚33)上的位1(从零开始编号)设置为高。PORTC上的所有其他引脚保持不变。REG_POIC_CODR = 0x00000002会将PORTC的位1设置为低电平。同样,所有其他引脚将保持不变。
由于这仍然不是最佳选择,或者如果您正在处理并行数据,则不是同步的,因此有一个寄存器允许您通过一次调用写入端口的所有32位。这些是REG_PIO?_ODSR,因此REG_PIOC_ODSR = 0x00000002现在将在单个CPU指令中立即将PORTC上的位1设置为高,而将PORTC上的所有其他位立即设置为低。
由于您不太可能需要同时设置端口的所有32位,因此您需要存储引脚的当前值,执行AND操作以掩盖您的引脚要进行更改,请执行“或”操作将您要设置的值设置为高,然后再次执行写入操作,这不是最佳选择。为了克服这个问题,CPU本身将为您执行屏蔽。有一个称为OWSR(输出写状态寄存器)的寄存器,它将屏蔽您写入ODSR的所有与OWSR中设置的位都不匹配的位。
因此,现在,如果我们调用REG_PIOC_OWER = 0x00000002(这将OWSR的位1设置为高)并且REG_PIOC_OWDR = 0xfffffffd(这将清除OWSR的位1除外),然后再次调用REG_PIOC_ODSR = 0x00000002,这一次它只会更改位PORTC的1和其他所有位保持不变。要注意一个事实,即OWER使任何位被设置为1在你写的价值和OWDR禁止任何位被设置为1在你写的值。即使我在阅读时理解了这一点,但在编写第一个测试代码时仍然认为OWDR禁用了在我编写的值中未设置为1的位,因此仍然犯了一个代码错误。
我希望这至少可以让您开始了解Due CPU的PIO。阅读并玩耍,如果您还有其他问题,我会尽力回答。
编辑:还有一件事...
您如何知道PORT的哪些位与Due的哪些数字线相对应?检查一下:Due Pinout