AVR и светодиодный индикатор

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: AVR и светодиодный индикатор

Сообщение ARV »

вы знаете... я вас почти подвел. оказалось, все свои старые проекты с 7-сегментными индикаторами я делал тяп-ляп, стыдно показать... что поделать - 10 лет назад сам от вашего уровня не сильно отличался...


но я набросал код, который ДОЛЖЕН работать (хоть я его и не проверял). во всяком случае можете взять его в качестве идеи для развития или самостоятельной доводки до совершенства

Код: Выделить всё

/// структура элемента меню 
typedef struct{
	uint8_t		data_id; // номер данных
	char		name[4]; // текст пункта меню
} menu_item_t;

/// массив пунктов меню
static menu_item_t menu[] = {
		{0, "CLOC"}, // настройка часов
		{1, "t1on"}, // далее настройки моментов времени 4-х таймеров
		{2, "t1of"},
		{3, "t2on"},
		{4, "t2of"},
		{5, "t3on"},
		{6, "t3of"},
		{7, "t4on"},
		{8, "t4of"}
};

/// структура записи времени
typedef struct{
	uint8_t hour;
	uint8_t min;
} time_t;

/// количество пунктов меню
#define MENU_CNT	(sizeof(menu) / sizeof(menu_item_t))

/// внешний массив с данными о времени
extern time_t time_array[];
/// внешняя функция вывода строки из 4 символов на экран
extern void str_to_screen(char str[4]);
/// внешняя функция вывода времени на экран
extern void time_to_scren(time_t *t);
/// внешняя функция включения мигания позиций на экране
/// позиции задается единичками в 4-х младших битах
extern void blink_scren(uint8_t pos);

/// прототип функции редактирования времени
bool edit_time(uint8_t id);

/// навигация по меню
bool menu_navigate(void){
	uint8_t item = 0;	// текущий пункт меню на экране
	uint8_t btn;		// код нажатой кнопки
	
	while(1){
		// выводим на экран название текущего пункта
		str_to_screen(menu[item].name);
		// ждем нажатия кнопки
		btn = get_button();
		// обработка кнопки
		switch(btn){
		case BTN_ENTER:
			// включаем редактирование времени
			if(edit_time(menu[item].data_id)) break;
			else return false;
		case BTN_ESCAPE:
			// выход (отмена меню)
			return false;
		case BTN_LEFT:
			// предыдущий пункт меню по кругу
			if(--item >= MENU_CNT) item = MENU_CNT-1;
			break;
		case BTN_RIGHT:
			// следующий пункт меню по кругу
			if(++item >= MENU_CNT) item = 0;
			break;
		}
	}
}

/// тип результата редактирования числа
typedef enum{
	EDIT_OK,	// редактирование закончено успешно
	EDIT_ESC,	// редактирование отменяется
	EDIT_CONT	// редактирование продолжается
} edit_result_t;

/**
 * редактирование числа с ограничением максимального значения
 * @param btn код нажатой кнопки
 * @param data указатель на однобайтное число
 * @param max верхняя граница допустимого значения (не пересекаемая)
 * @return результат редактирования
 */
edit_result_t edit_int(uint8_t btn, uint8_t *data, uint8_t max){
	switch(btn){
	case BTN_ENTER:
		// закончили редактиование
		return EDIT_OK;
	case BTN_ESCAPE:
		// отменили редактирование
		return EDIT_ESC;
	case BTN_LEFT:
		// уменьшаем число по кругу
		if(--(*data) >= max) *data = max-1;
		break;
	case BTN_RIGHT:
		// увеличиваем число по кругу
		if(++(*data) >= max) *data = 0;
		break;
	}
	// редактирование продожается
	return EDIT_CONT;
}

/**
 * редактирование времени из массива
 * @param id номер записи времени в массиве
 * @return если время отредактировано полностью - true
 */
bool edit_time(uint8_t id){
	edit_result_t cont = EDIT_CONT;	// флаг продолжения редактирования

	uint8_t tmp; // временное хранилище редактируемого числа
	
	// редактирование ЧАСОВ:
	// запоминаем текущее значение часов из указанного элемента массива
	// включаем мигание перых 2 позиций
	// цикл продолжается, пока результат равен EDIT_CONT
	for(tmp  = time_array[id].hour, blink_screen(0b00001100); cont == EDIT_CONT; cont = edit_int(get_button(), &time_array[id].hour, 24));
	// если вышли из цикла по отмене редактирования
	if(cont == EDIT_ESC){
		// восстановим прежнее значение часов
		time_array[id].hour = tmp;
		// выключаем мигание
		blink_screen(0);
		// вернем результат отмены
		return false;
	} 
	
	// редактирвоание МИНУТ
	cont = EDIT_CONT;
	for(tmp  = time_array[id].min, blink_screen(0b00000011); cont == EDIT_CONT; cont = edit_int(get_button(), &time_array[id].min, 60));
	if(cont == EDIT_ESC){
		time_array[id].min = tmp;
		blink_screen(0);
		return false;
	} 
	// если добарись до этого места - время отредактировано полностью
	// выключаем мигание
	blink_screen(0);
	// возвращаем результат успеха
	return true;
}
подсветка синтаксиса отсутствует, что, конечно, сильно подгаживает восприятие... но надеюсь, разберетесь. во всяком случае можете рассчитывать на мои пояснения, если что-то не понятно.

