Jump to content
    

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

Возникли проблемы с реализацией цикличного мигания светодиодов с переключением скорости и направления по кнопке. Схема не реагирует на нажатие кнопки на 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

Edited by haker_fox
Длинный код спрятал под спойлер.

Share this post


Link to post
Share on other sites

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

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

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

Share this post


Link to post
Share on other sites

1 hour ago, slava_q9 said:

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

 

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

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

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

Share this post


Link to post
Share on other sites

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

....

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

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...