|
Повторный вызов функции |
|
|
|
Dec 1 2005, 06:40
|
Местный
  
Группа: Свой
Сообщений: 269
Регистрация: 17-11-05
Из: Киров-Москва
Пользователь №: 10 957

|
Вопрос по повторному вызову функций. Есть такой алгоритм: читается с линии байт и по результатам чтения устанавливается ПРИЗНАК_А и РЕЗУЛЬТАТ_А. В зависимости от ПРИЗНАК_А производятся разные действия, одно из которых теперь уже в зависимости от РЕЗУЛЬТАТ_А может потребовать прием второго байта с линии. Так вот, когда второй байт принимаю, он всегда равен первому принятому байту. Я уже продублировал функцию приема с линии и для приема второго байта использую другую функцию с другими переменными. Но результат тот же. Это же алгоритм отлично работает на ассемблере. Причем когда идут однобайтовые команды, они принимаются нормально, при двухбайтовых происходит этот глюк. Код, к сожалению, выложить не могу, привожу условно. Хотелось бы теоретических рекомендаций, где я криво написал. Код РЕЗУЛЬТАТ_А = func_receive(); // тут же формируется через глобальную переменную ПРИЗНАК_А
switch (ПРИЗНАК_А) { case 1: func1; break; case 2: func2(РЕЗУЛЬТАТ_А); break; default: func3; break; }
void func2(unsigned char РЕЗУЛЬТАТ_А) { switch (РЕЗУЛЬТАТ_А) { case 1: func1_1; break; case 2: РЕЗУЛЬТАТ_Б = func_receive_2(); // РЕЗУЛЬТАТ_Б = РЕЗУЛЬТАТ_А всегда! if ((РЕЗУЛЬТАТ_Б & 2) == 0) PORTD &= 0xBF; else PORTD |= 0x40; break; } }
Сообщение отредактировал Георгий - Dec 1 2005, 10:24
--------------------
Обычно последним смеется тот, кто хуже соображает!
|
|
|
|
|
 |
Ответов
(1 - 14)
|
Dec 1 2005, 10:32
|
Местный
  
Группа: Свой
Сообщений: 269
Регистрация: 17-11-05
Из: Киров-Москва
Пользователь №: 10 957

|
Это была не ошибка, это я не дописал, сейчас исправил, проверяю я именно это бит, из-за этого злополучного бита и вся бодяга. А оптимизатор я отключал напрочь, не помогло. Регистра приемника нет, функция func_receive читает прямо с линии и выдает результат, только когда чтение упешно прошло. Я проверял, ошибки при приеме второго байта не возникает, значит байт принимается и где-то в недрах компилятора подменивается на предыдущий результат. Посмотрел еще раз листинги, возникло такое предположение - проверка условий на Си занимает больше времени, чем на Ассемблере, и программа просто не успевает вовремя дать подтверждение приема, источник не получив подтверждения еще раз высылает первый байт команды, который я благополучно принимаю за второй. Вечером проверю.
Сообщение отредактировал Георгий - Dec 1 2005, 10:59
--------------------
Обычно последним смеется тот, кто хуже соображает!
|
|
|
|
|
Dec 2 2005, 05:33
|
Местный
  
Группа: Свой
Сообщений: 269
Регистрация: 17-11-05
Из: Киров-Москва
Пользователь №: 10 957

|
Если бы вы внимательно прочитали, то увидели, у меня нет приемника, или регистра приемник, процедуры func_receive и и ее копия func_receive2 читают прямо с линии. Линия естественно проверяется на старт стоп паузу и т .п. Пока вечером копался, накопал еще хуже. 1. Результат, возвращаемый функцией, зависит от начального состояния переменной, которая загоняется в return. 2. Если принудительно возвращать нужный результат в return, программа все равно после отработки либо погасит, либо включит светодиод, в зависимости от начального состояния переменной РЕЗУЛЬТАТ_Б, даже если в самой функции эта переменная изменяется. Чем лучше дизассемблировать результатный HEX, чтобы посмотреть, что на самом деле наворачивает компилятор?
--------------------
Обычно последним смеется тот, кто хуже соображает!
|
|
|
|
|
Dec 2 2005, 10:10
|
Местный
  
Группа: Свой
Сообщений: 269
Регистрация: 17-11-05
Из: Киров-Москва
Пользователь №: 10 957

|
Нашел глюк компилятор, взгляните на куски листинга: (в процедуре приема func_receive) Код 56 if ((PIND & 4) > 0) Paritet++; \ 0000003E 9982 SBIC 0x10, 0x02 \ 00000040 9513 INC R17 57 delay40mks; \ ??inbyte_4: \ 00000042 EA20 LDI R18, 160 \ 00000044 952A DEC R18 \ 00000046 F7F1 BRNE $-2 (в процедуре приема func_receive2) Код 128 if ((PIND & 4) > 0) Paritet2++; \ 00000038 B300 IN R16, 0x10 129 delay40mks; \ 0000003A EA00 LDI R16, 160 \ 0000003C 950A DEC R16 \ 0000003E F7F1 BRNE $-2 Поэтому второй байт всегда принимается с ошибкой. Чем победить, пока не знаю. Упорно ставит IN
--------------------
Обычно последним смеется тот, кто хуже соображает!
|
|
|
|
|
Dec 6 2005, 12:55
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Георгий , может вместо Код if ((PIND & 4) > 0) и т. д. лучше попробовать Код if (PIND_Bit2) и т. д. ? Я допускаю, что Вы работаете в среде IAR v4.11.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|