SPI Arduino是否与pinMode()发生冲突,错误?


9

考虑下面的最小示例,我pinMode在调用SPI函数之前进行了设置:

#include <SPI.h>

void setup() {
  pinMode(10, OUTPUT);
  SPI.begin(10);
  SPI.setDataMode(10,SPI_MODE1);
}

void loop() {
  delay(1000);
  SPI.transfer(10,1);
}

现在,当SPI.transfer(10,1)被调用时loop(),我总是看到从机选择的引脚下降到1.65V,而不是应有的0!(见下图)

在调用SPI功能之前设置了引脚模式

如果我们不打电话pinMode(),像这样:

#include <SPI.h>

void setup() {
  SPI.begin(10);
  SPI.setDataMode(10,SPI_MODE1);
}

void loop() {
  delay(1000);
  SPI.transfer(10,1);
}

调用时,我们得到了期望的结果SPI.transfer

引脚模式未设置

这是一个错误还是您对此行为有解释?

非常感谢您的时间和兴趣!


不是SPI.setDataMode(10, SPI_MODE1);吗?同样,只有第二个有用,因为begin()调用setDataMode。查看源代码,看起来SPI库不会改变您指定的引脚(尽管我不知道ARM)。
Gerben 2014年

Ja,您是对的,偶然地我两次调用setDataMode()。明天我将测试SPI.setDataMode(10,SPI_MODE1);的效果。但是,为什么调用pinMode()具有这种效果仍然不清楚?@Gerben
newandlost 2014年

@Gerben我修改了我的帖子
newandlost 2014年

Answers:


1

它可能与内部上拉电阻有关。根据SAM3X / A数据表,

不管I / O线的配置如何,都可以控制上拉电阻。

复位后,所有上拉均启用。

如果您浏览所有包含文件,则会发现:

../Arduino/hardware/arduino/samd/cores/arduino/wiring_digtal.c

第124行定义了pinMode(uint32_t ulPin, uint32_t ulMode)功能。检查INPUT vs INPUT_PULLUP vs OUTPUT的switch / case语句,您将看到以下内容:

  1. INPUT将寄存器设置为reg = PORT_PINCFG_INEN
  2. INPUT_PULLUP将寄存器设置为 reg = (PORT_PINCFG_INEN | PORT_PINCFG_PULLEN)
  3. OUTPUT将寄存器设置为reg &= ~PORT_PINCFG_INEN

每种情况下的“寄存器”都是相同的。我一生无法找到定义PORT_PINCFG_INEN或PORT_PINCFG_PULLEN的值,但是毫无疑问,它们只是8位掩码(将它们分配给“寄存器”时,它们将转换为uint8_t)。因此,我们可以假定,置位后,控制输入/输出的任何一位都有效,上拉位也是如此。例如:

 PORT_PINCFG_INEN   = b'00000001';
 PORT_PINCFG_PULLEN = b'00000010';
~PORT_PINCFG_INEN   = b'11111110';

如果重置后启用了上拉,我们可以说重置时:

 reg = b'xxxxxx1x';

上面的点(3)强烈暗示该指令是:

 reg = b'xxxxxx1x' & 'b11111110';
   so
 reg = b'xxxxxx10'; // pull-up is enabled!

因此,如果先调用pinMode(X,OUTPUT),则最终将使能上拉电阻。将引脚设置为输入将清除上拉使能位,之​​后您可以将引脚设置为输出,并且该位将保持清除。

但是,整个争论都归结为一个简单的事实,即如果您根本不调用pinMode()就不会发生问题...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.