嵌入式C编程- IF语句不能正常工作



下面的代码不能工作。在这个程序中,如果我按下Swich1 (Arduino Mega的PORTK PK1引脚),然后如果我按下Switch2,每次按下开关,LED 0到3(连接在Arduino Mega的端口F的0到3引脚处)会依次闪烁。如果我按下SW2开关两次,那么在按下SW1开关时,led 4到7应该会依次闪烁。但是第一种情况是有效的,而第二种情况是无效的。

void setup() {
DDRF =0xFF;
DDRK = 0x00;
volatile long i,j,m;
j=0;
m=0;
while (1)
{
if ((PINK & 0x02) == 0x02)
//for(i=0; i<1000; i++) ;
{
j=1;
if (j/2) {
if ((PINK & 0x01) == 0x01) {
m++;
for(i=0; i<50000; i++)
;
}
if (m==1)
PORTF =0x01;
else if(m==2) 
PORTF=0x02;
else if(m==3)
PORTF=0x04;
else if (m==4) {
PORTF = 0x08;
m=0;
}
}
if (j%2) {
if ((PINK & 0x01) == 0x01)
// for(i=0; i<20000; i++) ;
{
m++;
for (i=0; i<50000; i++) 
; 
}
if (m==1)
PORTF =0x01;
else if (m==2) 
PORTF=0x02;
else if (m==3)
PORTF=0x04;
else if (m==4) {
PORTF = 0x08;
m=0;
}
}
}
}
}
void loop() {
// put your main code here, to run repeatedly:
}

if语句的工作方式完全符合您的期望-如果true是布尔表达式,则执行该块,否则不执行。您有整数表达式,计算为布尔值的非零整数表达式是true,而零是false

:

j=1;
if (j/2) {  // <<<< ALWAYS FALSE (1/2 == 0)

在这里:

if (j%2) {  // ALWAYS TRUE (1%2 == 1)

关键是你将1赋值给j,但从不修改它。在测试j之前,初始化为0永远不会被使用-在测试时它总是1。

不清楚您的意图,但显然需要根据开关状态有条件地修改j

这是在任何情况下你的问题的答案,但代码本身不是"arduino友好"。在Arduino框架中,您通常会:

  • 使用Arduino库进行I/O
  • 只在setup()
  • 中进行初始化
  • loop()
  • 中进行迭代工作
  • 允许框架进行迭代,而不是无限循环。
  • 使迭代工作无阻塞(无忙等待延迟),以便后台工作可以完成。

在这种情况下,我会将开关检测与LED控制分开,并使用Arduino I/O。例如:

static const int SW1 = A9 ;
static const int SW2 = A9 ;
static const size_t LED_COUNT = 4u ;
static const int LEDS[2][LED_COUNT] = { { A0, A1, A2, A3 }, 
{ A4, A5, A6, A7 } } ;
void setup() 
{
// Switch inputs
pinMode( SW1, INPUT ) ;
pinMode( SW2, INPUT ) ;
// LED outputs
for( size_t i = 0; i < LED_COUNT; i++ )
{
pinMode( LEDS[0][i], OUTPUT ) ;
pinMode( LEDS[1][i], OUTPUT ) ;
digitalWrite( LEDS[0][i], 0 ) ;
digitalWrite( LEDS[1][i], 0 ) ;
}
}
void loop() 
{
static unsigned long led_time = millis() ;
static unsigned long sw1_time = millis() ;
static unsigned long sw2_time = millis() ;
static const int DEBOUNCE_MILLIS = 20 ;
static const int LED_MILLIS = 500 ;
static bool previous_sw1_state = digitalRead( SW1 ) != 0 ;
static bool previous_sw2_state = digitalRead( SW2 ) != 0 ;
static size_t current_led = LED_COUNT ;
static size_t current_group = 0 ;
unsigned long now = millis() ;

// If SW1 state changed (with debounce)...
bool sw1_state = digitalRead( SW1 ) != 0 ;
if( now - sw1_time > DEBOUNCE_MILLIS &&
sw1_state != previous_sw1_state )
{
sw1_time = now ;
previous_sw1_state = sw1_state ;
// If SW1 pressed and LED cycle not running...
if( sw1_state && current_led > LED_COUNT)
{
// Start LED cycle
current_led = 0 ;
}
}
// If SW2 state changed (with debounce)...
bool sw2_state = digitalRead( SW2 ) != 0 ;
if( now - sw2_time > DEBOUNCE_MILLIS &&
sw2_state != previous_sw2_state )
{
sw2_time = now ;
previous_sw2_state = sw2_state ;
// If SW2 pressed and LED cycle not running...
if( sw2_state && current_led > LED_COUNT )
{
// Switch group
current_group = current_group == 0 ? 1 : 0 ;
}
}
// If LED cycle in progress, and time to switch LED...
if( current_led <= LED_COUNT && 
now - led_time > LED_MILLIS  )
{
led_time = now ;

// Previous LED off
if( current_led > 0 )
{
digitalWrite( LEDS[current_group][current_led - 1], 0 ) ;
}
// Current LED on
if( current_led < LED_COUNT )
{
digitalWrite( LEDS[current_group][current_led], 1 ) ;
}

// Next LED
current_led++ ;
}
}

注意没有忙等待延迟。这允许您在loop()中执行其他工作,而不会显着影响计时。

SW1启动序列,当您下一次按下SW1时,SW2切换序列运行的led组

最新更新