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

Преобразование массива в код (Си)


-=FISHER=-

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

 

33 минуты назад, ruhi сказал:

if(code!=(PINB & 0x07)){code=0;}

Не нравится мне этот вариант. Если я нажал первую кнопку, а потом, не отпуская, нажал вторую во время delay(10), то этот код мне занулит обе кнопки и первую занулит тоже? При чём здесь первая, я же её не отпускал?

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

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

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

Не нравится мне этот вариант.

Давайте рассмотрим ситуацию "вообще": есть состояние сигналов, которое мы контролируем. При изменении сигналов могут быть кратковременные нестабильные ситуации, которые мы должны отслеживать и игнорировать (дребезг). Мы считаем, что если за 10 мс состояние не изменилось, оно СТАБИЛЬНО и его можно анализировать. Следовательно, любое НЕСТАБИЛЬНОЕ состояние надо игнорировать. Мы уславливаемся, что состояние с кодом 0 - никак не обрабатывается, оно равносильно "отсутствию чего-либо". Все ненулевые состояния должны обрабатываться. Очевидно, что при обнаружении НЕСТАБИЛЬНОСТИ состояния надо вернуть 0, чтобы проигнорировать это. Так как опрос состояния ведется периодически, то В СЛЕДУЮЩИЙ РАЗ мы обнаружим состояние с двумя одновременно нажатыми кнопками и корректно обработаем его.

Так что все нормально.

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

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

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

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

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

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

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

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

Мы уславливаемся, что состояние с кодом 0 - никак не обрабатывается,

Только вот в моем случае состояние с кодом 0 должно обрабатываться. Этому коду соответствует своя функция.

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

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

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

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

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

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

состояние с кодом 0 - никак не обрабатывается

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

Ноль - значит все кнопки были отпущены. Вот и получится вместо "кн.1 нажата - кн.1 и кн.2 нажаты" будем иметь ситуацию "кн.1 нажата - всё отпущено - кн.1 и 2 нажаты, причём кн.1 нажата второй раз".

Вон, и у ТС программа реагирует на ноль какой-то паузой в освещении.

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

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

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

Что и как у вас обрабатывается в программе - это дело ваше. Но должно быть состояние, которое НЕ обрабатывается, пусть это будет не 0, а -1 - какая разница? Именно это значение и надо вернуть, если обнаружено НЕСТАБИЛЬНОЕ состояние. Нестабильным назовем любое изменение состояния за 10 мс, стабильным - любое, длящееся больше, чем 10 мс.

Реакция на отпускание, если требуется,  должна реализовываться на следующем, более высоком, уровне, равно как и на долгое удержание (типа автоповтора клавиатуры). Конкретно к защите от дребезга это уже не имеет отношения.

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

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

Литиевые аккумуляторы EVE Energy и решения для управления перезаряжаемыми источниками тока (материалы вебинара)

Опубликованы материалы вебинара Компэл, посвященного литиевым аккумуляторам EVE Energy и решениям для управления перезаряжаемыми источниками тока.

На вебинаре мы представили информацию не только по линейкам аккумуляторной продукции EVE, но и по решениям для управления ею, что поможет рассмотреть эти ХИТ в качестве дополнительной альтернативы для уже выпускающихся изделий. Также рассмотрели нюансы работы с производителем и сервисы, предоставляемые Компэл по данной продукции. Подробнее>>

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

Кстати, если есть желание, то вышепредложенный способ борьбы с дребезгом может быть доведен до крайности, и тогда исчезнет то самое "необрабатываемое" состояние. Если опрашивать порт каждые, допустим 20 мс (т.е. период опроса больше, чем время дребезга - это важное условие), и результат опроса помещать в переменную, то можно будет просто в нужные моменты смотреть содержимое этой переменной и все... То есть фактически будет делаться так:

uint8_t tmp = PINB & 0b00000111;
_delay_ms(10);
if(tmp == (PINB & 0b00000111)) code = tmp;
// и далее работать с code

 

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

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

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

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

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

опрашивать порт каждые, допустим 20 мс

Этого как раз достаточно для борьбы с дребезгом.

Не надо никаких сравнений  и delay(), просто каждые 20 мс выполнять одну строчку:

code = PINB & 0b00000111;
// и далее работать с code

вот и вся борьба ...

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

6 минут назад, Yurkin2015 сказал:

вот и вся борьба ...

Ну я бы не сказал, что совсем вся... борьба просто перейдет в партер :) 

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

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

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

Ну я бы не сказал

Не, ну, посудите сами. Например, нажатие кнопки выдаёт 1 и пусть нажали на кнопку, и прямо угадали опросить "code = PINB & 0b00000111;" как раз во время дребезга. Всё нормально: если зафиксировали 1, то это как раз и нужно. А если зафиксировали 0, то и хрен с ним, был ноль - ноль и остался, желаемую 1 получите через следующие 20 мс. В результате по-любому в переменной code будет единственный переход 0->1, никакого дребезга не будет, и в партер переходить не надо. :lol:

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

8 часов назад, Yurkin2015 сказал:

и в партер переходить не надо

Теперь обращаю ваше внимание на то, что данный подход работает при регулярном опросе кнопок. А такое не всегда делается. Для нерегулярного придется применять задержки.

Никуда не делась ситуация с тем, когда в предыдущий раз была нажата 1 кнопка, в "этот" раз обнаружилось нажатие дополнительно второй, а в следующий раз второй не будет. Т.е. пройдет всего 50-60 мс, а метод выдаст 3 разных состояния. Маловероятно, что это правильно, но без борьбы в партере будет отработано последующим кодом и, скорее всего, результат будет не совсем тот...

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

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

Уважаемые, @ARV@Alex и @Yurkin2015 и мне очень помогли Ваши советы по обработки кнопок. Получилось значительно сократить объём кода и избавиться от глюков.

А теперь может быть у нас совместными усилиями получится так же красиво упростить алгоритмы обработки этих самых команд? У меня в принципе получилось, но там огромное количество операторов ветвления if-else. Наверняка должен быть более лаконичный подход, только я его не вижу.

 

Всего имеем три провода приходящих от кнопки аварийки: от ламп правого поворотника (right) на PB0, от ламп левого поворотника (left) на PB2, от реле прерывателя поворотов (COM) на PB1. И всего имеем 5 возможных состояний / команд:

  • код 2 (010) - режим ожидания. Оба поворотника выключены, от провода COM приходит +12В;
  • код 3 (011) - включен/горит правый поворотник, от провода COM приходит +12В, от провода right приходит +12В;
  • код 6 (110) - включен/горит левый поворотник, от провода COM приходит +12В, от провода left приходит +12В; 
  • код 0 (000) - режим паузы между вспышками,  подрулевой рычаг включен до фиксции либо была нажата кнопка аварийки, горел левый или поворотник или аварийка, от провода COM приходит 0В, от провода left и провода right приходит 0В; 
  • код 7 (111) - включена аварийка, от всех трёх проводов приходит +12В.

У этого устройства вот такой алгоритм работы:

Функциональные возможности

Удлинитель поворотов работает следующим образом:

·         При коротком нажатии на рычаг поворотов – устройство выдаст серию запрограммированных импульсов мигания лампами поворотов;

·         При длительном нажатии на рычаг поворотов (больше одного моргания) – эффекта удлинения не будет;

·         При переключении из одного направления в момент удлинения поворотов в другое, повороты прекращают мигать по первому направлению и начинают мигать по второму.

 

Режим программирования

·         Включить зажигание, при этом на устройстве загорится зелёный светодиод. С этого момента начинается отсчет времени (10 сек), по истечению которого вход в режим программирования будет невозможен;

·         Включить правый поворот на два мигания, затем включить левый поворот на два мигания;

