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

Запись "заводских" настроек в EEPROM AtMega8


-=FISHER=-

Рекомендуемые сообщения

1 hour ago, ARV said:

И мои советы могут быть, мягко говоря, не в струю.

Я просто пока вижу только один вариант, это отследив нажатие кнопки (кстати в автомате состояний, как вы меня когда-то научили), затем через if проверив включены ли габариты и исходя (как Вы мне показали только что) из значения direction отнять или прибавить яркость, и опять такие проверив перед этим через if, не уперся ли я в потолок или дно.

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

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Хотел сейчас записать функцию опроса кнопок вот так:

uint8_t get_button(void) //опрос сразе двух кнопок
{
	static unsigned char but_code;
	but_code=PIND & BUTTON_PINS;
	_delay_ms(10);
	if(but_code==(PIND & BUTTON_PINS))
	{
		return but_code;
	}
	else
	{
		return 0xff;
	}
}

void check_buttons(void)
{
	static unsigned char command;
	command=get_button();
	if(command==Command_CH0_BTN_CLICK) //нажали кнопку №1
	{
		if(input_state==GAB_ON)
		{
			
		}
		if(input_state==GAB_OFF)
		{
			
		}
	}
	
	if(command==Command_CH1_BTN_CLICK) //нажали кнопку №2
	{
		if(input_state==GAB_ON)
		{
			
		}
		if(input_state==GAB_OFF)
		{
			
		}
	}

	if(command==Command_ALL_BTN_OFF) //ни одна кнопка не нажата
	{
		if(direction){direction=-1;}
		else{direction=1;}
	}
}

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

Получается нужно делать по старинке опрашивая каждый пин отдельно, учитывать дребезг и кучу флагов нажатия и отжатия использовать?...

Изменено пользователем -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Как по мне, так функция опроса должна возвращать число, биты которого соответствуют состоянию кнопок. То есть в одном байте можно вернуть состояние до 8 кнопок, причем в различных комбинациях нажатий. Если все биты равны нулю, то кнопки не нажаты. Я именно так и делаю всегда в своих проектах.

А вот пример моего кода из одного проекта, который реализует автоповтор кодов нажатых кнопок при длительном удержании их в нажатом состоянии:

MAKE_TIMER(TR, 0, 0);

char key_repeater(char kk){
	static char old_kk;
	char result = 0;

	if(kk == 0){
		timer_stop(&TR);
	} else {
		if(old_kk != kk){
			timer_start(&TR, 1000, 0);
			result = kk;
		} else {
			if(timeout(&TR)){
				result = kk;
				timer_start(&TR, 300, 0);
			}
		}
	}
	old_kk = kk;
	return result;
}

Тут я применил программный таймер собственной разработки, о чем писал уже в своем блоге. В эту функцию надо передавать состояние кнопок, а возвращать она будет разное:

- при первом изменении состояния кнопок сразу вернет код нажатий;
- при удержании более 1 секунды - начнет снова возвращать код каждые 0,3 с;
- во все прочие моменты будет возвращать 0.

То есть функция реализует алгоритм работы обычной клавиатуры компа: автоповтор начинается не сразу, а спустя секунду, но скорость автоповтора меньше 3 символа в секунду. Как часто эта функция будет вызываться - не имеет значения, т.к. работает в ней "фоновый" таймер TR.

Изменено пользователем ARV

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

1 hour ago, ARV said:

Как по мне, так функция опроса должна возвращать число, биты которого соответствуют состоянию кнопок. То есть в одном байте можно вернуть состояние до 8 кнопок, причем в различных комбинациях нажатий. Если все биты равны нулю, то кнопки не нажаты. Я именно так и делаю всегда в своих проектах.

В коде, что я выше привел функция get_button тоже возвращает комбинацию битов, перед этим обрабатывая дребезг. А в вашем случае, Вы как раз результат работы аналогичной функции и передаете в key_repeater? И через определённое время транслируете дальше? А как потом анализируете? Вернула она вам например 0b00000001, какие дальше варианты?

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Ну, у меня в главном цикле как-то так делается:

char key;

while(1){
	// это главный цикл
	
	key = key_repeater(get_button_presed());
	switch(key){
	case K_LEFT: 
		break;
	case K_RIGHT:
		break;
	case K_UP:
		break;
	case K_DN:
		break;
	}
}

Если кнопки не нажаты - ничего не делаю, а если нажаты - что-то делаю по коду нажатой комбинации.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

13 hours ago, ARV said:

Я именно так и делаю всегда в своих проектах.

