我有一个非常简单的测试sketch,其中我试图将引脚设置为HIGH
,然后使用digitalRead
读取其状态。这是我的草图。
void setup()
{
Serial.begin(9600);
}
void loop()
{
delay(1000);
pinMode(3, OUTPUT);
digitalWrite(3, HIGH);
delay(1000);
pinMode(3, INPUT);
Serial.println(digitalRead(3));
}
串口监控结果:
0
0
0
0
我已经明白,更改pinMode会阻止它成为HIGH
。因此,在HIGH
模式下将引脚设置为OUTPUT
,然后更改为INPUT
模式会将其更改为LOW
。因此,digitalRead将始终返回0.如果我不更改pinMode,它将无法读取引脚。那么如何在不丢失值的情况下读取OUTPUT
模式下引脚的当前设置?
答案 0 :(得分:32)
在这种情况下,您只想访问数据寄存器。
PORTB和PORTD寄存器包含您要查找的引脚数据。我终于可以访问Arduino了解它。您想使用bitRead(PORTD, pin)
。
Serial.println(bitRead(PORTD,3)); //Reads bit 3 of register PORTD which contains the current state (high/low) of pin 3.
参考Bit Read Operation了解更多信息。
答案 1 :(得分:32)
你的素描应该是
void setup()
{
Serial.begin(9600);
}
void loop()
{
delay(1000);
pinMode(3, OUTPUT);
digitalWrite(3, HIGH);
delay(1000);
// pinMode(3, INPUT); // get rid of this line
Serial.println(digitalRead(3));
}
这就是全部。然后它读取引脚的状态,在你的情况下是“高”。如果将pinMode设置为输入,它将根据连接的内容读取输入。如果您将“HIGH”写入输入引脚,则会激活内部上拉。如果在将其设置为输入模式或将其设置为输入模式之前写入HIGH,则无关紧要。除非您正在驱动输出引脚的高负载(例如,接地开关)。那么这可能会杀掉别针。
如果你写了一个低电平并将引脚设置为低电平,它可能会浮动,这可能导致任何不可预测的行为。
答案 2 :(得分:4)
digitalWrite(3,HIGH);
digitalRead(3);
答案 3 :(得分:3)
不喜欢以前的任何答案,因为它们不会与跨arduino平台兼容。您需要通过引脚参考表访问。以下表达式可以解决问题。
bool value = (0!=(*portOutputRegister( digitalPinToPort(pin) ) & digitalPinToBitMask(pin)));
让我打破这一点,以便更好地理解
digitalPinToPort(pin)
查看您在所选硬件上分配引脚的gpio bank [port]
portOutputRegister(...)
为您提供指向包含您要查找的值的端口的指针。 *取消引用指针并给出分配给该端口的所有8个引脚的完整值。它还不是特别有用,但你要找的那个位于那里。
&digitalPinToBitMask(pin)
仅选择您感兴趣的引脚位,所有其他位将为零。
0!=测试结果表达式是否为零或其他内容。如果它为零,则该引脚上的输出为零。否则输出为1。
答案 4 :(得分:2)
你为什么要这样做?如果您这样做是为了验证引脚是否真的很高,这将无法确认,因为外部电路的高引脚可能存在短路,最好的方法是通过另一个引脚创建反馈;将另一个引脚配置为输入,并将输出引脚连接到新的输入引脚,并读取其值。读取内部寄存器将始终为您返回控制器试图放在引脚上的内容,而不是实际的引脚值。
答案 5 :(得分:2)
将pinMode()
选项保留在setup()
功能中,然后尝试使用digitalWrite()
和digitalRead()
功能。
setup()
,loop()
将是继续执行的函数。
int pin22 = 22;
void setup()
{
Serial.begin(9600);
pinMode(pin22,output);
}
void loop()
{
digitalWrite(pin22,HIGH);
digitalRead(pin22);
digitalWrite(pin22,LOW);
digitalRead(pin22);
}
答案 6 :(得分:0)
保留输出引脚状态的单独布尔图。
如果将微控制器GPIO引脚设置为输入,则读取时其值取决于它与外部连接的值。这就是重点。
答案 7 :(得分:0)
您是否尝试将默认输入设为HIGH?
如果是这样,您希望激活上拉寄存器:
void setup()
{
Serial.begin(9600);
}
void loop()
{
delay(1000);
pinMode(3,INPUT); // default mode is INPUT
digitalWrite(3, HIGH); // Turn on the internal pull-up resistor, default state is HIGH
delay(1000);
Serial.println(digitalRead(3));
}
摘自DigitalWrite:
如果引脚配置为INPUT,则使用digitalWrite()写入HIGH值将启用内部20K上拉电阻。
答案 8 :(得分:0)
总是记住。如果您尝试配置任何内容,请将其保存在安装文件中。由于设置文件执行一次,如果您正在设置In循环。它执行连续。并尝试保持它保持启动状态。这是活动的低状态
答案 9 :(得分:0)
我写了一个例程,用于闪存四个不同的LED用于不同的目的,但我还想在我闪存之前保留它们的初始状态,因为它们的稳定状态也告诉我在我的代码中发生了一些事情,所以这是我的Flash代码,你通过发送引脚号码,闪存它的次数以及闪烁它的时间来调用它。
inline void Flash (byte pinNum, byte times, byte flashSpeed)
{
bool state; // Local var for State of pin
state = digitalRead(pinNum); // Read the current state as set elsewhere
int x; // Local var for repeat flash
for (x = 0; x < times; x++)
{
digitalWrite(pinNum, HIGH); // Turn on LED
delay(flashSpeed);
digitalWrite(pinNum, LOW); // Turn off LED
delay(flashSpeed * 2); // leave off twice as long as on
} // due to persistence of Vision
digitalWrite(pinNum, state); // Restore the original state of the LED
}
答案 10 :(得分:-2)
您可以尝试:
int Pin22 = 22;
int valuePin22 = 0;
void setup() {
pinMode(Pin22, OUTPUT);
digitalWrite(Pin22, LOW);
}
void loop() {
digitalWrite(Pin22, HIGH)
valuePin22 = 1;
Serial.println(valuePin22);
delay(100);
digitalWrite(Pin22, LOW)
valuePin22 = 0;
Serial.println(valuePin22);
delay(1000)
}