|
|
  |
Оптимизатор кода в WinAVR, сплошное непонятство |
|
|
|
Aug 21 2006, 13:31
|
Местный
  
Группа: Свой
Сообщений: 335
Регистрация: 17-06-04
Из: Москва
Пользователь №: 35

|
Никак не могу понять, почему это требуется?: код без оптимизации работает, с оптимизацией по параметру "s" - приходится вставлять строки 170, 211 и 300. Как они влияют на работу? Смотрел листинг ассемблера - вроде ничего не меняется с их использованием, но ведь начинает работать!
Программа - начального уровня, конечно, но в самом начале хотелось бы уяснить, как оптимально писать...
--------------------
Всегда не хватает времени, чтобы выполнить работу как надо, но на то, чтобы ее переделать, время находится. (Закон Мескимена.)
|
|
|
|
|
Aug 21 2006, 13:48
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Эта.. А что у Вас не работает-то? Цитата Как они влияют на работу? На первый взгляд их влияние - задержка на ~20-30 тактов между записью в порт и считыванием.. вероятно там будет достаточно одного _NOP в строках 211 и 300. В 170 задержка скорее всего не нужна.
Сообщение отредактировал defunct - Aug 21 2006, 13:51
|
|
|
|
|
Aug 21 2006, 14:04
|
Местный
  
Группа: Свой
Сообщений: 335
Регистрация: 17-06-04
Из: Москва
Пользователь №: 35

|
Цитата(defunct @ Aug 21 2006, 17:48)  Эта.. А что у Вас не работает-то? индикатор должен писать код кнопки... так вот без строк 170 и 211 кнопка не считывается (  да, смешно, но разными подстановками в программе именно это и вырисовывается  ), а без 300-й - не выводится на экран, хотя и считывается, причем вместо 300 можно подставить вызов любой другой функции, а вот подстановка NOP ничего не дает  еще один прикол - при перестановке строк 169 и 170 порт так же не считывается, хотя и при этом ассемблерный код меняется адекватно - просто переставляются команды... да, стоит WinAVR-20060421
Сообщение отредактировал Panych - Aug 21 2006, 14:05
--------------------
Всегда не хватает времени, чтобы выполнить работу как надо, но на то, чтобы ее переделать, время находится. (Закон Мескимена.)
|
|
|
|
|
Aug 21 2006, 14:20
|
Местный
  
Группа: Свой
Сообщений: 335
Регистрация: 17-06-04
Из: Москва
Пользователь №: 35

|
Цитата(Tiro @ Aug 21 2006, 18:08)  1) ввод и вывод в АВР имеют встроенные синхронизаторы, что требует задержки в один такт перед считыванием пина _после изменения состояния соответствующего вывода_ (в дейташите раздел I/O-Ports -> Introduction) так я вроде учел... непонятно, как на это может влиять перемена строк 169 и 170... Цитата(Tiro @ Aug 21 2006, 18:08)  2) любые _внешние по отношению к обработчику прерывания_ переменные, модифицируемые в прерывании (и в вызываемых из обработчика функциях), должны иметь модификатор volatile, чтобы запретить компилятору оптимизацию при работе с ними. Это не особенность WinAVR, а общее правило использования оптимизирующих компиляторов при написании обработчиков прерываний. имеется в виду, что все дело в перегруженности прерываний? надо строго в прерываниях выставлять флаги, обрабатываемые в основном теле программы, чтобы как можно более сократить тело прерываний и уменьшить количество и вложенность функций в них?
--------------------
Всегда не хватает времени, чтобы выполнить работу как надо, но на то, чтобы ее переделать, время находится. (Закон Мескимена.)
|
|
|
|
|
Aug 21 2006, 14:44
|
Знающий
   
Группа: Свой
Сообщений: 781
Регистрация: 3-10-04
Из: Санкт-Петербург
Пользователь №: 768

|
1. Мне тоже непонятно, как влияет перестановка 169 и 170. Зато понятно, как влияют друг на друга 172 и 173
169 DDRA = 0; // DATA_LCD_IO = 0; 170 NOP( 1 ); 171 SETBIT( PORT_KN2, KN2 ); //включение 172 PORTB &= ~(1<<3);//CLEARBIT( PORT_KN1, KN1 ); //первого вывода 173 PORT_READ = PINA; // PORT_READ = READ_LCD; //считывание порта
которые скорее всего в ассемблере выглядят так out portb, reg1 in reg2, porta без задержки на такт, а она нужна.
2. Дело не в перегруженности прерываний, а в том, что компилятор может оптимизировать обращение к переменной, не объявленной как volatile
Пример:
int global_var;
ISR (vector) { global_var = 2; }
int main (void) { for (;;) { global_var = 1; // здесь произошло прерывание if (global_var == 2) { printf ("Почему я не попал сюда? Надо использовать volatile"); } } }
Компилятор оптимизировал обращение к global_var в функции main и вообще удалил ветку с if () как недостижимый код.
С уважением.
Сообщение отредактировал Tiro - Aug 21 2006, 14:59
|
|
|
|
|
Aug 21 2006, 14:52
|
Местный
  
Группа: Свой
Сообщений: 335
Регистрация: 17-06-04
Из: Москва
Пользователь №: 35

|
Цитата(Tiro @ Aug 21 2006, 18:44)  Зато понятно, как влияют друг на друга 173 и 174 я понял мысль, но приложенная программа является рабочей...
--------------------
Всегда не хватает времени, чтобы выполнить работу как надо, но на то, чтобы ее переделать, время находится. (Закон Мескимена.)
|
|
|
|
|
Aug 21 2006, 15:57
|
Местный
  
Группа: Свой
Сообщений: 335
Регистрация: 17-06-04
Из: Москва
Пользователь №: 35

|
Цитата(Tiro @ Aug 21 2006, 19:03)  Нажал табуляцию, потом еще что-то неглядя и все отправилось. а я и смотрю сообщение рваное какое-то... Цитата(Tiro @ Aug 21 2006, 19:03)  А мы вообще об одних и тех же строках говорим? Какой микроконтроллер используется? AtMega32... и я говорил о строка текста программы по Programmer Notepad
--------------------
Всегда не хватает времени, чтобы выполнить работу как надо, но на то, чтобы ее переделать, время находится. (Закон Мескимена.)
|
|
|
|
|
Aug 22 2006, 08:55
|
Знающий
   
Группа: Свой
Сообщений: 781
Регистрация: 3-10-04
Из: Санкт-Петербург
Пользователь №: 768

|
Переставил местами 169 и 170, откомпилировал с ключем -0s Код void SCAN_KEY(void) { //опрос кнопок 161: 162: uint8_t PORT_READ; //временыый регистр для считанного из порта 163: 164: //настройка направлений портов 165: SETBIT( DDR_KN1, KN1 ); //переводим выводы опроса \ 01d6 BB9A sbi 55-0x20,3 166: SETBIT( DDR_KN2, KN2 ); //кнопок на выход \ 01d8 BC9A sbi 55-0x20,4 167: SETBIT( PORT_KN2, KN2 ); //включение \ 01da C49A sbi 56-0x20,4 168: CLEARBIT( PORT_KN1, KN1 ); //первого вывода \ 01dc C398 cbi 56-0x20,3 169: NOP( 1 ); \ 01de 81E0 ldi r24,lo8(1) \ 01e0 0E94 0000 call NOP 170: DATA_LCD_IO = 0; \ 01e4 1ABA out 58-0x20,__zero_reg__ 171: SETBIT( PORT_KN2, KN2 ); //включение \ 01e6 C49A sbi 56-0x20,4 172: CLEARBIT( PORT_KN1, KN1 ); //первого вывода \ 01e8 C398 cbi 56-0x20,3 173: PORT_READ = READ_LCD; //считывание порта \ 01ea 89B3 in r24,57-0x20 174: if ( PORT_READ != 0xFF ) \ 01ec 8F3F cpi r24,lo8(-1) \ 01ee B1F1 breq .L49 Вот критичное место : Код 172: CLEARBIT( PORT_KN1, KN1 ); //первого вывода \ 01e8 C398 cbi 56-0x20,3 173: PORT_READ = READ_LCD; //считывание порта \ 01ea 89B3 in r24,57-0x20 Однако, Вы утверждаете, что здесь все ОК, а влияет строка 169. Есть только одно предположение - сигналы у Вас вне микроконтроллера устанавливаются медленно, и считываете вы значения, установленные в строках 167 и 168. Тогда 169 будет влиять, поскольку время установки сигналов будет определяться задержкой NOP. Берите в руки осциллограф, пишите тестовую программу, например переключайте ножку в 1 и 0 поочередно и смотрите прохождение сигнала. И объявите KEY так : volatile uint8_t KEY; С уважением.
|
|
|
|
|
Aug 23 2006, 22:04
|
Частый гость
 
Группа: Участник
Сообщений: 146
Регистрация: 16-05-05
Пользователь №: 5 069

|
А сюда смотрели? По моему похожая проблема. AVR _ Странное поведение портов! Автор: Sergio66 May 16 2006, 16:34 http://electronix.ru/forum/index.php?act=P...=10&t=16161__________ Цитата код без оптимизации работает, с оптимизацией по параметру "s" - приходится вставлять строки 170, 211 и 300. Как они влияют на работу? Ну так на то она и оптимизация, быстрее получается. Например переход со стр.171 (пины стали входами) на стр.175 (читаем, что на этих пинах), (без NOP), без оптимизации 12 тактов, с оптимизацией 5 тактов (в AVRStudio, чуть правленый код), болше чем в 2 раза. ____ К проблеме не относится.Но. Не надо при выходе из прерывания восстанавливать флаг I в SREG. reti сама это сделает, даже в ассемблере. А в Си, посмотрите листинг, SREG = 0b10000000;абсолютно бесполезна, все равно SREG сохраняется при входе и восстановится при выходе. _____ И еще, Вы уверены, что таймер1 у Вас выставлен правильно? _________ Александр2006 08 24
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|