Такая проблема сделал платку и код к ней. Суть работы: При включении начинает крутиться мотор с подключенным к нему энкодером и крутит второй мотор с энкодером подключенным к плате. Первый и второй энкодеры подключены к PD1, PD2, PD3,PD4 соответственно, при вращения мотора мега должна посчитать количество оборотов (50) и после этого включить светодиод зеленый (если крутится вправо) красный (если крутится влево). Сигналы доходят до меги, но она не включает ни один из светиков. Не могу разобраться в чем толком проблема (только начинаю свой путь).
Сам код:
#define F_CPU 8000000UL // Частота тактового генератора 8 МГц
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#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 и INT1 на любое изменение
EIMSK |= (1 << INT0) | (1 << INT1); // Включаем прерывания INT0 и INT1
// Разрешаем глобальные прерывания
sei();
}
ISR(INT0_vect) {
// Прерывание для энкодера 1
if (PIND & (1 << PD1)) {
encoder1Count++;
} else {
encoder1Count--;
}
}
ISR(INT1_vect) {
// Прерывание для энкодера 2 (если требуется)
// Если нужно добавить логику для второго энкодера, сделайте это здесь
}
void updateRevolutions() {
// Обновляем количество оборотов на основе счетчика импульсов
int32_t delta = encoder1Count - previousEncoder1Count;
if (delta >= ENCODER1_CPR) {
revolutions++;
previousEncoder1Count = encoder1Count; // Обновляем предыдущий счетчик
} else if (delta <= -ENCODER1_CPR) {
revolutions--;
previousEncoder1Count = encoder1Count; // Обновляем предыдущий счетчик
}
// Ограничиваем количество оборотов
if (revolutions > REVOLUTIONS_LIMIT) {
revolutions = REVOLUTIONS_LIMIT;
} else if (revolutions < -REVOLUTIONS_LIMIT) {
revolutions = -REVOLUTIONS_LIMIT;
}
}
void manageLEDs() {
// Управляем светодиодами в зависимости от количества оборотов и направления
if (revolutions >= REVOLUTIONS_LIMIT) {
if (encoder1Count > 0) {
PORTB |= (1 << GREEN_LED_PIN); // Включаем зеленый светодиод
PORTB &= ~(1 << RED_LED_PIN); // Выключаем красный светодиод
} else if (encoder1Count < 0) {
PORTB |= (1 << RED_LED_PIN); // Включаем красный светодиод
PORTB &= ~(1 << GREEN_LED_PIN); // Выключаем зеленый светодиод
} else {
PORTB &= ~((1 << GREEN_LED_PIN) | (1 << RED_LED_PIN)); // Оба светодиода выключены
}
} else {
PORTB &= ~((1 << GREEN_LED_PIN) | (1 << RED_LED_PIN)); // Если меньше 10 оборотов, оба светодиода выключены
}
}
void loop() {
updateRevolutions();
manageLEDs();
// Задержка для стабильности
_delay_ms(100);
}
int main(void) {
setup();
while (1) {
loop();
}
return 0;
}