·         Устройство подтвердит вход в режим программирования тройным миганием аварийки;

·         Для программирования количества миганий поворотами при удлинении: включить правый поворот на необходимое количество миганий и выключить его;

·         Если поворот не будет включен в течении 10 сек, устройство автоматически выйдет из режима программирования, без записи нового значения в память;

·         Устройство подтвердит запись нового параметра в память тройным миганием аварийки;

 

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

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

Только что, -=FISHER=- сказал:

У меня в принципе получилось, но там огромное количество операторов ветвления if-else. Наверняка должен быть более лаконичный подход, только я его не вижу.

Я тоже ничего не вижу :) 

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

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

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

Я тоже ничего не вижу :) 

Вы имеете ввиду мой вариант?

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

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

Только что, -=FISHER=- сказал:

Вы имеете ввиду мой вариант?

А вы предлагаете мне написать свой? ;)

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

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

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

А вы предлагаете мне написать свой? ;)

Нет, я прошу какой-то наводки :) Мне не сложно выложить свой код, но я боюсь что вы все в нём запутаетесь. Я сам то в нём путаюсь(( там такая портянка...Ну да ладно сейчас выложу для наглядности.

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

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

Только что, -=FISHER=- сказал:

я боюсь что вы все в нём запутаетесь. Я сам то в нём путаюсь

Вот чего могу пообещать, так это помочь вам распутать код. А когда распутаете, наверняка и сами сможете все поулучшить :) Если, конечно, готовы принимать к сведению критику. А то если "вам так удобнее" - я пас.

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

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

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

 А то если "вам так удобнее" - я пас.

Дак я почему обратился за помощью то?:)Потому что код мой жутко неудобный для восприятия. Сейчас сами всё поймете, ещё пару комментов допишу и выложу.

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

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

Я надеюсь у Вас @ARV не пойдет кровь из глаз...

 

#include "main.h"

char trig[4], butdown[4], //переменные для обработки нажатия на рычаг поворотника и кнопок
code, old_code, //переменные кода команды
prog_available=TRUE, count_right_prog, count_left_prog, prog_ini, prog_start,//переменные для режима программирования
count_turn=10, count_thx, //переменные для чтения из eeprom
accept_mode, accept_count, //переменные для режима подтверждения
turn_count, long_ini=FALSE, //переменные для режима удлинения поворотника
thx_count, thx_ini, //переменные для режима "Спасибо!"
count_right, count_left; //переменные для счёта мыргов от правого и от левого поворотника

int prog_available_count=0;

uint8_t EEMEM turn; //переменная EEPROM для хранения количества повторений поворотника в режиме удлинения 
uint8_t EEMEM thx; //переменная EEPROM для хранения количества повторений аварийки в режиме "Спасибо" 

uint8_t get_button(void)
{
	return PINB & ANY_K;
}

void press_button() //функция обработки нажатия на кнопку спасибо или включение заднего хода
{
	if(PINB&(1<<THX_REAR)) //опрос входа от кнопки спасибо\заднего хода
	{
		if(trig[THX_REAR]==OFF)
		{
			if(butdown[THX_REAR]<LONG)
			{
				butdown[THX_REAR]++;
				_delay_ms(10);
			}
			else //обработка при включении заднего хода
			{
				trig[THX_REAR]=ON;
				PORTB|=(ON<<LEFT_OUT)|(ON<<RIGHT_OUT);
			}
		}
	}
	else
	{
		if(trig[THX_REAR]==OFF)
		{
			if(SHORT<butdown[THX_REAR])// обработка при коротком нажатии на кнопкку спасибо
			{

				trig[THX_REAR]=ON;
				if((PINB&(1<<LEFT_OUT))){PORTB&=~(ON<<LEFT_OUT); PORTB&=~(ON<<RIGHT_OUT);}
				else{PORTB|=(ON<<LEFT_OUT)|(ON<<RIGHT_OUT);}
			}
		}
		else
		{
			if(butdown[THX_REAR]==LONG){PORTB&=~(1<<LEFT_OUT);PORTB&=~(1<<RIGHT_OUT);}
			trig[THX_REAR]=OFF;
			butdown[THX_REAR]=OFF;
		}
	}	
}

