这是我的代码:
#include <wiringPi.h>
#include <stdio.h>
#define LED 18
#define IN 24
int main(void)
{
wiringPiSetupGpio ();
pinMode (LED, OUTPUT);
pinMode (IN, INPUT);
for (;;)
{
digitalWrite (LED, 1);
delay (2000);
digitalWrite (LED, 0);
delay (2000);
if (digitalRead (IN) == 1)
{
for (;;)
{
digitalWrite (LED, 1);
delay(500);
digitalWrite (LED, 0);
delay(500);
}
}
}
return 0;
}
我使用开关从2000延迟到500延迟。问题在于,当我按开关时,它会等到循环结束直到它变得更快。反之亦然。我需要在代码中的某个地方写一个函数或循环,以使我可以按开关,而无需等待速度较慢/更快的速度。我正在使用接线Pi库和GPIO引脚编号在Raspberry Pi上对此进行编码。
首先,您所显示的代码将从不偏离2000
的延迟,仅仅是因为没有办法从初始for(;;)
循环退出。那可能是您需要检查和修复的第一个第一。
在能够尽早结束延迟方面,您可以做更改之类的事情:
delay (2000);
进入:
for (i = 0; i < 2000; i += 10) {
delay (10);
if (digitalRead (IN) == 1)
break;
}
如果开关发生变化,这基本上会尽早退出延迟,因此您永远不会等于10个时间单元(而不是2000年)。
请注意,可能会有一个开销可以反复调用延迟。换句话说,虽然delay(2000)
可能需要非常接近2000个时间单元,但由于每个呼叫的设置时间等等,对delay(10)
的两百个电话可能需要更多。
实际上,您可能根本不使用硬编码值可以极大地简化代码。取而代之的是,您可以使用一个最小延迟的单个循环,其中一些内部控件可以解决何时以及如何更改LED(即,不是每个通过循环)。
例如,这样的事情会做到。我没有测试过它,因为我的PI2仍在盒子里等着我玩的时间,但是它应该非常接近:
#include <wiringPi.h>
#include <stdio.h>
#define LED 18
#define IN 24
#define RES 10
int main (void) {
int cycleTime, ledState, lastSwitch, currSwitch, timeLeft;
wiringPiSetupGpio ();
pinMode (LED, OUTPUT);
pinMode (IN, INPUT);
cycleTime = 2000; // Initial cycle time
ledState = 0; // and LED state.
lastSwitch = 0; // Previous switch state,
// Start infinite loop with first cycle time.
timeLeft = cycleTime;
for (;;) {
// Delay for minimal time and adjust time left.
delay (RES);
timeLeft = timeLeft - RES;
// Detect switch change.
currSwith = digitalRead (IN);
if (currSwitch != lastSwitch) {
// If so, store new state, change cycle time
// and force IMMEDIATE end of current cycle.
lastSwitch = currSwitch;
cycleTime = 2500 - cycleTime; // switch 500 <-> 2000
timeLeft = 0;
}
// Detect end of cycle.
if (timeLeft <= 0) {
// Toggle LED and start new cycle.
ledState = 1 - ledState;
digitalWrite (LED, ledState);
timeLeft = cycleTime;
}
}
}
基本上,您有一个循环,但一个循环每十个单元,而不是每500或2000个循环。该计数器取决于当前周期时间。
当开关翻转时,该计数器为零,以使其(几乎)立即更改为下一个周期。