Перейти к содержанию
    

Мигание светодиодов с разной скоростью и направлением

Возникли проблемы с реализацией цикличного мигания светодиодов с переключением скорости и направления по кнопке. Схема не реагирует на нажатие кнопки на PD7 (изменение скорости), изменение направления (на PD6) происходит только тогда, когда не горит ни один диод.
Обязательно нужно применить прерывания по таймеру-счетчику, Преподаватель рекомендовал библиотеку axlib/timers.h .

Задание:
8 светодиодов сделать сквозное переключение (циклично).
Введем несколько режимов скорости (3 режима).
Взять в 2 раза увеличивающий период (использовать библиотеку по таймерам)
При работе с таймер счетчиком использовать прерывание
Подключить семисегментый индикатор (будут отображаться только режимы скорости).
2 кнопки (одна меняет скорость, другая направление).

Схема: image.png.55d9da491772c5db5806554f81b23ac9.png

Код программы: 

Spoiler
#define DEBOUNCE_DELAY_MS  100
#define F_CPU 1000000UL  // Определение частоты процессора для функций задержки
#include <avr/io.h>       // AVR стандартные функции ввода-вывода
#include <util/delay.h>   // Функции задержки
#include <main_init.h>
#include <axlib/timers.h>
#include <axlib/ports.h>


// Глобальные переменные
volatile uint8_t speedMode = 50; // Текущий режим скорости
volatile uint8_t ledState =   0; // Состояние светодиодов
volatile uint8_t direction =   1; // Направление сдвига светодиодов

volatile uint32_t lastDebounceTime =  0;


// Функция для изменения режима скорости
void changeSpeedMode() {
	speedMode=speedMode * 10;
	if (speedMode > 2000) {
		speedMode = 50;
	}
}

// Глобальные переменные
volatile uint8_t lastButtonState =  0; // Последнее состояние кнопки
volatile uint8_t debounceDelay =  50; // Задержка для отсеивания дребезга (в миллисекундах)

// Функция для изменения направления сдвига светодиодов с защитой от дребезга
void changeDirection() {
	uint8_t currentButtonState = ~PIND & (1<<6); // Текущее состояние кнопки
	if (currentButtonState != lastButtonState && currentButtonState == 0) { // Если состояние кнопки изменилось и она нажата
		_delay_ms(250); // Задержка для фильтрации дребезга
		 // Проверка, что кнопка все еще нажата после задержки
			direction = !direction; // Изменение направления, если состояние кнопки стабильно
		
	}
	lastButtonState = currentButtonState; // Обновление последнего состояния кнопки
}



int main(void)
{
	
	DDRA = 0b11111111;
	
	MCUCR = 0b00000010; // Конфигурация управления сенсором прерывания для INT0
	//sei ();
	          
	
	DDRD &= ~((1<<2)) | ((1<<6)) | ((1<<7));  // Настройка PD2, PD6, PD7 как входы
	PORTD |= ((1<<2)) | ((1<<6)) | ((1<<7)); // Установка  2, 6 и 7 пинов в состояние логическая единица
	DDRC = 0b11111111;  // Настройка порта C на выходы
	PORTC = 0b00000000; // Инициализация PORTC для отображения всех светодиодов выключенными
	
	timers_init(); // Проинициализировали таймер Т2

	timer(TIMER_7, speedMode, ON);
	//PORTC_OUT(0,1,2,3,4,5,6,7);
    while(1)
    {
		changeDirection();
		PORTA = 0b00000000;	
		
		
		
			// Сдвиг светодиодов
			if (direction) 
				{
					PORTA |= (1 << 7); // Установка бита PA7
				PORTC = 0b10000000; // Установка PORTC для отображения двоичного счетчика 10000000
				_delay_ms(250); // Задержка 250 миллисекунд
				PORTC = 0b01000000;
				_delay_ms(250);
				PORTC = 0b00100000;
				_delay_ms(250);
				PORTC = 0b00010000;
				_delay_ms(250);
				PORTC = 0b00001000;
				_delay_ms(250);
				PORTC = 0b00000100;
				_delay_ms(250);
				PORTC = 0b00000010;
				_delay_ms(250);
				PORTC = 0b00000001;
				_delay_ms(250);
				PORTC = 0b00000000;
				
				} 
				else
				{
					PORTA &= ~(1 << 7);
					// Последовательность мигания в произвольном порядке 
					PORTC = 0b00000000;
					_delay_ms(250);
					PORTC = 0b00000001;
					_delay_ms(250);
					PORTC = 0b00000100;
					_delay_ms(250);
					PORTC = 0b00010000;
					_delay_ms(250);
					PORTC = 0b01000000;
					_delay_ms(250);
					PORTC = 0b10000000;
					_delay_ms(250);
					PORTC = 0b00100000;
					_delay_ms(250);
					PORTC = 0b00001000;
					_delay_ms(250);
					PORTC = 0b00000010;
					_delay_ms(250);
					PORTC = 0b00000000;
					
				}
			
			        if (!(PIND & (1<<7))) 
					{
				        
				        _delay_ms(200);
				        PORTA |= (1 << 2);
				        changeSpeedMode();
			        }
		}
	}

Сам проект прикреплен.

project_Code_sxema.zip

Изменено пользователем haker_fox
Длинный код спрятал под спойлер.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поверхностно описано задание.

Отсутствует функциональная схема алгоритма работы, включая описание исходных состояний.

ТС сказанное выше пытается "уточнить" на форуме и ещё добавил алгоритм программы для "ясности". Это сделало все попытки анализа ощутимо бесполезными...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, slava_q9 said:

Схема не реагирует на нажатие кнопки на PD7 (изменение скорости), изменение направления (на PD6) происходит только тогда, когда не горит ни один диод.
Обязательно нужно применить прерывания по таймеру-счетчику, Преподаватель рекомендовал библиотеку axlib/timers.h .
 

 

И не будет реагировать, так написано.  И для PD7 и для PD6... их "не работа" - соответствует написанному в программе.

Где и когда меняется скорость?

А где прерывание ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

// Глобальные переменные
volatile uint8_t speedMode = 50; // Текущий режим скорости

....

	if (speedMode > 2000) {
		speedMode = 50;
	}

uint8_t будет доооооооолго достигать чего то выше 255 😜

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...