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

Cvavr Не Могу Понять Что Не Так If Else. Читаю Белова И Пытаюсь Писать Своё.


Vasyanew

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

Прошу не пинать сильно и по возможности указать где черпать более правильную инфу. Использую книгу "Разработка уст-в на мк AVR. А.В.Белов.

Встала поблема при использовании конструкции if else. Привожу код созданый в CVAVR

#include <mega32a.h>

void main(void)
{

#define kn1 PINB.4
#define kn2 PINB.5
#define kn3 PIND.0
#define kn4 PIND.1
#define kn5 PIND.2

#define led1 PORTA.6
#define led2 PORTA.4
#define led3 PORTA.3
#define led4 PORTA.2
#define led5 PORTA.1

PORTA=0x00;
DDRA=0xFF;

PORTB=0xF0;
DDRB=0x0F;

PORTC=0xFF;
DDRC=0x00;

PORTD=0xFF;
DDRD=0x00;

TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

MCUCR=0x00;
MCUCSR=0x00;

TIMSK=0x00;

UCSRB=0x00;

ACSR=0x80;
SFIOR=0x00;

ADCSRA=0x00;

SPCR=0x00;

TWCR=0x00;

while (1)
{

if ( kn1 == 0 ) led1 = 1; else led1 =0;

if ( kn2 == 0 ) led1 = 1; else led1 =0;

}
}

Проблема ледующая: данная конструкция работает при использовании только одной конструкции if else. Если их более одной то происходят судеса. При нажатии kn1 светодиод led5 начинает мигать, а при нажатии kn2 светодиод led6 светит неприрывно до момента отпускания кнопки kn2. Проверял в протеусе и на мекетной плате результат идентичен.

Конечным результатом было желание получить следующий алгоритм работы:

1 при нажатии kn1 светит led1 пока держим кнопку

2 при нажатии kn2 засвечивается led2 и при отпускании кнопки kn2 светодиод led2 продолжает светить

3 кнопка kn3 для выключения светодиода led2

4 исключить возможность подавать команды kn1 при работе светодиода led2

Нашел на форуме Atmega8 Включение Реле. сделал аналогично, не помогло.

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

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

if ( kn1 == 0 ) led1 = 1; else led1 =0;
if ( kn2 == 0 ) led1 = 1; else led1 =0;

Тут в условии только LED1. Разумеется если kn1 и kn2 находятся в разных состояниях - первое условие будет ставить одно значение LED1, и второе условие тут же будет менять его на противоположное, т.к. во всех условиях led1.

Причём тут led5 и led6, мне вообще неясно. константа led6 даже в программе не определена. Вообщем неплохо бы сначала вопрос более чётко сформулировать и приложить конкретно Вашу схему, а не "наподобе этого"

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

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

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

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

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

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

Виноват "очепятка"

if ( kn1 == 0 ) led1 = 1; else led1 =0;

if ( kn2 == 0 ) led2 = 1; else led2 =0;

Это и есть конкретно она только переделовалась много раз, т.к. с одним условием работает, а если их становиться больше ничинаются "бока"

4 условиe было реализовано следующим кодом

if ( kn1 == 0 && led2 == 0 ) led1 = 1; else led1 =0;

if ( kn2 == 0 ) led2 = 1; else led2 =0;

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

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

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

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

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

Я конечно ни схемы, ни полного листинга программы так и не увидал, но есть подозрения, что все инструкции, следующие за else могут восприниматься как "иначе" в Вашем случае. Попробуйте записывать в такой форме:

//если
if (некие условия){
//тогда
}else{
//Иначе
}

Отпишите, изменилось ли поведение.

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

Полная схема - котроллер и реле, которые включают нагрузку - есть ли смысл это рисовать?

Листинг полный за исключением комментов написаный генератором CodeVisionAVR.

Как уже писал "Нашел на форуме Atmega8 Включение Реле. сделал аналогично, не помогло." - пробовал данную конструкцию и результат аналогичный.

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

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

if ( kn1 == 0 ) led1 = 1; else led1 =0;
if ( kn2 == 0 ) led2 = 1; else led2 =0;

Так писать откровенная глупость

Хотите проверить if ... else, пишите полную конструкцию, опуская не нужное сравнение в условии:

if ( kn1 ) {led1 = 0;} else {led1 =1;}
if ( kn2 ) { led2 = 0;} else {led2 =1;}

Хотите тот же функционал, есть куда более правильное решение:

led1=!kn1;
...

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

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

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

Во-первых описания нужного алгоритма в первом посте нет, есть только описание поведения ненужного. Я не нашёл во всяком случае нужного. Во-вторых полнота данных увеличивает вероятность решения проблемы с помощью форума. В-третьих Вам написали, что нужно сделать, включая конструкцию, которая вообще без условий будет работать. Большинство вопросов Вы проигнорировали, соответственно диалога не получится. Посему единственный совет - читайте внимательно книжку, если что-то не работает, в этом явно не Си виноват. Тем более если разработка секретная ( :crazy: ), нечего по форумам лазить.

** а нет, описание нужного алгоритма есть, но я его не заметил :)

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

if ( kn1 == 0 ) led1 = 1; else led1 =0;

Так писать откровенная глупость

Хотите проверить if ... else, пишите полную конструкцию, опуская не нужное сравнение в условии:

if ( kn1 ) {led1 = 0;} else {led1 =1;}

Простите, а в чем разница данных записей? Чем вам помешало сравнение в if? Изменено пользователем BerZerKku
Ссылка на комментарий
Поделиться на другие сайты

Конечным результатом было желание получить следующий алгоритм работы:

1 при нажатии kn1 светит led1 пока держим кнопку

2 при нажатии kn2 засвечивается led2 и при отпускании кнопки kn2 светодиод led2 продолжает светить

3 кнопка kn3 для выключения светодиода led2

4 исключить возможность подавать команды kn1 при работе светодиода led2

Вот такой код при условии, что 1 в kn соответствует нажатой кнопке, а 1 в led соответствует включенному светодиоду.

while(1){
led1=(!led2)&&kn1; //Если led2 выключен, транслируем состояние кнопки на led1
if (kn2) led2=1;//Если kn2 хоть раз замкнётся - светодиод led2 включится
if (kn3) led2=0;//Если kn3 хоть раз замкнётся - светодиод led2 погаснет
}

Простите, а в чем разница данных записей? Чем вам помешало сравнение в if?

Разница в том, что фигурными скобками чётко обозначены условные блоки. Лично я всегда использую фигурные скобки, чтобы небыло недомолвок, потому прямо не могу сказать, как без них будет работать. А в IF() сравнение с чем-либо переменных, у которых только два значения - скоро станет дурным тоном, если уже не стало.

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

Простите, а в чем разница данных записей? Чем вам помешало сравнение в if?

А нафига там оно в данном случае? Читайте внимательно описание конструкции, желательно не в Белове.

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

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

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

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

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

Редактирую, т.к. пока отходил и мого пропустил. Я признаю свою глупость и не боюсь признать ее.

if ( kn1 ) {led1 = 0;} else {led1 =1;}

if ( kn2 ) { led2 = 0;} else {led2 =1;}

led3 =! kn3

Все работает отлично. Благодарю.

Прошу гуру проинспектировать правильность составления кода.

if ( kn4 & !led1 ) { led4 = 0; } else { led4 = 1; }

Если не Белов, есть еще Лебедев. Более ничего не нашел чтоб стартовать с нуля. Если есть еще авторы прошу назвать, думаю кому интересно сами найдут книгу.

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

& на && заменить, а так вроде всё ок. И что Вам самому мешает проверить? :) Каждую строку на проверку присылать будете? :)... И вообще все эти выражения можно без условных конструкций писать, т.е. чистым присвоением с логическими операциями. Оно и работать будет быстрее, и памяти меньше занимать, и вообще грамотней в целом.

**что то Вы больно часто меняете номера кнопок и светодиодов, и тем более от задачи отклоняетесь. Я за Вами не поспеваю :crazy:

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

Лично я всегда использую фигурные скобки, чтобы небыло недомолвок, потому прямо не могу сказать, как без них будет работать. А в IF() сравнение с чем-либо переменных, у которых только два значения - скоро станет дурным тоном, если уже не стало.

Эм-м-м, как оригинально, говорить про дурной тон, при этом не зная базовых основ С.
Ссылка на комментарий
Поделиться на другие сайты

Если изучать Си, то по этой книге. Книга, так сказать из первых рук, люди написавшме её, перед этим написали сам язык Си :big_boss:

Yazyik_programmirovaniya_C.zip

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

Иван Сусанин - первый полупроводник

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

Хороших книг предостаточно. Главное, на мой взгляд, пока не разберешься с языком не связываться с "Пишем красиво..", "Стиль оформления..." и т.д.

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

Угу, стиль форматирования программ и написание комментариев придут сами, когда придется редактировать свой же код после, скажем, года.

Специально для Goodefine и Vasyanew прокомментирую поведение if: в зависимости от значения логической переменной выполняется тот или иной оператор, если значение 1 - между if и else, если 0 - после else. Оператор может быть, в том числе, и составным ({...}) и даже пустым (;). Поскольку аргументом является логическое выражение, а сравнивать обычно приходится все типы данных подряд, чаще всего используют операторы сравнения (<, >, <=, >=, ==, !=). В частности, для проверки отдельного бита, аргумент будет выглядеть так (x & (1<<bit_num)). Такой способ используется для проверки флагов и специальной переменной и, для контроллеров, логических уровней на выводах, иногда (1<<bit_num) заменяют на _BV(bit_num) или аналогичный макрос, это уже на любителя

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

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

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

Эм-м-м, базовые основы? Что это? я просто бесполезной информацией голову не забиваю - беру язык и делаю на нём то, что хочу. Ведь главное - это алгоритмы и окружение, а не самые "языковые караказябры". И незнание чего либо не запрещает мне рассуждать о тоне и писать в хорошем тоне по возможности. Практически у меня ни разу небыло необходимости if с else записывать в одну строку, именно поэтому я не знаю, как оно работает без фигурных скобок. Мне это незнание не мешает, поскольку необходимости писать в одну строку и сейчас нет, и в будущем не будет :) А если вдруг с чего-то понадобится, я думаю это вполне решаемо с помощью пары экспериментов.

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

Я честно-честно не понимаю как оператор if связан с записью в одну строку.

А что вы подразумеваете под "хорошим тоном"? С чего вы взяли что предложенная запись if() является "хорошим тоном"? Лично я больше доверяю K&R (да и своему опыту), в книге которых сказано что каждой записи свое место. А источник ваших рассуждений откуда берет корни?

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

А оператор '?' знаком? Ну например, в таком виде printf("a %c b\n",(a < b ? '<' : '>' ). Ведь по сути это тот же if, только для удобства свернутый.

Вообще, стилей форматирования кода масса и не следует выдавать привычный за "правило хорошего тона". Например, разработчики cvavr считают что в начале программы надо инициализировать вообще все, что только можно, обязательно с комментариями. Может быть, конечно, это делается для безопасности, чтобы все модули были так или иначе инициализированы, но после сброса и так все что нужно обнуляется (кроме ОЗУ). Однако это увеличивает код программы, хотя и не намного и, что хуже, затрудняет чтение: в километрах ненужного кода легко потерять нечто уникальное для данной схемы, включение аналогового компаратора, например, да и листать такие простыни взад-вперед тоже не самое приятное занятие. В частности поэтому лично я (и не только, встречал подобный подход и у других) объединяю несколько операторов в одной строке, если они близки по смыслу (DDRx=0xXX; PORTx=0xXX, тот-же if в одну строчку) и не превышают, или превышают ненамного ширину экрана. И конструкции вида

while(a){
//код
}
do{
//код
}while(a);

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

//------- новый блок кода или отдельная функция --------

это само собой. Так получается короче, то есть проще для чтения, и понятнее.

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

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

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

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

Я честно-честно не понимаю как оператор if связан с записью в одну строку.

Во-первых я чётко написал if - else в одну строку, а не просто if. И в том же посте ELSE выделено жирным, но Вы всё равно не заметили.

А что вы подразумеваете под "хорошим тоном"? С чего вы взяли что предложенная запись if() является "хорошим тоном"?

Опять невнимательно читаем. В посте #9 чётко написано, что нет особой нужды применять операторы сравнения в условиях для переменных, принимающих только два значения.

if (a==true) .........; //Масло маслянное, в 7 раз больше символов
//или
if (a) ...................; //Коротко и ясно, считаю хорошим тоном

//=========================================================================

if (a==false)........; //Масло маслянное, в 4 раза больше символов
if (!a) ..................; //Коротко и ясно, считаю хорошим тоном

А источник ваших рассуждений откуда берет корни?

Из собственного мнения.

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

Для логических переменных это верно, но они используются достаточно редко: невыгодно выделять целый байт если он будет принимать всего 2 значения. Для этого используются флаги, тогда в одной переменной (8-битной для определенности) можно хранить 8 булевых значений. А их так просто уже не вынуть. Конечно, есть и всякие извращения, как int x:1; или, как в cvavr биты портов, но на практике это зависит от реализации и использовать такие ходы в составе структур, например, не так-то просто. К тому же, в зависимости от компилятора, может меняться размер: либо эти однобитные переменные хранятся вместе, либо каждая в отдельной ячейке. А таких неопределенностей лучше избегать.

да, и про if(a==true) речи не было, было if(a==1), что гораздо нагляднее, чем if(a) хотя и немного дольше.

Во-первых я чётко написал if - else в одну строку, а не просто if. И в том же посте ELSE выделено жирным, но Вы всё равно не заметили.

Как будто есть разница, if(){} или if(){}else{}, оператор-то один и тот же, это скорее зависит от длины выражений. Согласитесь, глупо расписывать
if(PINA & (1<<PA1))
{
PORTB |= (1<<PB1);
}
else
{
PORTB |= (1<<PB2);
}

когда можно написать

if(PINA & (1<<PA1)) PORTB |= (1<<PB1);else PORTB |= (1<<PB2);

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

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

Для логических переменных это верно

Дело в том, что и для нелогических типов оно также верно. В остальном согласен. Хотя лично мне представляется маловероятным, что компилятор будет из 8 булей один байт собирать, скорее всего 8 байт затратит.... и потом... а каким собственно типом можно считать например #define kn1 PINB.4 ? Его и булевым можно трактовать запросто....

да, и про if(a==true) речи не было, было if(a==1), что гораздо нагляднее, чем if(a) хотя и немного дольше.

Речь об этом я завёл в самом начале, так что было. По поводу наглядности - скорее действительно дело привычки. Я одинаково хорошо обе формы записи воспринимаю.

Как будто есть разница, if(){} или if(){}else{}, оператор-то один и тот же, это скорее зависит от длины выражений.

Не не, беседа была о разнице между if(...){...;}else{...;} и if (...) ...; else ....; Первое (с фигурными) совершенно точно работает, а второе (как у автора в первом посте) явно не так, как положено работало (не смотря на то, что он опечатался с номерами led... или хуже того просто тупо сбил с толку и на самом деле всё работало). Лично мне запись с наличием else без фигурных скобок ни разу не было надобности делать, а потому хз как оно должно работать при таком раскладе...

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

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

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

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

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

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

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

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

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

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

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