Dmitriy_V 0 13 ноября, 2007 Опубликовано 13 ноября, 2007 · Жалоба В CVAVR был с помощью CodeWizardAVR проект, в котором по таймеру менялось значение одного из портов. Практически без изменений этот же проект был перенесен в IAR. При тестировании в AVRStudio4 обе программы вели себя полностью одинаково и корректно. Однако в микроконтроллере корректно работала только программа, написанная в CVAVR. В IAR программа выполнялась, но без вызова прерывания. Контроллер прошивался в обоих случаях через CVAVR STK200. Поскольку в симуляторе обе программы работали корректно, то ошибка скорее всего возникает при создании hex файла. Формат вывода выставлен как Intel standart. В чем может быть проблема и какие настройки надо изменить, чтобы все работало нормально? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 13 ноября, 2007 Опубликовано 13 ноября, 2007 · Жалоба В чем может быть проблемаВ программе и настройках. Посмотрите размер стеков, хотя он не должен влиять на вызов прерываний, скорее на работоспособность всей программы. Показывайте код, будем смотреть. Можете выкинуть все, кроме инициализации, прерывания и пустого цикла в main(). Только сначала сами убедитесь, что в таком виде программа не работает. Если вдруг заработает - постепенно добваляйте код, пока не перестанет работать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kd_Rash 0 14 ноября, 2007 Опубликовано 14 ноября, 2007 · Жалоба точно-точно, со стеками в ИАР-е надо дружить Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dmitriy_V 0 15 ноября, 2007 Опубликовано 15 ноября, 2007 (изменено) · Жалоба Показывайте код, будем смотреть. Спасибо за участие и советы. Привожу код для CVAVR и IAR. Код, по-моему, проще не куда. Я его сделал после того, как два дня убил на отладку своей программы. В общем, то что мне надо, я уже переделал под CVAVR, но в симуляторе IAR заметно лидировал по тактам выполнения работы программы. Жалко терять скорость выполнения, она и так близка к критичной. IAR: ... CVAVR: ... Исправил, больше так не делайте. IgorKossak src.rar Изменено 16 ноября, 2007 пользователем IgorKossak Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 15 ноября, 2007 Опубликовано 15 ноября, 2007 · Жалоба А вы листинг смотрели? 99%, что цикл while (flag); ассемблировался в RJMP $-2. А ошибка ваша вот: volatile unsigned char flag; P.S. А такие большие куски кода надо прикладывать в виде файлов. Исправьте, пока не поздно, а то модераторы по шапке надают Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dmitriy_V 0 16 ноября, 2007 Опубликовано 16 ноября, 2007 · Жалоба А вы листинг смотрели? 99%, что цикл while (flag); ассемблировался в RJMP $-2. А ошибка ваша вот: volatile unsigned char flag; P.S. А такие большие куски кода надо прикладывать в виде файлов. Исправьте, пока не поздно, а то модераторы по шапке надают Огромное спасибо, буду пробовать. Листинг, конечно, смотрел, я его сам и писал . По поводу while(flag); : если он неправильно ассемблируется, то что можно использовать вместо него для задержки до срабатывания прерывания? По поводу ошибки: никогда не думал, что оптимизация может зайти так далеко. :crying: Можно еще вопросик не по теме? У меня в целевой программе есть переменная типа Int. При передачи нужно как можно быстрее передавать побайтно значение этой переменной. В настоящий момент данные передаются следующим образом: PORTA=A_int; ... PORTA=(A_int>>8) ... . Как мне кажется, такая передача не оптимальна. По-идее, можно зарезервировать определенные регистры под переменную и выводить уже регистры: PORTA=r15; ... PORTA=r15 . Подскажите пожалуйста, будет ли такой алгоритм более быстрым по сравнению с первым и каким образом можно зарезервировать регистры под переменную? Когда я пытался осуществить резервирование, IAR говорил что-то о необходимости в изменении каких-то настроек. Заранее благодарен. P.S. За большие вставки извиняюсь, не знал, больше не повторится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vvs5 0 16 ноября, 2007 Опубликовано 16 ноября, 2007 · Жалоба в опциях проекта C/C++ Compiler - Code - поле Register utilization резервируешь сколько тебе нужно байт (сильно не увлекайся) а потом в тексте пишешь что-то вроде __regvar __no_init unsigned char FLASH @ 15; // переменная FLASH в регистре 15 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 16 ноября, 2007 Опубликовано 16 ноября, 2007 · Жалоба Листинг, конечно, смотрел, я его сам и писал .Недопонял. Листинг генерит компилятор - там ассемблерный текст, в который скомпилился ваш исходник.По поводу while(flag); : если он неправильно ассемблируется, то что можно использовать вместо него для задержки до срабатывания прерывания? Он компилируется правильно. Вы неправильно написали исходный код - не указали компилятору (с помощью квалификатора volatile), что flag может в любой момент измениться где-то еще (в прерывании). Он видит, что перед циклом вы присвоили flag=1 и дальше сорвершенно правомерно решает, что поскольку внутри цикла flag не меняется, то и проверять его снова не имеет смысла. И поэтому цикл вырождается в бесконечный. Если же вы укажите flag как volatile - компилятор будет вынужден на каждом проходе цикла считывать flag снова. И ваш цикл будет работать так, как вы и задумали. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dmitriy_V 0 17 ноября, 2007 Опубликовано 17 ноября, 2007 · Жалоба Недопонял. Листинг генерит компилятор - там ассемблерный текст, в который скомпилился ваш исходник. У нас разные понятия о листинге программы. Поскольку я не силен в ассемблере (знаю только в общих чертах), то для меня листинг - это то, что я написал на C. Спасибо за разъяснения по ошибке. Теперь более понятно, получается, что CVAVR по-умолчанию считает все переменные volatile и поэтому работает правильно. Удручает при этом, что в симуляторе обе программы ведут себя одинаково. Впредь буду все глобальные переменные, используемые в прерывании, отмечать как volatile. Еще раз спасибо. в опциях проекта C/C++ Compiler - Code - поле Register utilization резервируешь сколько тебе нужно байт (сильно не увлекайся) а потом в тексте пишешь что-то вроде __regvar __no_init unsigned char FLASH @ 15; // переменная FLASH в регистре 15 Мне нужна всего одна переменная типа int. Спасибо за разъяснения, теперь понятно где чего резервировать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 17 ноября, 2007 Опубликовано 17 ноября, 2007 · Жалоба У нас разные понятия о листинге программы. Поскольку я не силен в ассемблере (знаю только в общих чертах), то для меня листинг - это то, что я написал на C.Во избежание дальнейших недоразумений - это называется исходным текстом, исходниками, source. А ассемблер надо знать хотя бы на уровне чтения листингов со словарем - т.е посмотреть, что же нагенерил компилятор и поставив себя на место процессора прокрутить в голове интересующий участок кода.получается, что CVAVR по-умолчанию считает все переменные volatile и поэтому работает правильно.У него просто более слабый опримизатор, видимо не способный вынести из цикла вычисления, которые не влияют на остальные операции в цикле.Удручает при этом, что в симуляторе обе программы ведут себя одинаково.В симуляторе в обоих программах вызывается прерывание? Тогда надо копать глубже. Если не победите к понедельнику, гляну на результат компиляции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 17 ноября, 2007 Опубликовано 17 ноября, 2007 · Жалоба У меня в целевой программе есть переменная типа Int. При передачи нужно как можно быстрее передавать побайтно значение этой переменной. В настоящий момент данные передаются следующим образом: PORTA=A_int; ... PORTA=(A_int>>8) ... . Можно не волноваться по данному поводу. IAR правильно поймёт вашу операцию и скомпилирует это в две команды МК. То есть эти два оператора будут соответствовать двум операторам ассемблера и выполнятся за два такта. Ну не считая конечно времени обращения к ячейкам. А время обращения зависит от типа применённой переменной A_int. Если она статическая, то время уйдёт примерно 7 тактов. Если это у вас в п/п, то переменная будет размещена в регистрах. PS: Ассемблер не страшен. Можно посмотреть результирующий листинг и посмотреть описание инструкций МК. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dmitriy_V 0 21 ноября, 2007 Опубликовано 21 ноября, 2007 · Жалоба В симуляторе в обоих программах вызывается прерывание? Тогда надо копать глубже. Если не победите к понедельнику, гляну на результат компиляции. С volatile все заработало. На самом деле в симуляторе я смотрел cof файл. В этом, наверное, и кроется результат несовпадения. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ALexx 0 22 ноября, 2007 Опубликовано 22 ноября, 2007 · Жалоба У меня в целевой программе есть переменная типа Int. При передачи нужно как можно быстрее передавать побайтно значение этой переменной. Как вариант - использование объединения: union{ uchar Bytes[2]; uint Word; }Val16; ... //где-то в программе... Val16.Word=0x1234; PORTA=Val16.Bytes[0]; // PORTA=0x34 PORTB=Val16.Bytes[1]; // PORTB=0x12 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 22 ноября, 2007 Опубликовано 22 ноября, 2007 · Жалоба Как вариант - использование объединения:И как это может ускорить выдачу в порт? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться