Страница 1 из 2
Помощ с программой
Добавлено: Чт мар 26, 2009 14:56:13
Arlleex
while (PINA.0=1 || PINA.1=1); // если на входе...
PORTD.0=1; // зажигаем 1 светодиод
delay_ms(100); // ждем
PORTD.0=0; // гасим
delay_ms(100); // ждем
PORTD.1=1; // зажигаем 2 светодиод
delay_ms(100); //ждем
PORTD.1=0; // гасим
delay_ms(100); // ждем
Я думаю так: МК ждет на вохде 0 или 1 порта А высокий уровень ( сигнал), и если дождалась - выполняет код. На входы и буду подавать положительное напряжение ИП, подтягивающие резиторы надо значит не ставить.
Почему компилятор выдает ошибку в этой строке?
while (PINA.0=1 || PINA.1=1); // если на входе...
Добавлено: Чт мар 26, 2009 15:00:11
ARV
потому что вы плохо знаете синтаксис языка Си: знак проверки на равенство ==, а не =, как у вас.
Добавлено: Чт мар 26, 2009 15:10:13
Arlleex
Но ведь Символ = обозначает присваивание!
Мы же ведь присваиваем выходу 0 или 1 порта А значение логической 1. И ставим перед ними while - это как если........
Почему мы приравниваем выходу порта А логическую 1?
Что то я в этом запутался немножко...
Добавлено: Чт мар 26, 2009 15:15:51
Arlleex
Вот даже с исправленным видом не работает...
Добавлено: Чт мар 26, 2009 15:16:17
sachok
У Вас условие пока PINA.1 равно лог 1 то делам что то, а не мы присваиваем PINA.1 уровень лог.1. Тесть нужно проверить наше условие:
Код: Выделить всё
while (PINA.0==1 || PINA.1==1); // если на PINA.0 есть лог.1 или на PINA.0 есть лог.1 - зажигаем 1 светодиод
{
PORTD.0=1; // зажигаем 1 светодиод
delay_ms(100); // ждем
PORTD.0=0; // гасим
delay_ms(100); // ждем
PORTD.1=1; // зажигаем 2 светодиод
delay_ms(100); //ждем
PORTD.1=0; // гасим
delay_ms(100); // ждем
}
Добавлено: Чт мар 26, 2009 15:22:31
ARV
Stalker46 писал(а):Но ведь Символ = обозначает присваивание!
Мы же ведь присваиваем выходу 0 или 1 порта А значение логической 1. И ставим перед ними while - это как если........
Почему мы приравниваем выходу порта А логическую 1?
Что то я в этом запутался немножко...
я вам расскажу, как быть должно, а уж что там ваш любимый
CVAVR делает на самом деле - я не знаю. сами разбирайтесь.
если мы пишем
if(var1 = var2), то компилятор поступает так: сначала переменная
var1 получает значение переменной
var2, а потом содержимое var1 проверяется на равенство нулю. т.е. это эквивалентно следующему:
var1 = var2;
if(var1)...
то есть в качестве значения выражения, состоящего из оператора присваивания, принимается значение переменной, получающей значение (т.е. значение левой части выражения).
если вы хотели занести в пину единички, то ваш
while становися бесконечным:
while(1 || 1) - не так ли? возможно, об этом вам компилятор и сообщает.
возможно, ему не понравилось такое совмещение присваивания с проверкой условия, т.к. он (компилятор ваш) шибко грамотный и использует точечную нотацию для манипуляций над битами (фича, отсутствующая в стандарте Си), при этом он генерирует асмовую инструкцию
SBI или
CBI. в то же время для проверки бита он использует инструкцию
SBIS или
SBIC - возможно в случае, когда присваивание совмещено с проверкой, он не понимает, что ему делать... короче, гадальщик из меня плохой... к тому же вы не потрудились привести матюк компилятора, что хоть как-то пролило бы свет на проблему...
на вашем месте я бы написал максимально просто все, не стремясь "одновременно" сделать несколько дел. во всяком случае, это помогло бы вам понять, что именно вы делаете...
Добавлено: Чт мар 26, 2009 15:29:17
Arlleex
Так у нас же PINA.1==1. это же и означает, что на входе 1 порта А логическая единица...
Добавлено: Чт мар 26, 2009 15:31:54
ARV
после того, как вы вместо = написали == - да, у вас началась проверка... а я пишу медленно
что вы вообще хотите? в чем проблема?
Добавлено: Чт мар 26, 2009 16:00:03
Yellow Tiger
ARV писал(а):компилятор ваш шибко грамотный и использует точечную нотацию для манипуляций над битами (фича, отсутствующая в стандарте Си), ... возможно в случае, когда присваивание совмещено с проверкой, он не понимает, что ему делать...
Именно - старая история с приоритетами операций и порядком исполнения - если присвоения выделить скобками, то все становится на свои места, так как после этого передается правильный порядок выполнения - сначала осуществить два присвоения, а затем уже привести значения обоих выражений и сложить по ИЛИ. Без этого выделения он пытается выполнить такие присвоения:
Код: Выделить всё
а) PINA.1 = 1
б) 1 || PINA.1 = <значение из а)> - ну, и кому здесь присваивать?
в) PINA.0 = <значение из б)>
См. скриншот - там внизу видна ругань компилятора (must be lvalue), а на одну строку выше (откомментарено) находится то же выражение, но с нужными скобками - ругань исчезает.
А вообще - он правильно намекает на "possibly incorrect assignment".
Лучший способ запутать компилятор - запутаться самому! Пусть-ка он попробует понять то, что и программист не понимает... А лучший способ запутаться самому - в полный рост использовать умолчания, о которых ничего не помнишь - каково старшинство операций, в каком поорядке они исполняются и т.д.
Скобки придумали слабые духом!
Сталкер46 - учись правильно писать бесконечные циклы!

У меня бесконечные циклы всегда компилировались без ошибок, а потом я сидел и ждаааал.... и думал - "а что это ничего не мигает?"

Добавлено: Чт мар 26, 2009 16:10:30
Arlleex
бесконечный щикл это и есть while...
что то в голове крутится а дойти не может...

Добавлено: Чт мар 26, 2009 16:14:39
ARV
Yellow Tiger писал(а):Именно - старая история с приоритетами операций и порядком исполнения
а разве приоритет
= не однозначно выше приоритета
||? или CVAVR по-своему приоритеты расставляет?
Добавлено: Чт мар 26, 2009 16:15:46
Yellow Tiger
Stalker46 писал(а):бесконечный щикл это и есть while...
Бесконечный цикл - это не
do не
while и не
for - это цикл без условия выхода.
Stalker46 писал(а):что то в голове крутится а дойти не может...

Выдели скобками, как показано и запусти - все скомпилируется, но проц
навсегда завсинет внутри этого цикла.
А заменишь "=" на "==" и все заработает. Вот над этой разницей в поведении и подумаешь, и все прояснится.
ARV писал(а):а разве приоритет = не однозначно выше приоритета ||?
Вот именно потому и не работает, что он использует правильные приоритеты - то есть, сначала пытается построить
цепочку присвоений, а до
|| даже не доходит, так как встречает непонятку - кому присваивать-то?
P.S. О! Пост № 4.12

Добавлено: Чт мар 26, 2009 16:24:42
Arlleex
Файл то у меня скомпилировался да не работает...
Ладно, вот пример, сделал все правильно...
#include <mega16>
#include <delay>
void main(void)
{
while (1)
{
// Place your code here
while (!PINA.0==0); // если не ноль...
{
PORTD.0=1; // включаем
delay_ms(100); // ждем
PORTD.0=0; // вырубаем
delay_ms(100); //ждем
}
};
}
но эта программа не работает в протеусе. Вот еще вопрос. когда выставляешь порты на вывод, там есть 1 или 0 что это обозначает?
Добавлено: Чт мар 26, 2009 16:27:30
Yellow Tiger
Stalker46 писал(а):Файл то у меня скомпилировался да не работает...
А я разве не то же самое тебе писал, вот только-что?

Добавлено: Чт мар 26, 2009 16:32:35
ARV
Yellow Tiger писал(а):Вот именно потому и не работает, что он использует правильные приоритеты - то есть, сначала пытается построить цепочку присвоений, а до || даже не доходит, так как встречает непонятку - кому присваивать-то?
точно... слева от знака равенства должно быть леводопустимое выражение, грубо говоря - переменная, а не выражение... с первым знаком равенства вроде понятно, а второе равенство - уже слева имеет не то, что можно

Добавлено: Чт мар 26, 2009 16:38:37
Yellow Tiger
ARV писал(а):точно... слева от знака равенства должно быть леводопустимое выражение, ...
Именно! Маст би эль-вэлью!

Добавлено: Чт мар 26, 2009 17:36:35
Arlleex
а что с этой прогой?
Скомпилировалась отлично, но в протеусе не пашет!
Поставил 0 выход порта Д на Единичку.
Вход сделал порт А, с подтягивающим резистором.
#include <mega16>
#include <delay>
void main(void)
{
while (1)
{
while (!PINA.0==0); // пока на входе 0 порта А не ноль, будет выполняться следующаю программа, а значит при единице
{
PORTD.0=1; // зажигаем 1 светодиод
delay_ms(100); // ждем
PORTD.0=0; // гасим
delay_ms(100); // ждем
}
};
}
Добавлено: Чт мар 26, 2009 17:46:25
ikarab
ARV писал(а): вы хотите, чтобы я стал разглагольствовать о выражении, результатом которого является указатель? думаю, тут и я запросто ошибусь, да и мало кто поймет из остальных... потому и грубо....
Нет. просто я формулирую грубо так: "Переменная должна быть левее присваивания"
потому что с лева может быть например + или & и много всего
переменная +=
переменная &=
Т.е. переменная не слева от присваивания а левее.
Такое определение - "левее" - включает и случаи когда переменная вплотную к присваиванию написана:
переменная =
Сне кажется что так понятней и точней.
Добавлено: Чт мар 26, 2009 21:03:53
Arlleex
вот когда на Си программу пишем, сначала пишем текст, затем смотрим, какие операторы применяли, например, delay_..., и пишем библиотеки - #include <delay> ?
Добавлено: Чт мар 26, 2009 21:26:36
Aheir
Мне когда-то один умный человек советовал записывать условия типа if (a == 5) в виде if (5 == a). Чувствуете разницу? Если в первом случае ошибиться и написать if (a = 5) компилятор это замечательно проглотит, но работать ничего не будет, как мы только что видели выше, а вот если по ошибке написать if (5 = a) - будет ошибка компиляции.