@BitMEimNovice

Как ATmega88 подружить с кодом на С++?

Такая проблема сделал платку и код к ней. Суть работы: При включении начинает крутиться мотор с подключенным к нему энкодером и крутит второй мотор с энкодером подключенным к плате. Первый и второй энкодеры подключены к 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;
}

66e0378cde532371022712.png
  • Вопрос задан
  • 211 просмотров
Решения вопроса 1
nava2002
@nava2002
Инженер
Сигналы доходят до меги, но она не включает ни один из светиков.

Сигналы доходят - значит электроника работает.
Учитывая что код написанный на С++ его можно компелировать и загрузить в контроллер - "Дружить" ничего тоже не нужно все подружено.
Дальше внимательно вникаем в логику программы и находим ошибку. ( она там есть ).

P.S. Для "Начинающих" я бы взял Ардуино. Для Ардуино есть много готовых библиотек для быстрого решения таких простых задач.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@LanskoyGames
У модераторов первое место, но только с конца...
1.Код в тегах должен быть.
2. А почему Вы решили, что проблема именно в коде, а не в том, как собрана схема(не тот резистор…)?
Ответ написан
Комментировать
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Сигналы доходят до меги, но она не включает ни один из светиков.

Я бы начал с отладки простым безусловным включением led на старте программы. Потому что 1К резистор последовательно со светодиодом с падением в 2В ограничивает ток 3ма, чего, скорее всего, недостаточно для заметного свечения.
Ответ написан
Комментировать
@VT100
Embedded hardware & software.
Каскады на Q1-Q4 сделаны как-то глупо, транзисторы всё время открыты.
Что за энкодеры применены?
И вообще - зачем "святые оптрончики", если они не делают гальваническую развязку?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы