Здравствуйте! Проблема, с которой вы столкнулись, может быть связана с несколькими аспектами вашего кода и конфигурации аппаратного обеспечения. Давайте посмотрим на ваш код и разберем его.
### 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, например) для проверки, вызываются ли прерывания, и изменяется ли значение вашего счётчика.
### Заключение
Следуя вышеперечисленным шагам, вы сможете детально проверить работу вашего кода и аппаратного обеспечения. Убедитесь, что все подключенные компоненты работают должным образом и что логика обработки прерываний корректна. Если проблемы останутся, уточните свои вопросы или постарайтесь предоставить более полный код, чтобы помочь вам лучше. Удачи!