Сейчас разбираю Ваш пример, появились вопросы.

1. Чтобы таймер запустился без выполнения процедуры, Вы запускаете его с параметром NULL вместо указания ссылки на функцию?

void StartTimer(SoftTimer *CurSoftTimer, enum StateTimer state, unsigned int time, void (*pFunc)());

StartTimer(&Timer_KK, ACTIVE, 1*sec, NULL);

2. Я правильно понимаю, что эта функция вернет TRUE если значения поля time для указанного таймера будет равно 0?

bool TimeoutTimer(SoftTimer *CurSoftTimer) //проверяем не вышло ли время
{
    return CurSoftTimer->time == 0;
}

if(TimeoutTimer(&Timer_KK)) //если время таймера вышло
{
	//что-то делаем
}

 

Изменено пользователем -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Макрос MAKE_TIMER создаёт таймер, указанный в первом параметре. Второй параметр - период таймера, третий - вызываемая после истечения периода функция. Функция timer_start имеет точно такие же параметры. Если функция не указана, то надо опрашивать состояние таймера функцией timeout, которая вернет true, если таймерный период истек. Если функция указана при создании или старте таймера, то она будет вызвана по истечению периода. Если функция вернет true, таймер автоматически перезапустится с тем же периодом, если false, то таймер остановится. Функция таймера получает в параметре указатель на свой таймер и через него может изменить его период, если надо.

Изменено пользователем ARV

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

@ARV У меня получилось адаптировать тот программный таймер который я использую под Ваши примеры (дописав пару функций и исправив существующие). Всё заработало как часы! Спасибо!

Осталось разобраться с "переворотом направления" изменения яркости, и морганием при упоре в потолок или пол. Разбираюсь.

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

14 часов назад, ARV сказал:

if(kk == 0){ timer_stop(&TR); }

Только вот в Вашем примере, если ни одна кнопка не нажата, то таймер останавливает,а мне ведь нужно чтобы в этом случае менялось направление...

И если я просто допишу в этот if, переворот значение direction, то оно будет меняться при каждом опросе кнопок.

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Внутрь функции повтора кода кнопок лезть не стоит. Тем более, что если переворот направления вставить туда, куда вы задумали, то переворачивается оно будет совсем не тогда, когда вы надеетесь...

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

1 час назад, ARV сказал:

Внутрь функции повтора кода кнопок лезть не стоит.

Но ведь иначе "отжатие" кнопок не отследить?...

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Тогда надо лезть так, чтобы заставить её выдавать разные коды для отсутствия кода при автоповторе и при отпускании кнопки. Сейчас втобоих случаях вернётся ноль, а надо эти случаи разделять.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

5 hours ago, -=FISHER=- said:

"отжатие" кнопок не отследить

Добавьте новую переменную в функцию check_buttons() для хранения предыдущего состояния кнопок. Если в предыдущем что-то было нажато, а текущее состояние == Command_ALL_BTN_OFF,  значит кнопка отпущена, и надо переворачивать направление.

Вот такое сравнение сработает только один раз при отпускании кнопки.

static unsigned char old_command;

if(old_command != Command_ALL_BTN_OFF && command == Command_ALL_BTN_OFF) //ни одна кнопка не нажата 
{
	if(direction == 1)
		direction = -1; 
	else
		direction = 1; 
}

old_command = command;

После проверки новое состояние записывается в old_command.

 

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

  • 3 недели спустя...
28.07.2019 в 01:17, Yurkin2015 сказал:

Вот такое сравнение сработает только один раз при отпускании кнопки.

Очень крутой вариант похоже!

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

27.07.2019 в 23:17, Yurkin2015 сказал:

if(direction == 1) 
	direction = -1; 
else 
	direction = 1;

 

Я бы заменил на

direction *= -1;

 

Изменено пользователем ARV

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

Что за ерунду вы написали?! 

Знак у числа меняется умножением его на -1. Вы как-то забыли, разве, что число может быть по модулю больше 1?

Не надо заниматься битовой оптимизацией, доверьтесь компилятору, он все сделает в лучшем виде.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

19 часов назад, ARV сказал:

Я бы заменил на

Выглядит лаконичнее, надо бы запомнить.

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Дело не в лаконичности, а в правильности. Математически знак у числа меняется умножением на -1, так и следует поступать, так и будет правильно.

А правильно - практически всегда красиво :) 

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

  • 4 недели спустя...
14.08.2019 в 17:09, ARV сказал:

Я бы заменил на


direction *= -1;

Приветствую!

Я сделал именно так, но почему-то результат этого сокращенного выражения у меня получается 255, а не -1 как хотелось бы... переменная типа char. В чем я ошибаюсь?...

Или просто функция itoa не умеет переводить отрицательные числа в строку?

if(old_kk!=Command_NO_BTN_CLICK){dir*=-1; itoa(dir, tmp, 10); USART_SendStr(tmp);}

 

Изменено пользователем -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

itoa хочет иметь int на входе, а не char

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

@ARV Но почему-то условие:

if(dir==-1){}

у меня вообще не выполняется после выражения:

dir*=-1;

 

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

А вы уверены, что dir у вас именно -1? Направление, как мне кажется, определяется не значением, а знаком. Например, -2 тоже будет "в другую сторону", но не равно -1.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

12 минут назад, ARV сказал:

А вы уверены, что dir у вас именно -1

Я объявляю и инициализирую переменную сразу так:

char dir = 1;

Затем при отжатии кнопки происходит действие:

dir*=-1;

Я предполагаю что значение переменной dir в таком случае может быть либо 1 либо -1.

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

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

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

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

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

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

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

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

  • Сообщения

    • Тюльгин Ю.М. Радиоконструктор 2016-03 Датчик пересечения ИК-луча Другая сфера применения аналоговых усилителей на основе микросхемы 4069 - инфракрасный датчик или фотоприемник инфракрасного сигнала. На рисунке 7 показана схема успешно эксплуатируемого уже несколько лет датчика, реагирующего на пересечение либо отражение инфракрасного луча. Интересно то, что в схеме нет широко используемых в таких случаях готовых интегральных фотоприемников. Сигнал принимается обычным ИК-фотодиодом, а усиление производится усилительными каскадами, выполненными на основе инверторов микросхемы 4069. Наличие шести инверторов в одном корпусе микросхемы 4069 позволяет весь датчик, как его приемную, так и передающую части выполнить на одной микросхеме 4069. Рис. 7. Схема датчика пересечения ИК-луча на микросхеме 4069. И так, схема показана на рис. 7. Как обычно, ИК-датчик работающий на отражение или пересечение луча состоит из передатчика ИК-луча и его приемника. Передатчик ИК-луча состоит из ИК-светодиода HL1 (здесь светодиод, такой как в пультах ДУ аппаратуры), токового ключа на транзисторах VТ1 и VТ2 и генератора импульсов частотой около 8-10 kHz. Импульсы с выхода мультивибратора на элементах D1.5 и D1.6 поступают через токовый ключ на VT1 и VT2 на ИК-светодиод HL1. Резистор R11 ограничивает ток через светодиод. HL1 излучает ИК вспышки, следующие с частотой 8-10 kHz. Если существует видимость между HL1 и FH1, излученные вспышки воздействуют на фотодиод FH1 ив нем возникают импульсы тока. Благодаря резистору R1 они преобразуются в импульсы напряжения. Переменное напряжение через конденсатор С1 поступает на первый усилитель на элементе D1.1. Его в усилительный режим переводит резистор R2. Далее, через С2 усиленное переменное напряжение поступает на усилитель на D1.2. В цепи ООС D1.2 есть резистор R3, который смещает его вход в сторону напряжения логической единицы. В результате его выход смещен в сторону логического нуля. Поэтому, в отсутствие входного сигнала напряжение на С3 соответствует логическому нулю. Но при наличии входного сигнала за счет работы детектора на VD1 напряжение на С3 увеличивается до логической единицы. Выходные импульсы формирует триггер Шмитта на элементах D1.3 и D1.4. Фотодиод РН302 можно заменить любым ИК-фотодиодом. Налаживание датчика сводится к подбору сопротивления R3, чтобы при отсутствии сигнала на выходе D1.4 был ноль, а при наличии сигнала - единица. Везде вместо микросхемы 4069 можно попробовать микросхему К561ЛН2.
    • А программатора нет чтоб попробовать залить загрузчик?
    • Мда... Ардуино приехала нерабочая. К компу подключаю - звук подключения есть, а компом не определяется. Маркировка микросхемы загрузчика стёрта.... Ну китайцы... Теперь ждём новую Ардуино, а я пока начну делать пульт.
    • ИМХО, только с24, с25, с12 имеет смысл проверить/заменить.
    • Я сам найду, вы мне название напишите пожалуйста.
    • Добрый вечер..)) Нет в моем случае лучше найти готовый для моего Цифровой осциллограф Instrustar ISDS205A 2 канала х 20 МГц.. Что касается измерительной техники я пасс.. стараюсь купить уже готовое..))
×
×
  • Создать...