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

Запись "заводских" настроек в 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 пользователей онлайн

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

  • Сообщения

    • Имел дело с зарядкой батареек еще с советских времен. Тогда еще в магазине (!) купил специальную зарядку для ртутно-цинковых батареек, очень миниатюрная, зарядка шла от встроенного солнечного элемента (и это еще в советские времена!). Использовал для зарядки батареек для наручных часов, после первой зарядки батарейки хватало примерно на полгода, потом на 3-4 месяца. Потом (когда батарейка служила меньше двух месяцев) батарейка отправлялась на упокой. Спасала студента тогда очень эта вещица. Жалею что тогда не срисовал ее внутренности. А вот с зарядкой щелочных батареек пришлось заниматься уже значительно позже. Мне кто-то подарил такой набор (зарядка с комплектом перезаряжаемых батареек) - вот его обзор https://aphnetworks.com/reviews/pure_energy_xl  Все было нормально, но у всех этих батареек ресурс очень ограничен, примерно 25 циклов максимум. После чего емкость уменьшается и нет смысла их дальше использовать. После каждой зарядки емкость уменьшается, но не сильно. Реально раз десять заряжать можно точно без проблем. После того как выработался ресурс последней батарейки стал вопрос - а можно ли заряжать обычные батарейки тоже? Зарядка-то осталась... И как раз в то время приобрел обычные (т.е. "незаряжаемые") батарейки той же фирмы (PureEnergy). Оказалось что они заряжаются точно также, как и "заряжаемые"! Возможно что у них та же химия... Пробовал батарейки разных фирм, степени разряда. Короче говоря, фирменные всякие Дюраселлы и Энержайзеры не заряжаются вообще, и даже могут потечь во время зарядки. А вот самые дикие и дешевые нонейм чаще всего заряжаются без проблем. Насчет емкости - конечно емкость полностью не восстанавливается, но для работы в беспроводной клаве,, мышке или пульте вполне хватает и достаточно надолго.  Но занимаюсь этим нечасто, просто когда лень ехать в магазин за очередной партией батареек.  А если есть возможность, то предпочитаю переделывать питание под литий. Очень сильно достает саморазряд всяких Ni-Cd, Ni-MH - разряжаются даже те, которые якобы должны долго держать заряд. Схему зарядки еще не срисовывал (лень было разбирать), но схема сложнее чем все что я видел в Интернете. Напряжение заряда примерно 1,7в. xlaa_tds.pdf
    • Я делаю ставку на контакты NC реле запуска и NO реле торможения. Тем более они такие хлипенькие.
    • Раз смогли срисовать схему "силы", то и решить проблему для вас вряд ли сложно будет... Проверьте емкость и ЭПС C-20мкФ и сопротивление контактов этих двух реле в on/off
    • Как? Вы ж никакой информации для работы мозга не дали. Ну, что-то собрали, как-то подключили, подаёте 220 на схему с незапаянным трансформатором, лампочка моргает, защита не срабатывает... Единственный вариант - вас отодвинуть и посмотреть, что там происходит. Но вы даже где обитаете не указали... Единственное, что можно вытянуть из вашего текста: Как может работать микросхема, если у неё замкнуто питание? Перед подачей 220 вы эту перемычку сняли?  
    • Если тут нет необходимой инфы, на это можно забить. Вот если он отвечает на АТ несколькими строками, то стоит разбирать на лету (во время приема) из кольцевого буфера.
    • Так что? Помогите реализовать, нужно за меня реализовать, подскажите как реализовать?? "Барыня лягли и просють..." Вас что в школе, дома, на улице никто не учил диалог вести. 
×
×
  • Создать...