пытаясь дать двигателю остановиться при нажатии двух кнопок - PullRequest
0 голосов
/ 12 ноября 2018

Я работаю над проектом, и у него есть две кнопки, каждая из которых поворачивает двигатель в направлении (по часовой стрелке / против часовой стрелки) через 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 голосов
/ 13 ноября 2018

В конструкции else-if последнее условие никогда не будет проверяться, поскольку первый тест PIND & (1<<PD2) также будет истинным. Также неправильное использование && в третьем тесте.

Еще одна проблема заключается в том, что вы читаете 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.

0 голосов
/ 12 ноября 2018

I предполагает , что при нажатии одной кнопки устанавливается 1 << PD2 вывод PIND. Условие PIND & (1 << PD2) становится истинным, ветвь if берется, и код не мешает проверять другие условия (так как они находятся в условиях else).

Кроме того, && - логическая операция. (1<<PD3 ) && (1<<PD2) всегда дает true, поэтому предложение else будет эффективно проверять PING & 1. Не совсем то, что вы хотите.

Рассмотрим вместо

    button_state = PIND & ((1 << PD2) | (1 << PD3)); // Mask out pins of interest
    switch (button_state) {
        case 0: // Nothing pressed
            ....
            break;
        case 1 << PD2: // One button pressed
            ....
            break;
        case 1 << PD3: // Another button pressed
            ....
            break;
        case (1 << PD2) | (1 << PD3): // Both pressed
            ....
            break;
...