void Stand_by(void) //рычаг ПП выключен, огни погашены
{
	if(old_code==0)
	{
	if((count_right==1)||(count_left==1))
	{
		if(count_right==1)
		{
			PORTB|=(ON<<RIGHT_OUT);
		}
		if(count_left==1)
		{
			PORTB|=(ON<<LEFT_OUT);
		}
		else
		{
			if(accept_mode==0)
			{
				PORTB|=(ON<<LEFT_OUT);PORTB|=(ON<<RIGHT_OUT);
			}
		}
	}
	}
	else
	{
		if(old_code==6)
		{
			if(prog_ini==ON)
			{
				eeprom_write_byte(&turn, count_turn); eeprom_write_byte(&thx,count_thx); accept_mode=ON;PORTB|=(ON<<LEFT_OUT);PORTB|=(ON<<RIGHT_OUT);
			}
		}
	}
}

void Ligts_On_Right(void) //рычаг ПП включен вправо, горит правый поворотник
{
	if(old_code==2)
	{
		if(long_ini==ON)
		{
			count_right++;
		}
		else
		{
			if(prog_available==ON)
			{
				turn_count++;
			}
			else
			{
				long_ini=ON;count_right++;PORTB|=(ON<<RIGHT_OUT);
				if(prog_available==TRUE)
				{
					count_right_prog++;
				}
			}
		}
	}
	else
	{
		if(old_code==0)
		{
			if(long_ini==ON)
			{
				count_right++;
			}
			else
			{
				if(count_right==1)
				{
					count_right=0;
				}
				if(prog_ini==ON)
				{
					if(turn_count<MAX_TURN)
					{
						turn_count++;
					}
				}
				else
				{
					if(prog_available==TRUE)
					{
						count_right_prog++;
						if(count_right_prog>3)
						{
							prog_available=FALSE;
						}
					}
				}
			}
		}
	}
}

void Ligts_On_Left(void) //рычаг ПП включен влево, горит левый поворотник 
{
	
	if(old_code==2)
	{
		if(long_ini==ON)
		{
			count_left++;
		}else
		{
			if(prog_ini==ON)
			{
				thx_count++;
			}
			else
			{
				long_ini=ON;PORTB|=(1<<LEFT_OUT); count_left++;
				if(prog_available==TRUE)
				{
					count_left_prog++;
				}
			}
		}
	}
	else
	{
		if(old_code==0)
		{
			if(long_ini==ON)
			{
				count_left++;
			}
			else
			{
				if(count_left==1)
				{
					count_left=0;
				}
				if(prog_ini==ON)
				{
					if(thx_count<MAX_THX)
					{
						thx_count++;
					}
				}
				else
				{
					if(prog_available==TRUE)
					{
						if(count_right_prog==3)
						{
							count_left_prog++;
							if(count_left_prog==3)
							{
								prog_ini=ON; thx_count=0; turn_count=0;prog_available=FALSE;prog_start=0;
							}
						}
						else
						{
							prog_available=FALSE;
						}
					}
				}
			}
		}
	}
}

