我正在一个项目上,它有两个按钮,每个按钮都通过H桥在一个方向(时钟/逆时针)上旋转电动机,但是我试图让电动机在单击时停止两个按钮。一切工作正常,但我不能完全按下两个按钮...
这是我的尝试:
#include "motor.h"
#include <avr/io.h>
#include <util/delay.h>
int flag=0;
int main(void)
{
DDRD &= ~(1<<PD2);
DDRD &= ~(1<<PD3);
DDRB |= (1<<PB0);
DDRB |= (1<<PB1);
PORTB &= ~(1<<PB0);
PORTB &= ~(1<<PB1);
while(1)
{
if (PIND & (1<<PD2))
{
flag = 1;
}
else if (PIND & (1<<PD3))
{
flag = 2;
}
else if (PIND & (1<<PD3 ) && (1<<PD2))
{
flag = 3;
}
switch (flag)
{
case 1:
DC_MOTOR_PORT |= (1<<DC_MOTOR_PIN1);
DC_MOTOR_PORT &= ~(1<<DC_MOTOR_PIN2);
break;
case 2:
DC_MOTOR_PORT |= (1<<DC_MOTOR_PIN2);
DC_MOTOR_PORT &= ~(1<<DC_MOTOR_PIN1);
break;
case 3:
DC_MOTOR_PORT=0x00;
break;
}
}
}
答案 0 :(得分:5)
我假定,当您按下一个按钮时,history
中的1 << PD2
销将置位。条件PIND
成立,进入PIND & (1 << PD2)
分支,并且代码不会费心测试其他条件(因为它们在if
子句下)。
此外,else
是一个逻辑运算。 &&
总是产生(1<<PD3 ) && (1<<PD2)
,因此true
子句将有效测试else
。并不是您想要的。
请考虑
PING & 1
答案 1 :(得分:0)
在else-if构造中,将永远不会测试最后一个条件,因为第一个测试PIND & (1<<PD2)
也将为true。同样,在第三项测试中使用&&
是不正确的。
另一个问题是您多次阅读PIND
。为了确保一致性,您应该阅读一次并测试读取的值。
您可以先测试第三个条件(两个按钮),但实际上这是不必要的。整个结构可以替换为:
uint8_t buttons = PIND ;
flag = 0 ;
if( buttons & (1<<PD2) )
{
flag |= 1;
}
if( buttons & (1<<PD3) )
{
flag |= 2 ;
}
或更简洁地说:
flag = ( buttons & (1<<PD2) ) ? 1 : 0 ;
flag |= ( buttons & (1<<PD3) ) ? 2 : 0 ;
然后同时按下这两个按钮时,标记将为1 | 2
,即3
。
即使那可能是不必要的;您可以直接在开关中直接使用PIND的掩码值。该解决方案已由@ user58697发布。