试图在按下两个按钮时让电动机停止

时间:2018-11-11 21:50:32

标签: c embedded microcontroller avr

我正在一个项目上,它有两个按钮,每个按钮都通过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;
        }
    }
}

2 个答案:

答案 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发布。