tuma 0 12 августа, 2011 Опубликовано 12 августа, 2011 (изменено) · Жалоба Добрый день, коллеги! Возможно я что-то недопонимаю или не знаю в C, посему возник такой вопрос: #include <stdio.h> void SendString (const char _String[]) { unsigned int i = 0; while (_String[i] != '\0') { printf ("%c\n", _String[i]); i++; } } int main (void) { SendString ("LaLa"); return 0; } Прекрасно работает на i386. Но ни одна из void SendString (const char _String[]) { unsigned int i = 0; while (_String[i] != '\0') { SendChar (_String[i]); i++; } return; } void SendString2 (const char *_String) { while (*_String) { SendChar (*_String++); } } ... SendString ("1234567890"); SendString2 ("1234567890"); ... функций не работает - в функцию SendChar передаётся мусор. Самостоятельный вызов SendChar ('a'); работает прекрасно. Как нужно правильно передавать параметры на ATMega/AVR-GCC. Изменено 12 августа, 2011 пользователем Tuma Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Mareng 1 12 августа, 2011 Опубликовано 12 августа, 2011 · Жалоба void SendString (char String[]) { unsigned int i = 0; while (String[i]) SendChar (String[i++]); return; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tuma 0 12 августа, 2011 Опубликовано 12 августа, 2011 · Жалоба Mareng, увы, не помогло. Упорно присылает только первый символ, а далее - мусор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Mareng 1 12 августа, 2011 Опубликовано 12 августа, 2011 · Жалоба Самостоятельный вызов SendChar ('a'); работает прекрасно. А если подряд 5-10 раз вызвать SendChar() с разными аргументами? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 12 августа, 2011 Опубликовано 12 августа, 2011 · Жалоба Ответьте себе на два вопроса: - Какая архитектура у AVR и как это отражается на процедуре доступа к данным размещенным во Flash и RAM; - А Ваша функция SendChar() обеспечивает ожидание окончания процесса передачи символа. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tuma 0 12 августа, 2011 Опубликовано 12 августа, 2011 · Жалоба А если подряд 5-10 раз вызвать SendChar() с разными аргументами? О, что вы! С этого всё начиналось. :) Всё прекрасно работает. Я заметил что параметр gcc -O - влияет. void SendChar (char _Char) работает всегда. А вот void SendString (char String[]) показывает первый символ только при -O2 или -O3. При -O1 и -Os не показывается даже первый символ - только мусор. При -O2 или -O3 вместо двух символов SendString ("32"); приходит четыре символа: 3???, вместо четырёх - шесть: 3?????. Замена первого символа влияет, т.е. первый символ приходит корректно. При попытке послать один символ приходит один корректный символ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 12 августа, 2011 Опубликовано 12 августа, 2011 (изменено) · Жалоба Исходники функци передачи символа покажите. 0) не очень хорошая идея свои переменные (имена) начинать с подчёркиваний. Теоретически можно нарваться. В заголовочных файлах такое применяется для того, чтоьы с пользовательскими define не пересечься. Все приведённые Вами примеры располагают массив символов в ОЗУ. Формулу зависимости количества мусорных символов от параметра -O выводить не надо. Надо с причиной разбираться. Имейте в виду, что у других всё работает. Изменено 12 августа, 2011 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 12 августа, 2011 Опубликовано 12 августа, 2011 · Жалоба Все приведённые Вами примеры располагают массив символов в ОЗУ. Однако с точностью до наоборот - в приведенных примерах для AVR "массивы символов", ака строки, расположены в ROM. Прикольно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 12 августа, 2011 Опубликовано 12 августа, 2011 · Жалоба Однако с точностью до наоборот - в приведенных примерах для AVR "массивы символов", ака строки, расположены в ROM. Прикольно? Нет, в winavr строки по умолчанию располагаются в ОЗУ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 12 августа, 2011 Опубликовано 12 августа, 2011 · Жалоба Нет, в winavr строки по умолчанию располагаются в ОЗУ. Фу, какой моветон :(. Имеем строчку в ROM для инициализации строчки в RAM. При этом строки в общем-то явно тяготеют к константам. Тогда переходим к ответу на второй вопрос. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 12 августа, 2011 Опубликовано 12 августа, 2011 · Жалоба Фу, какой моветон :(. К сожалению, просто const ничего ГЦЦ не говорит про то, что надо в ROM складывать. Но концептуально правильно: указать секцию progmem надо явно, иначе мыж тупые, не знаем, в каком проце как чего... Так что, Вас IAR тоже зомбировал :), подсадив на удобную фичу. Шучу. printf_P("1234567890"); Знаменит тем, что форматную строку держит в РОМ адназначна, но при этом putchar() все-таки прописать придется :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 12 августа, 2011 Опубликовано 12 августа, 2011 · Жалоба К сожалению, просто const ничего ГЦЦ не говорит про то, что надо в ROM складывать. А const тут совсем ни причем - там все чисто все даже по умолчанию вполне разумно во flash класть. Так что, Вас IAR тоже зомбировал так к хорошему мгновенно привыкаешь :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tuma 0 15 августа, 2011 Опубликовано 15 августа, 2011 · Жалоба не очень хорошая идея свои переменные (имена) начинать с подчёркиваний. Меня ещё мой куратор на первой работе научил так выделять передаваемые в функцию параметры. В заголовочных файлах такое применяется для того, чтоьы с пользовательскими define не пересечься. Я как-то даже не задумывался что умудрюсь пересечься с какими либо объявлениями. Хотя теоретически это реально. Всем спасибо, всё переложено в память программы, всё работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 15 августа, 2011 Опубликовано 15 августа, 2011 · Жалоба Меня ещё мой куратор на первой работе научил так выделять передаваемые в функцию параметры. Очень плохой у вас куратор. Обычно с подчеркивания начинаются служебные зарезервированные имена компилятора, типа __DATE__, __FILE__ , __noop и прочее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tuma 0 16 августа, 2011 Опубликовано 16 августа, 2011 · Жалоба Обычно с подчеркивания начинаются служебные зарезервированные имена компилятора, типа __DATE__, __FILE__ , __noop и прочее. Вы же сами написали "__DATE__, __FILE__ , __noop" - всё с двумя подчёркиваниями, а я использую одно и всегда с заглавной буквы - _String, _UARTData и пр.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться