Proteus, KiCAD и другие ECAD Разработчик так или иначе сталкивается с системами автоматизированного проектирования. Данный раздел - по САПР. |
27.03.2007, 15:44
|
|
Частый гость
Регистрация: 16.03.2007
Сообщений: 13
Сказал спасибо: 1
Сказали Спасибо 10 раз(а) в 2 сообщении(ях)
|
Особенности программирования на Си для AVR
Предлагаю "делиться" мыслями по тем или иным "проблемным" вопросам, тонкостям при программировании на Си для AVR (то есть с учетом ахритектурных особенностей МК).
.....
часто, при использовании "i", как временной переменной во всех попрограммах (функциях), может возникнуть следующая ошибка.
Если в функции, назовем ее "А", инициализируется временная (рабочая) переменная "i". Из "А" вызывается функция "В", в которой есть, допустим цикл (FO..NEXT), в котором в качестве счетчика используется переменная с тем же именем "i", то ошибочное значение переменной "i" в ф-циие "А", после возврата из "В", гарантировано.
ПРИЧИНА: Область видимости переменной "i", объявленной в "А" распространяется на все ф-ции, вызываемые из "А". То есть "В" работает не со своей (локальной) переменной "i", а с объявленной в "А".
РЕШЕНИЕ: Правильным решением будет объявление рабочей переменной в каждой функции. Такое решение не увеличивает длину кода, не влияет на время выполнения программы и позволяет избежать ошибок в работе программы.
P.S. Если ув.модераторы посчитают, что тему нужно переименовать, модифицировать каким-либо способом, буду только рад.
|
|
|
|
27.03.2007, 16:09
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.05.2006
Адрес: Москва
Сообщений: 3,559
Сказал спасибо: 76
Сказали Спасибо 326 раз(а) в 230 сообщении(ях)
|
Это противоречит моему учению - avr123.nm.ru/05a.htm
и Языку Си - "локальная переменная видна в той функции в которой объялена"
При вызове другой функции вы уже в другой функции находитесь.
Вот пример в прицепе.
Я однако в курсе советую не давать локальным переменным разных функций одинаковых имен.
Прикрепленный файл: 9541639.rar
__________________
Обучалка AVR PIC ARM начинающим программирование курс самоучитель шаг за шагом с нуля, CVAVR, PROTEUS, MPLAB, WinAVR, IAR, KEIL электроника - http://proavr.narod.ru
|
|
|
|
27.03.2007, 16:27
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.05.2006
Адрес: Москва
Сообщений: 3,559
Сказал спасибо: 76
Сказали Спасибо 326 раз(а) в 230 сообщении(ях)
|
Может у вас компилятор не правильный ?
У меня тест в CVAVR.
__________________
Обучалка AVR PIC ARM начинающим программирование курс самоучитель шаг за шагом с нуля, CVAVR, PROTEUS, MPLAB, WinAVR, IAR, KEIL электроника - http://proavr.narod.ru
|
|
|
|
27.03.2007, 16:43
|
|
Частый гость
Регистрация: 16.03.2007
Сообщений: 13
Сказал спасибо: 1
Сказали Спасибо 10 раз(а) в 2 сообщении(ях)
|
Сообщение от avr123-nm-ru
|
и Языку Си - "локальная переменная видна в той функции в которой объялена"
При вызове другой функции вы уже в другой функции находитесь.
|
Согласен, но только для условия, когда "вторая" функция НЕ является "вложенной" по отношению к "первой".
Прикрепленный файл: 9541639.rar
|
|
|
|
27.03.2007, 16:51
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.05.2006
Адрес: Москва
Сообщений: 3,559
Сказал спасибо: 76
Сказали Спасибо 326 раз(а) в 230 сообщении(ях)
|
Напиши прямо тут что значит вложеная функция?
Пример короткий прямо тут изобразите.
В моем примере из main вызывается функ_1 а из нее функ_2.
__________________
Обучалка AVR PIC ARM начинающим программирование курс самоучитель шаг за шагом с нуля, CVAVR, PROTEUS, MPLAB, WinAVR, IAR, KEIL электроника - http://proavr.narod.ru
|
|
|
|
27.03.2007, 19:24
|
|
Частый гость
Регистрация: 16.03.2007
Сообщений: 13
Сказал спасибо: 1
Сказали Спасибо 10 раз(а) в 2 сообщении(ях)
|
Сообщение от avr123-nm-ru
|
Напиши прямо тут что значит вложеная функция?
Пример короткий прямо тут изобразите.
В моем примере из main вызывается функ_1 а из нее функ_2.
|
"Вложенной" я называю функцию, которая вызывается из другой функции (на правильности терминологии не настаиваю), т.е. это функ_2 в Ващем примере.
....
поясню свое мнение на Вашем примере...
я говорю о том, что строка инициализации "char i;" в функ_2 обязательна. Убирите ее и результат работы будет неправильным. А компилятор нечего не "заподозрит".
|
|
|
|
27.03.2007, 19:59
|
|
Частый гость
Регистрация: 16.03.2007
Сообщений: 13
Сказал спасибо: 1
Сказали Спасибо 10 раз(а) в 2 сообщении(ях)
|
Еще одна мысль....
Про "return"
Возврат из подпрограммы (функции) лучше указывать явно, даже если функция ничего не возвращает ("void").
А еще лучше, возвращать значение нормального/ненормального завершения функции. Хотя, безусловно последнее увеличивает размер кода, но повышает "усточивость" работы и переносимость программы.
|
|
|
|
27.03.2007, 20:04
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.05.2006
Адрес: Москва
Сообщений: 3,559
Сказал спасибо: 76
Сказали Спасибо 326 раз(а) в 230 сообщении(ях)
|
Вы бы скачали компилятор на avr123.nm.ru на сером фоне и проверяли гипотезы прежде чем людей пугать.
=======
Очевидно компилятор заругался ОШИБКОЙ на то что переменная i не объявлена в функции 2.
=======
Вобщем сделайте пример подтверждающий ваши слова и тогда опубликуйте.
__________________
Обучалка AVR PIC ARM начинающим программирование курс самоучитель шаг за шагом с нуля, CVAVR, PROTEUS, MPLAB, WinAVR, IAR, KEIL электроника - http://proavr.narod.ru
|
|
|
|
27.03.2007, 20:57
|
|
Гражданин KAZUS.RU
Регистрация: 16.12.2004
Сообщений: 587
Сказал спасибо: 13
Сказали Спасибо 23 раз(а) в 9 сообщении(ях)
|
Можетъ я чё то не въехал, но что за компилятор Вы используете. Не используете ли Вы оптимизацию? А то там и не такое может быть. Описанный здесь случай видел лично ри работе в GreenHeel, но там это было связано с переполнением количества регистровых переменных, т.е. баг компилятора. Я например пользуюсь IAR и ни когда такой чуши не видел. По правилам локальное имя (переменная) объявленная внутри функции более приоритетное, т.е. именно локальная переменная будет вызываться а не глобальная. Второе: если переменная объявлена внутри функции, т.е. является локальной, то она видима только внутри ЭТОЙ функции и ни где более. Любой вызов другой функции ни как не влияет на эту переменную, если только ссылка на неё не является аргументом этой функции. И внутри любой функции никакие локальные переменные функции вызывающей не видны. Скорее всего это баг или после вызова функции эта переменная (регистровая) стала не нужна и была "съедена" компилятором. Например:
void BiBik(int nRaz)
{
int i = 3;
for(int i=0;i‹nRaz;i++)
Beep();
while(i--)
Beep();
}
int main(void)
{
int i = 4;
// тут i = 4
BiBik(i);
// тут i уже не определено, но при SAVE_I != 0 i по режнему == 4
#if SAVE_I
for(i=0;i‹3;i++)
{
BiBik(i);
Sleep(500);
}
#endif
}
Просто компиляторы не совсем тупые и они умеют рачительно использовать регистровые переменные, а именно в регистрах локальным переменнм и место. Поэтому не смотрите в отладчике, чего там вышло с переменной, когда она вам боле не требуется (хотя при отладке иногда это ой как хочется посмотреть).
|
|
|
|
27.03.2007, 21:39
|
|
Частый гость
Регистрация: 16.03.2007
Сообщений: 13
Сказал спасибо: 1
Сказали Спасибо 10 раз(а) в 2 сообщении(ях)
|
Сообщение от avr123-nm-ru
|
Вы бы скачали компилятор на avr123.nm.ru на сером фоне и проверяли гипотезы прежде чем людей пугать.
=======
Очевидно компилятор заругался ОШИБКОЙ на то что переменная i не объявлена в функции 2.
=======
Вобщем сделайте пример подтверждающий ваши слова и тогда опубликуйте.
|
Вы правы, в моей рекомендации есть неточность (точнее не указано принципиальное условие).
Вот она...
В своих программах рабочую переменную "i" для работы в фун-ции main я объявлял за ее (main) пределами (там же, где у Вас объявлена переменная "temp"), что автоматически делало "i" - "общей" (public).
С ЭТИМ "уточнением" все мои утверждения верны.
Пример у себя (старый)найти не смог, написал новый, аналогичный Вашему. Прим. Простота используемых функций не позволяет оценить легкость возможного совершения ошибки. Если функция содержит 10..20 строк, да к тому же изобилует циклами, и операторы написаны в строку (для "экономии" места), то ошибки весьма вероятны.
Прикрепленный файл: 70002.rar
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Тема |
Автор |
Раздел |
Ответов |
Последнее сообщение |
Краткий обзор методов помехоустойчивого программирования для
|
Don_Ambrosio |
Микроконтроллеры, АЦП, память и т.д |
0 |
09.04.2008 01:17 |
О стилях программирования на C для МК
|
Prime |
Микроконтроллеры, АЦП, память и т.д |
13 |
04.04.2008 14:12 |
Особенности использованя ATiny45
|
BodyZ |
Микроконтроллеры, АЦП, память и т.д |
5 |
24.07.2007 22:26 |
Особенности прописывания Tiny13,
|
delay |
Микроконтроллеры, АЦП, память и т.д |
0 |
02.11.2005 22:00 |
Какие необходимые условия для программирования PIC?
|
graham |
Микроконтроллеры, АЦП, память и т.д |
4 |
17.10.2005 21:18 |
Часовой пояс GMT +4, время: 12:12.
|
|