P.S. простите меня за циклы for... обычно я так не пишу...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
melandr
Вымогатель припоя
Сообщения: 580
Зарегистрирован: Пт ноя 08, 2013 01:01:18

Re: AVR и светодиодный индикатор

Сообщение melandr »

Спасибки, буду разбираться. Кстати смотрел Ваш проект "Таймер - меньше просто не бывает" так и не понял все зависимости хидеров и исходников. Есть файл micro-timer.c и файл main.c Но нигде не нашел подключение исходного файла display-new.c
Реклама
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15553
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: AVR и светодиодный индикатор

Сообщение BOB51 »

Собственно, как я понял, хотелось таймер-часики соорудить?
8)
Сразу замечание по схемотехнике - на один разъем выводить все те сигналя, что на схеме НЕ РЕКОМЕНДУЕТСЯ.
Сразу разделяем позиционные ключи, сегментные ключи и кнопы.
Особое внимание к шлейфу кнопок.
:write:
Поглядю со временем... чего на том калеченом 28-лапом корпусировании соорудить можно. С моего взгляда такой вариант нагрузок на 8-ю мегу весьма избыточен - вместе с путевым/легко воспринимаемым интерфейсом пользователя может и не влезть прожка - индикатор-то ВСЕГО ЛИШЬ 4-х позиционный...
Но... продолжать буду на своей ветке (https://radiokot.ru/forum/viewtopic.php?f=62&t=156720) - отвлекаться сложно...
Да и какая-то тренировка... Я б такую постановку задачи сразу же отбросил по причине ЛЕНИ и наличия готовых и удобных в схемотехническом плане изделий. В том числе и немаловажный фактор - корпусировка/разводка выводов кристалла МК.
Да и в подобном проекте ассемблер значительно удобнее...
Ну ужжшшш... "ежли хотимсс впихерить" - то придется извратом заняться.
:beer:
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: AVR и светодиодный индикатор

Сообщение ARV »

BOB51 писал(а):то придется извратом заняться
вы, конечно, можете заниматься извратом сколько угодно, но проект подобного уровня влезет не только в мегу8, но и в attiny2313 на Си без маленйших извратов. а уж на меге8 можно просто вот вообще не париться.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15553
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: AVR и светодиодный индикатор

Сообщение BOB51 »

Для простого варианта часейков/таймерюг места и в тиньке 13-й достаточно.
Однако...
У нас 4 позиции в дисплее и 4 кнопы, что само по себе для устройства с несколькими внутренними одновременно функционирующими подустройствами маловато.
Когда-то впихивал и 16 независимых таймерюг в одну упаковку - но там же помимо 4-х позиционки были еще 8 двухцветных светиков (по одному на каждый таймер - настройка/счет/сработка - желтый/зеленый/красный) и 16-позиционная клавиатура с пищалкой (ну и ессно под ассемблером - тогда ешшо на бумаге компилировать приходилось). А тут ДВА календарных таймера и главные часы/календарь плюс режим ввода параметров одновременно могут быть востребованы. Да в качестве показаний или цифирь или "синтез-кракозябры"...
Следовательно система индикации текущего статуса и одновременно фоновых устройств будет весьма сложной задачей.
Да еще так, чтоб пользователю удобно было все это начинко ОДНОВРЕМЕННО воспринимать.
А пользователь в нашем случае весьма вредно-придирчивый (ЖОНА к примеру).
Наибольшие возможные проблемы именно в самой менюшке и сопутствующем управлении - а они во много больше места, чем собственно сам таймер занимать могут.
То я уж в своем монологе расставить попытаюсь (ежли удастся).
8)
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: AVR и светодиодный индикатор

Сообщение ARV »

BOB51, при всем уважении: вы рассуждаете, как теоретик, только думающий о проблеме, а я - как практик, не единожды делавший подобное. я со всеми проблемами знаком не понаслышке, и могу смело утверждать, что atmega8 для описанного топикстертером проекта - более чем просторный МК.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
Starichok51
Модератор
Сообщения: 19046
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: AVR и светодиодный индикатор

Сообщение Starichok51 »

ну, если писать на Си, то может atmega8 окажется маловата. а на ассемблере будет даже с хорошим запасом.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: AVR и светодиодный индикатор

Сообщение ARV »

:facepalm:
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ПростоНуб
Собутыльник Кота
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Re: AVR и светодиодный индикатор

Сообщение ПростоНуб »

Starichok51, при все уважении, "маловато" или нет зависит, в первую очередь, от программиста, а не от того, на С он пишет или на ассемблере. При правильном использовании С (не исключающем ассемблерных вставок), за одно и то же время можно написать более компактный код, чем на ассемблере. Так как бОльшую часть времени удастся уделить оптимизации алгоритма и меньшую - его реализации в коде.
С другой стороны, студент для диплома может и на ассемблере такое понаписать, что без слез не взглянешь. Реализовывал один такой CORDIC для тригонометрических функций на ассемблере i386. Так родная функция из glibc, написанная на С, оказалась и быстрее, и короче :)))
melandr
Вымогатель припоя
Сообщения: 580
Зарегистрирован: Пт ноя 08, 2013 01:01:18

Re: AVR и светодиодный индикатор

Сообщение melandr »

Добрый день! Сам таймер работает, вот результат компиляции.
Изображение
И все помещается. Просто хотелось бы разобраться, как правильно и писать код, чтобы его потом через время можно было легко поддерживать. Потому и поднял данную тему. В частности вопрос возник по работе с меню.
Ответить

Вернуться в «AVR»