Jump to content
Sign in to follow this  
-=FISHER=-

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

Recommended Posts

1 hour ago, ARV said:

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

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

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

Share this post


Link to post
Share on other sites
Posted (edited)

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

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;}
	}
}

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

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

Edited by -=FISHER=-

Share this post


Link to post
Share on other sites
Posted (edited)

Как по мне, так функция опроса должна возвращать число, биты которого соответствуют состоянию кнопок. То есть в одном байте можно вернуть состояние до 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.

Edited by ARV

Share this post


Link to post
Share on other sites

Литиевые батарейки Fanso для систем телеметрии и дистанционного контроля

Системы телеметрии находят все более широкое применение во многих отраслях на промышленных и коммунальных объектах. Требования, предъявляемые к условиям эксплуатации приборов телеметрии и, как следствие, источников питания для них, могут быть довольно жесткими. Fanso предоставляет широкую линейку продукции, рассчитанной на различные условия эксплуатации, что позволяет подобрать батарейку для каждого конкретного применения, в том числе и для устройств телеметрии.

Подробнее

1 hour ago, ARV said:

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

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

Share this post


Link to post
Share on other sites

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

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;
	}
}

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

Share this post


Link to post
Share on other sites
                     

Приглашаем на вебинар Решения для построения ультразвуковых счетчиков жидкостей и газов на базе MSP430

Компэл совместно с Texas Instruments 23 октября 2019 приглашают на вебинар, посвященный системам-на-кристалле для построения ультразвуковых расходомеров жидкостей и газов на базе ядра MSP430. Вебинар проводит Йоханн Ципперер – эксперт по ультразвуковым технологиям, непосредственно участвовавший в создании данного решения. На вебинаре компания Texas Instruments представит однокристальное решение, позволяющее создавать точные недорогие счетчики жидкостей и газов.

Подробнее...

Posted (edited)
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)) //если время таймера вышло
{
	//что-то делаем
}

 

Edited by -=FISHER=-

Share this post


Link to post
Share on other sites
Posted (edited)

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

Edited by ARV

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites
14 часов назад, ARV сказал:

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

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
1 час назад, ARV сказал:

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
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.

 

Share this post


Link to post
Share on other sites
28.07.2019 в 01:17, Yurkin2015 сказал:

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

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

Share this post


Link to post
Share on other sites
Posted (edited)
27.07.2019 в 23:17, Yurkin2015 сказал:

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

 

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

direction *= -1;

 

Edited by ARV

Share this post


Link to post
Share on other sites
3 часа назад, ARV сказал:

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

тогда уж

direction = ((direction + 1) ^ 0x02) - 1;

:)))

Share this post


Link to post
Share on other sites

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

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

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

Share this post


Link to post
Share on other sites
19 часов назад, ARV сказал:

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

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites
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);}

 

Edited by -=FISHER=-

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

if(dir==-1){}

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

dir*=-1;

 

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
12 минут назад, ARV сказал:

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

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

char dir = 1;

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

dir*=-1;

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

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.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  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.

Loading...
Sign in to follow this  

  • Сообщения

    • Доброго времени всем. Уважаемый @FonSchtirlitz прослушал в наушниках представленный вами ролик, разрешите высказать свое мнение. По мне "высоких" слишком много, сильно "цыкают", " низкие" частоты, такое слуховое впечатление, воспроизводятся уже не столько динамиками сколько ящиками.  Для корректного сравнения наверное лучше  привести ролики с звучанием одного широкополосного динамика в щите или в открытом ящике, наверняка есть и с двух-трехполосным разделением такие АС,  в которых по идее не должно быть так называемой "интерференционной каши", а ФИ, ЗЯ, ТКВП, ОНКЕН, Рупор и т.д. , конечно не мне дилетанту говорить вам об этом,  совершенно другое АО  и по моему мнению сравнивать их с ГИ некорректно. Интересно каким микрофоном делали запись и какова стоимость данных АС. Почему представленный @Artem Ivn  материал вы считаете бахвальством?  Человек сделал своими руками, снял видео и АЧХ, выложил , что бы люди ознакомились, тем более в соответствующей теме, что в этом нехорошо или не правильно мне не понятно. Я бы с удовольствием посмотрел и послушал, пусть даже через ютуб, ваши наработки и совсем не считал бы  такой материал бахвальством с вашей стороны.  На данный момент времени у меня ГИ ( в аннотации под видео есть небольшой фото отчет об УМЗЧ, кому интересно посмотрите) звучание которых меня устраивает, ""хора мальчиков или воробышков" в них нет, звучание очень гармоничное, к стереоэффекту тоже претензий нет, нижний регистр полностью устраивает.  Да габариты конечно не маленькие но на то оно и АО щит, были самодельные АС лабиринт на Сонидо SWR 250, по габаритам были  тоже "солидные", если правильно помню высота 1400мм, глубина 500мм, ширина 460мм, а по весу под 60кг,  места тоже занимали не мало, правда пришлось продать их из-за жизненных  обстоятельств. Я не адепт  чего то  с утверждением типа: "Только широкополосные дины, только лампы, только без ОС или наоборот только  транзисторы, только многополоска и т.д и т.п." по моему мнению все имеет место быть кроме того, что стреляет и убивает. Слушая по все тому же пресловутому ютуб, много слушая,  причем ролики с хорошим качеством записи, я не могу отделаться от ощущения, что практически все АС  в корпусах гудят или бубнят,  и как я понимаю, из-за корпусов. Возможно это глупое занятие, такие прослушивания и оценки, но другой возможности услышать другие АС у меня нет. Может быть я просто привык к звучанию щитов ГИ в которых установлены  не дорогие советские динамики и данные динамики не такие плохие как утверждают некоторые участники форума,  по крайней мере цена - результат  несоизмеримы, я тоже не ожидал, что от таких недорогих, доступных пока еще, головок можно получить такой отличный результат.   
    • ВАу! Может попробуете объяснить неучу?
    • Учите мат часть прежде чем писать... И читайте внимательно выше... средняя точка гуляла до этой схемы, по классическому варианту, и прочтите не только меня выше но и других людей... 
    • Частота то какая? Чтоб дроссель не грелся , его надо мотать скруткой(литцендратом). Например я мотаю проводом 0,14мм в 20-40 жил, в зависимости от мощности на выходе. И дроссель почти не греется даже на 1000 ватт(RM14).
    • всем привет помогите пожалуйста найти  datasheet на микросхему a2c53402059
    • Интересно, каким образом? А вообще, чтобы вам помогли, потрудитесь нарисовать читаемую схему, указать номиналы элементов и выложите её тут.
    • Не работает ссылка, ничего не открывается. Попробуйте вот этот симулятор https://falstad.com/circuit/ Там есть масса готовых схем.
  • Покупай!

×
×
  • Create New...