Свежие обсуждения
Микроконтроллеры

Ликбез по С для микроконтроллеров PIC

1 47 64

Хорошо, есть такое:
IF... {}
ELSE ...
{
if(input(Pin_E0)) { PlusFlag = 1; }
else if(input(Pin_E1)) { PlusFlag = 0; }
else a = 0; break;
............
}

Вот break, что сделает? Прервет выполнение условия ELSE?
Или вообще ничего не сделает?

 

Left Radio break прервет весь ваш IF...Else, хотя в последнем случае смысла в использовании break нету, так как по любому на данном этапе произойдет выход из обработчика.

 

Арс: Вообщем, могу на спор любую структуру с goto переписать без него
У меня что-то не пришло ничего путного на ум и пришлось оставить с goto. Вот привожу кусок кода, где собрано практически все операторы goto из всей программы(780 строк кода для PIC16F876A и в итоге 2563 слов):

#bit key1 =key.0
#bit key2 =key.1
#bit key3 =key.2
#bit key4 =key.3
#bit alarm1 =alarmall.0 //
#bit alarm2 =alarmall.1 //
#bit alarm3 =alarmall.2 //
#bit alarm4 =alarmall.3 //
#bit alarm5 =alarmall.4 //
#bit alarm6 =alarmall.5 //
#bit alarm7 =alarmall.6 //
#bit alarm8 =alarmall.7 //-
...

#int_rb
void detect_rb()
{
key=0;
key=(input_b()^0x0f)&0x0f;
if(alarm6) goto out2;
if(!mig && !alarm7)
{
if(key1)
{
if(!migall) {migdow =1;goto out1;}
migall<=1; if(mig) migall=0;
}
out1: if(key4)
{
if(!alarm1) {alarm1=1;migall=0;bit_set(migall,(dow-1));goto out2;}
if((alarmall&0x0f)==0x01) {alarm2=1;goto out2;}
if(alarm2) {alarm2=0;alarm3=1;goto out2;}
if(alarm3) {alarm3=0;alarm4=1;goto out2;}
if(alarm4) {alarmall=0x00;migall=0;}
}
}
out2: migall^=0x80; //if(mig) mig=0; else mig=1;
}
/b>
(комментарии убрал т.к. не смог переконвертировать в нормальную кодировку хотя недавно делал тоже самое, а сейчас забыл где та утилитка)
Как уже написал это практически все goto из программы и "сосредоточены" они в п/п прерывания #int_rb как видите и есть еще один последний goto из программы:
...
if(alarm1) goto alarm; //Переход на отображение времени будильника если нужен
...
Код программы "вылизал" практически до нельзя в плане того чтобы как можно меньше места занимал в памяти. Конечно еще памяти осталось навалом, но планирую ее заполнить голосовыми сообщениями. Вот что можете сказать по этому поводу?

 

chav1961: А почему именно через switch? Чем if не устраивает?

Тогда четыре условия надо проверять.

Left Radio: Вот такая конструкция работать не хочет

В принципе, если выражение в операторе switch (input(Pin_E0) & input(Pin_E1)) у вас целочисленное
и принимает значения Pin_E0 и Pin_E1, то всё должно работать.

Давайте посмотрим на определения Pin_E0 и Pin_E1.

 

ivasi: Left Radio break прервет весь ваш IF...Else, хотя в последнем случае смысла в использовании break нету,
так как по любому на данном этапе произойдет выход из обработчика.

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

 

GM: В принципе, если выражение в операторе switch (input(Pin_E0) & input(Pin_E1)) у вас целочисленное
и принимает значения Pin_E0 и Pin_E1, то всё должно работать.

То есть выражение типа input(Pin_E0) & input(Pin_E1) в операторе switch это типа мат. действие ?
А я то по глупости подумал что это обозначает тоже самое что и в операторе if, или одно или другое.

GM:
Давайте посмотрим на определения Pin_E0 и Pin_E1.

Если нажата кнопка "плюс" то Pin_E0 = 1, не нажата Pin_E0 = 0.
То же и с кнопкой "минус" и Pin_E1.

Ну ладно разберусь, а пока вот во вложении написано по мегаблоксхеме by Vladikas
Все пойду я, пока время есть, платы своим микроскопом сверлить .

174269.c

 

Я не совсем понял, что задумывалось сделать в той программе, но функцию обработки "+" и "-" я сделал бы так:


int counter=0
void Button(void)
{
int dest; //направление
if (input(Pin_E0)) dest=1; else dest=0;
if (input(Pin_E1)) dest--;
if (dest=0) {counter=0; return;} // не нажата ни одна из кнопок или нажаты обе сразу
if (counter<8) counter++; else dest*=4;
value+=dest;
if (value < 10) value=10;
else if (value>245) value=245;
}

И вставил бы её вызов прямо в обработчик прерывания.
Эта функция обрабатывает 8 одиночных автонажатий, а потом увеличивает скорость в 4 раза.
Там можно подумать над оптимизацией, например замену умножения на битовые операции.

ЗЫ. Я не знаю, что возвращает функция input, если она возвращает только 0 или 1, то вместо 2-х условных операторов можно написать:

dest =input(Pin_E0)-input(Pin_E1);

 

Left Radio: То есть выражение типа input(Pin_E0) & input(Pin_E1) в операторе switch это типа мат. действие ?
А я думал, что это означает то же самое, что и в операторе if, или одно или другое.

Оператор IF имеет след. синтаксис IF(логическое выражение), где ЛВ может принимать только два логических значения true или false.

Оператор SWITCH имеет след. синтаксис SWITCH(арифметическое выражение), где АВ может принимать значения типа integer

А у вас получается, что для оператора SWITCH вы даёте 0&1=0, если нажата Pin_E0 или 1&0=0, если нажата Pin_E1.
И всё время переходите на вариант default, только в случае, когда нажаты обе кнопки 1&1=1, вы перейдёте на case Pin_E0, при условии, Pin_E0=1.

 

AleksBak:
out1: if(key4)
{
if(!alarm1) {alarm1=1;migall=0;bit_set(migall,(dow-1));goto out2;}
if((alarmall&0x0f)==0x01) {alarm2=1;goto out2;}
if(alarm2) {alarm2=0;alarm3=1;goto out2;}
if(alarm3) {alarm3=0;alarm4=1;goto out2;}
if(alarm4) {alarmall=0x00;migall=0;}
}
out2:

Я кусочек вашей программы модернизировал, остальное по аналогии можно сделать


out1: if(key4)
{
.if(cond1) oper1();
.else
.{
..if(cond2) oper2();
..else
..{
...if(cond3) oper3();
...else if(cond4) oper4();
..}
.}
}
out2:

(В начале строк поставил точки вместо пробелов, скипа переформатирует, невзирая на теги пре, надо Andy сказать)

 

GM

Спасибо, теперь буду знать.

SAK: Я не совсем понял, что задумывалось сделать в той программе......

Мне аж стыдно стало.... Такого монстра написать, а тут так все просто.
Правда возникает вопрос о дребезге, Как вы с ним боритесь?