void Lights_Pause(void) //рычаг ПП включен в какую-либо сторону, либо включена аварийка, огни погашены
{
	
	if(old_code==3)
	{
		if(count_right==1)
		{
			long_ini=OFF;PORTB&=~(1<<RIGHT_OUT);
		}
		if(long_ini==ON)
		{
			if(count_right==count_turn)
			{
				long_ini=OFF;PORTB&=~(1<<RIGHT_OUT);count_right=0;
			}
		}
	}
	else
	{
		if(old_code==6)
		{
			if(count_left==1)
			{
				long_ini=OFF;PORTB&=~(1<<LEFT_OUT);
			}
			else
			{
				if(long_ini==ON)
				{
					if(count_left==count_turn)
					{
						long_ini=OFF;PORTB&=~(1<<LEFT_OUT);count_left=0;
					}
				}
				else
				{
					if(prog_ini==ON)
					{
						if(prog_start==ON)
						{
							accept_mode=ON;
						}
					}
				}
			}
		}
		else
		{
			if(old_code==7)
			{
				if(thx_ini)
				{
					if(thx_count==count_thx)
					{
						thx_count=0;thx_ini=OFF;PORTB&=~(1<<LEFT_OUT);PORTB&=~(1<<RIGHT_OUT);
					}
				}
				else
				{
					if(accept_mode==ON)
					{
						if(accept_count==3)
						{
							accept_mode=OFF;PORTB&=~(1<<LEFT_OUT);PORTB&=~(1<<RIGHT_OUT); accept_count=0;prog_start=0;
						}
					}
				}
			}
		}
	}
}

void Ligts_On_All(void) //включена аварийка горит оба поворотника
{
	
	if(old_code==3)
	{
		long_ini=ON;PORTB&=~(1<<RIGHT_OUT);count_right=0;
	}
	if(old_code==6)
	{
		long_ini=ON;PORTB&=~(1<<LEFT_OUT);count_left=0;
	}
	if(old_code==2)
	{
		if(thx_ini==ON)
		{
			thx_count++;
		}
		else
		{
			if(accept_mode==ON)
			{
				accept_count++;
			}
		}
	}
	if(old_code==0)
	{
		if(long_ini==ON)
		{
			long_ini=OFF;PORTB&=~(1<<LEFT_OUT);PORTB&=~(1<<RIGHT_OUT);
		}
	}
	if(thx_ini==ON)
	{
		thx_count++;
	}
	else
	{
		if(accept_mode==ON)
		{
			accept_count++;
		}
	}
}

void get_command(char mode)
{

	if(!((old_code)==mode))
	{
		switch(mode)
		{
			case 0:{Lights_Pause(); break;} //рычаг ПП включен в какую-либо сторону, либо включена аварийка, огни погашены
			case 2:{Stand_by(); break;} //рычаг ПП выключен, огни погашены
			case 3:{Ligts_On_Right(); break;} //рычаг ПП включен вправо, горит правый поворотник
			case 6:{Ligts_On_Left(); break;} //рычаг ПП включен влево, горит левый поворотник
			case 7:{Ligts_On_All(); break;} //включена аварийка горит оба поворотника
			break;
		}
		old_code=mode;		
	}
}

void pol_ports(void) //опрос портов
{
	code=get_button();
	_delay_ms(10);
	if(code!=get_button()){code=10;}
}

ISR(TIM0_OVF_vect)
{
	if(prog_available==TRUE){prog_available_count++;if(prog_available_count>1220){PORTB|=(ON<<RIGHT_OUT);prog_available=FALSE;}} //отключаем возможность
		//входа в режим программирования после истечения 10 секунд с момента включения устройства
}

int main(void)
{
	port_ini();
	timer_ini();
	sei();
    while(1)
    {
		pol_ports();
		get_command(code); //вызов команды
		press_button();	//опрос кнопки спасибо/ЗХ
    }
}

Вот такую схемку накидал для проверки.

1.jpg.4b1b8ad793707604ac9f661c958847ac.jpg

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

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

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

Чтобы Вам @ARV  понять всю трагичность ситуации, просто взгляните на алгоритмы, которые я составил для каждой команды.

Скрытый текст

 

123.jpg

1231.jpg

1232.jpg

 

1234.jpg

1233.jpg

 

 

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

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

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

Ну зачем вы так сразу... надо ж было дать время на подготовку какую-то... 

В общем, кровь из глаз не пошла, но на грани :)

Сверните в спойлер алгоритмы, пожалуйста

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

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

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

Сверните в спойлер алгоритмы, пожалуйста

Готово. Должно же быть более красивое решение.... У меня же просто миллион if-else

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

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

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

Предлагаю начать с конца :)

ISR(TIM0_OVF_vect){
	if(prog_available==TRUE){
		prog_available_count++;
		if(prog_available_count>1220){
			PORTB|=(ON<<RIGHT_OUT);
			prog_available=FALSE;
		}
	} //отключаем возможность
//входа в режим программирования после истечения 10 секунд с момента включения устройства
}

int main(void){
	port_ini();
	timer_ini();
	sei();
  
	while(1){
		pol_ports();
		get_command(code); //вызов команды
		press_button();	//опрос кнопки спасибо/ЗХ
	}
}

1220 - магическое число, плохо, не понятно

В главном цикле откуда берется code? Не понятно. Если code берется из pol_port(), то почему эта функция не возвращает это значение? code = pol_ports(); и понятнее, и логичнее.

Кнопка "спасибо" разве не часть общего алгоритма? Почему ей особая честь обрабатываться отдельно, а не внутри get_commands()?

 

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

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

void Ligts_On_All(void) //включена аварийка горит оба поворотника

все if которые не имеют else переведите в switch(oldcode)

- А совесть в курсе? - А совесть в доле! :-D

Эксперт — это человек, который совершил все возможные ошибки в некотором узком поле.

Все грамматические ошибки являются авторским стилем изложения материала.

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

Раз уж у вас все равно есть прерывания от таймера, т.е. вы не боитесь асинхронных процессов, то я бы рекомендовал вам вообще поменять подход...

Смотрите: делаем мигание на таймере. Т.е. обработчик прерывания срабатывает, скажем, каждые 100 мс, ведет там подсчет времени, если надо, но главное, он управляет свечением лампочек. То есть смотрит, предположим, в массив лампочек, и мигает теми, для которых в массиве установлено разрешение. Разрешение может быть в виде количества вспышек. То есть если в массиве 0 - не мигает, если 1 - мигает 1 раз, если 2 - то 2 раза... Т.е. таймер посмотрел в массив - там НЕ НОЛЬ, значит, надо мигнуть и уменьшить на 1.

А основная программа занимается тем, что анализирует состояния внешних сигналов и формирует содержимое этого самого массива...

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

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

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

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

Предлагаю начать с конца :)

1220 - магическое число, плохо, не понятно

Попробую объяснить свой ход мыслей: Частота МК установлена на 8 МГц, предделитель таймера настроен на 256 (этого не видно потому что эти настройки вынесены в отдельный си.файл). Так же настроено прерывание по переполнению. Соответственно за 1 секунду таймер переполнится 8000000/256/256=122 раза. А за десять секунд соответсвенно 1220 :)

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

Кнопка "спасибо" разве не часть общего алгоритма? Почему ей особая честь обрабатываться отдельно, а не внутри get_commands()?

Часть общего, но её необязательно (а может даже и не нужно) рассматривать в совокупности с тремя сигналами. Так как там может быть два состояния: нажата долго, нажата коротко.

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

В главном цикле откуда берется code? Не понятно. Если code берется из pol_port(), то почему эта функция не возвращает это значение? code = pol_ports(); и понятнее, и логичнее.

uint8_t pol_ports(void) //опрос портов
{
	code=get_button();
	_delay_ms(10);
	if(code!=get_button()){code=10;}
	return code;
}

while(1)
{
    get_command(pol_ports()); //вызов команды
}

Вы это имели ввиду?

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

Раз уж у вас все равно есть прерывания от таймера, т.е. вы не боитесь асинхронных процессов, то я бы рекомендовал вам вообще поменять подход...

Сейчас попробую осмыслить Ваше предложение.

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

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

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

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

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

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

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

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

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

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

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

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

×
×
  • Создать...