Как можно интегрировать код на C++ с микроконтроллером ATmega88?

Здравствуйте, Хабр. У меня возникла проблема с платой и кодом, которые я создал. Суть работы заключается в следующем: при включении начинает вращаться мотор с подключенным энкодером, а также второй мотор с энкодером, подключенным к плате. Первый и второй энкодеры подключены к PD1, PD2, PD3 и PD4 соответственно. При вращении мотор должен подсчитать количество оборотов (50) и после этого включить зеленый светодиод, если вращение происходит вправо, и красный — если влево. Сигналы до меги доходят, однако она не активирует ни один из светодиодов. Я не могу понять в чем заключается проблема, так как только начинаю свой путь в этой области. 

Вот сам код:  
```cpp
#define F_CPU 8000000UL  // Частота тактового генератора 8 МГц

#include <...>
#include <...>
#include <...>

#define GREEN_LED_PIN PB0
#define RED_LED_PIN PB1
#define ENCODER1_CPR 5  // Количество импульсов на один оборот энкодера
#define REVOLUTIONS_LIMIT 10  // Ограничение на количество оборотов

volatile int32_t encoder1Count = 0;
volatile int32_t previousEncoder1Count = 0;
volatile int32_t revolutions = 0;

void setup() {
    // Установим пины для светодиодов как выходы
    DDRB |= (1 << GREEN_LED_PIN) | (1 << RED_LED_PIN);
    PORTB &= ~((1 << GREEN_LED_PIN) | (1 << RED_LED_PIN));

    // Настроим пины для энкодеров как входы
    DDRD &= ~((1 << PD1) | (1 << PD2) | (1 << PD3) | (1 << PD4));

    // Включаем внутренние подтягивающие резисторы на входах энкодеров
    PORTD |= (1 << PD1) | (1 << PD2) | (1 << PD3) | (1 << PD4);

    // Настраиваем прерывания на фронты сигналов энкодеров
    EICRA |= (1 << ISC00) | (1 << ISC01) | (1 << ISC10) | (1 << ISC11); // Настраиваем INT0
```
Сможет ли кто-то помочь разобраться с этой проблемой?
  • 10 сентября 2024 г. 12:13
Ответы на вопрос 2
Здравствуйте! Проблема, с которой вы столкнулись, может быть связана с несколькими аспектами вашего кода и конфигурации аппаратного обеспечения. Давайте посмотрим на ваш код и разберем его.

### 1. Основные моменты на которые стоит обратить внимание

#### 1.1. Настройка прерываний
Вы можете не настроить правильно прерывания для энкодеров. Убедитесь, что вы правильно включили прерывания для пинов, к которым подключены ваши энкодеры. Например, если вы используете пины PD2 и PD3 как входы для энкодеров, то у вас должно быть что-то подобное:

```cpp
EICRA |= (1 << ISC01) | (1 << ISC11); // нарастающий фронт для INT0 и INT1
EIMSK |= (1 << INT0) | (1 << INT1); // включаем прерывания
```

#### 1.2. Реакция на прерывания
Убедитесь, что в функции для обработки прерывания вы правильно считываете значения энкодеров и увеличиваете или уменьшаете счётчик в зависимости от направления вращения. Например:

```cpp
ISR(INT0_vect) {
    if (PIND & (1 << PD1)) {
        encoder1Count++;
    } else {
        encoder1Count--;
    }
    checkRevolutions();
}

ISR(INT1_vect) {
    if (PIND & (1 << PD3)) {
        encoder2Count++;
    } else {
        encoder2Count--;
    }
    checkRevolutions();
}
```

#### 1.3. Проверка количества оборотов
Обязательно проверьте значение вашего счётчика после поступления каждого импульса. Например:

```cpp
void checkRevolutions() {
    if (encoder1Count >= (ENCODER1_CPR * REVOLUTIONS_LIMIT)) {
        PORTB |= (1 << GREEN_LED_PIN); // Включаем зелёный светодиод
        // Здесь добавьте логику, например, сбросить счётчик
    } else if (encoder1Count <= -(ENCODER1_CPR * REVOLUTIONS_LIMIT)) {
        PORTB |= (1 << RED_LED_PIN); // Включаем красный светодиод
        // Здесь добавьте логику, например, сбросить счётчик
    }
}
```

### 2. Обратите внимание на подключение
Проверьте, чтобы подключение моторов и энкодеров было правильным. Иногда проблемы с подключением могут приводить к тому, что прерывания не срабатывают.

### 3. Добавление `loop()` или аналогичного кода
Проверьте, что в `setup()` функции вы вызываете `sei()` для включения глобальных прерываний. Следующий код имеет минимальный цикл:

```cpp
int main() {
    setup();
    sei(); // включает глобальные прерывания
    while (1) {
        // Ваш код здесь, возможно, для других задач или просто ожидание.
    }
}
```

### 4. Отладка
Добавьте простую отладку с помощью последовательного вывода (если используете Arduino, например) для проверки, вызываются ли прерывания, и изменяется ли значение вашего счётчика.

### Заключение
Следуя вышеперечисленным шагам, вы сможете детально проверить работу вашего кода и аппаратного обеспечения. Убедитесь, что все подключенные компоненты работают должным образом и что логика обработки прерываний корректна. Если проблемы останутся, уточните свои вопросы или постарайтесь предоставить более полный код, чтобы помочь вам лучше. Удачи!
1.Код в тегах должен быть. 
2. А почему Вы решили, что проблема именно в коде, а не в том, как собрана схема(не тот резистор…)?
Похожие вопросы