Опасность 'goto'
|
|
retas |
Дата: Вс, 28.12.2008, 21:15 | Сообщение # 1 |
Группа:
Проверенные
Ранг:
Помогаю всем
Сообщений:
445
Замечания:
±
На сайте с 10.09.2007
Статус:
Offline
|
. Где то как то попадалось читать изречение спецов, что, якобы, в хорошей программе не должно быть каманд 'goto'. Почитывая про PicBasicPro опять наткнулся на подобное - мол с этими командами возможны глюки, лутче иметь дело с 'gosub'. . Я тут мучаюсь с одной программкой, в которой надо следить за несколькими датчиками одновременно, проверять их антидребезгом, хочется чтоб программа получилась удобно читаемой и мне в этом сильно помогает 'goto'. Если это грозит опасностями, мож кто взгляет на кусочек моего "творчества" и что либо предложет? Вот такой у меня "антидребезг": ' Применено: A.... ' if A=1 надо делать эту проверку . ..................B.....' установим в 1 если полная проверка даст положительный результат . ..................s_tr. ' счетчик в прерываниях от TMR0 (допустим каждые 10ms) . ..................P_x .' Нога порта на которой ловим единицы . ..................s1 ...' счетчик единиц . ..................s2 ...' счетчик проверок (скажем всего будем делать 100 проверок) ....IF A = 0.... then goto Lop2........ ' проверка не требуется, выходим ... IF s_tr > 0 then goto Lop2........ ' 10ms ещё непрошло, выходим ....IF P_x = 0 then goto Lop1......... ' 10ms прошло, но на P_x нет '1' ........s1 = s1+1............................ ' попалась '1' в нужное время ' Lop1: ........ s2 = s2 + 1........................... ' подсчитываем сделанные проверки .... IF s2 < 100....... then goto Lop2.. ' 100 раз ещё не проверяли, выходим .... IF s2 - s1 <= 20 then B = 1........ ' если получено 80% '1'-ниц ........ A = 0.................................... ' все дела - очищаемся ........ s1 = 0 ........ s2 = 0 . Lop2: ... . И ещё. Поделитесь, как вы составляете алгоритмы для своих програм - чертите на бумаге или пользуетесь какой то программой на компютере? . Спасибо.
Сообщение отредактировал
retas - Вс, 28.12.2008, 21:29
|
|
|
|
Romario |
Дата: Сб, 03.01.2009, 20:27 | Сообщение # 2 |
Группа:
Проверенные
Ранг:
Пытаюсь разобраться
Сообщений:
58
Замечания:
±
На сайте с 14.09.2007
Статус:
Offline
|
Возможно когда очень много переходов goto, то скорей всего будут глюки, да и запутаться в них можно. А так несколько goto глюки не вызовут, проверено на опыте. Для реализации сложных алгоритмов применяю и gosub и goto. Насчёт составления алгоритма. В основном описываю в виде тезисов, что должен делать МК в тех или иных ситуациях, а потом программировать. Чётким алгоритм не делаю, могу несколько раз его поменять, для достижения необходимого результата.
|
|
|
|
demanik |
Дата: Вс, 04.01.2009, 00:18 | Сообщение # 3 |
Группа:
Проверенные
Ранг:
Помогаю всем
Сообщений:
448
Замечания:
±
На сайте с 11.12.2007
Статус:
Offline
|
В пикбейсикпро не рекомендуют использовать goto если программа выходит за пределы одной кодовой страницы памяти. А вместо goto использовать BRANCHL. Вот выдержка из родного мануала правда на английском : Life After 2K Yes, there is life after 2K using the PicBasic Pro Compiler. PICmicro MCUs have a segmented code space. PICmicro MCU instructions in 14-bit core parts such as Call and Goto only have enough bits within them to address 2K of program space. To get to code outside the 2K boundary, the PCLATH register must be set before each Call or Goto. PBP automatically sets these PCLATH bits for you. There are a few restrictions imposed, however. The PicBasic Pro library must fit entirely into page 0 of code space (the first half of page 0 for 12-bit core devices). Normally this is not an issue as the library is the first thing in a PicBasic Pro program and the entire library is smaller than 2K. However, attention must be payed to this issue if additional libraries are used. Assembly language interrupt handlers must also fit into page 0 of code space. Putting them at the beginning of the PicBasic Pro program should make this work. See the upcoming section on assembly language for more information. The addition of instructions to set the PCLATH bits does add overhead to the produced code. PBP will set the PCLATH bits before any Call or Goto instruction on 12-bit core PICmicro MCUs with more than 512 words of code space, 14-bit core devices with more than 2K of code space and PIC17Cxxx devices with more than 8K of code space. There are specific PicBasic Pro instructions to assist with the 2K issues. BRANCHL was created to allow branching to labels that may be further than 1K locations away on PIC18Xxxx devices or on the other side of a page boundary for all other devices. If the PICmicro MCU has only one code page of program space, BRANCH may be used as it takes up less space than BRANCHL. If the microcontroller has more than one page of code space, and you cannot be certain that BRANCH will always act within the same page, use BRANCHL. The assembler may issue a warning that a page boundary has been crossed. This is normal and is there to suggest that you check for any BRANCHes that may cross a page boundary. В пртонбейсике такой опасности как я понял нету.
Попробуй всё и вся... может быть пол...
Сообщение отредактировал
demanik - Вс, 04.01.2009, 00:21
|
|
|
|
holyuser |
Дата: Вс, 04.01.2009, 02:53 | Сообщение # 4 |
Группа:
Проверенные
Ранг:
Могу и подсказать
Сообщений:
228
Замечания:
±
На сайте с 12.12.2007
Статус:
Offline
|
не смешите, в PBPro можно использовать GOTO везде и всегда, без ограничений (формальных) ... а вот, надо ли делать этого? вопрос отдельный...
|
|
|
|
Mixlich |
Дата: Пн, 05.01.2009, 08:36 | Сообщение # 5 |
Группа:
Проверенные
Ранг:
Новенький
Сообщений:
14
Замечания:
±
На сайте с 30.11.2008
Статус:
Offline
|
Я тоже столкнулся с проблемой GOTO, программа работала некорректно, пока не изменил на GOSUB
|
|
|
|
holyuser |
Дата: Пн, 05.01.2009, 15:42 | Сообщение # 6 |
Группа:
Проверенные
Ранг:
Могу и подсказать
Сообщений:
228
Замечания:
±
На сайте с 12.12.2007
Статус:
Offline
|
Не следует смешивать логические ошибки программы (конкретного алгоритма) с корректным выполнением операторов (комманд). Оператор GOTO в PBPro работает корректно, проблемы могут возникнуть только при неправильном его употреблении.
|
|
|
|
ADMIN |
Дата: Пн, 05.01.2009, 17:42 | Сообщение # 7 |
Администратор
Группа:
Администраторы
Ранг:
Специалист
Сообщений:
1085
Замечания:
±
На сайте с 20.08.2007
Статус:
Offline
|
Ес-сно, необходимо тщательно отслеживать направления работы программы, следить за стеком. А goto он и в африке goto.
|
|
|
|
retas |
Дата: Вт, 06.01.2009, 19:03 | Сообщение # 8 |
Группа:
Проверенные
Ранг:
Помогаю всем
Сообщений:
445
Замечания:
±
На сайте с 10.09.2007
Статус:
Offline
|
Уважаемый, basicpic! А разве gotо "дружит" со стеком? У меня PIC Simulator IDE после gotо всегда всовывает MOWLW 0X1F и ANDWF STATUS,F - думаю чтоб избежать проблем, но как эти команды могут помогать...?
|
|
|
|
ADMIN |
Дата: Вт, 06.01.2009, 19:20 | Сообщение # 9 |
Администратор
Группа:
Администраторы
Ранг:
Специалист
Сообщений:
1085
Замечания:
±
На сайте с 20.08.2007
Статус:
Offline
|
Могу объяснить, что я имел в виду. Представьте, вы по gosub перешли в ПП, из которой выходите по goto, забыв о том, что стек отработал на один уровень. Если это 16 пик, то хватит 8 проходов, что бы программа перестала быть управляемой.
|
|
|
|
evgenb |
Дата: Вт, 06.01.2009, 21:43 | Сообщение # 10 |
Группа:
Проверенные
Ранг:
Понимаю
Сообщений:
91
Замечания:
±
На сайте с 14.09.2007
Статус:
Offline
|
2.6.4. GOTO Постарайтесь не использовать слишком много GOTO. Пока GOTO является неизбежным злом, пытайтесь минимизировать их использование сколь возможно. Пытайтесь записывать ваш код логическими секциями и не прыгать по сторонам слишком много. При соблюдении этого, GOSUB может быть полезен. BRANCH Index,[Label{,Label...}] Для 12- и 14-битных ядер и PIC17Cxxx устройств, Label должна находиться на той же кодовой странице что и BRANCH. Если Вы не уверены, будут ли они на одной кодовой странице, используйте BRANCHL BRANCHL создавалась, чтобы позволить переходы к меткам, которые могут быть дальше чем 1K позиция на PIC18Xxxx устройствах или по другую сторону границы страницы для остальных устройств. Если PICmicro MCU имеет только одну кодовую страницу программного пространства, BRANCH может использоваться, она требует по меньше памяти чем BRANCHL. Если микроконтроллер имеет более чем одну страницу кодового пространства, и Вы не можете быть уверены, что BRANCH всегда останется внутри той же страницы, используйте BRANCHL. Выдержки из перевода описания языка demanik приводил на аглицком пояснение по теме GOSUB так же может без проблем переходить через страницы ( 2К ) так как в адресации используется два байта
Сообщение отредактировал
evgenb - Вт, 06.01.2009, 22:31
|
|
|
|
holyuser |
Дата: Вт, 06.01.2009, 23:19 | Сообщение # 11 |
Группа:
Проверенные
Ранг:
Могу и подсказать
Сообщений:
228
Замечания:
±
На сайте с 12.12.2007
Статус:
Offline
|
В практике я встречал одну-единственную ситуацию, когда без GOTO обойтись невозможно - это, когда нужно обойти секцию кода "DEFINE INTHAND...", если в программе используются прерывания на ассемблере.
|
|
|
|
igorkov |
Дата: Чт, 08.01.2009, 13:14 | Сообщение # 12 |
Группа:
Проверенные
Ранг:
Новенький
Сообщений:
2
Замечания:
±
На сайте с 12.05.2008
Статус:
Offline
|
В Вашем случае избавиться от goto можно примерно так: if (A <> 0) & (s_tr <> 0) then 'проверка требуется и 10 ms прошли s1 = s1 + P_x 'отсчёт единиц на P_x s2 = s2 + 1 'отсчёт проверок if s2 = 100 then 'проверили 100 раз: if (s2 - s1) <= 20 then B = 1 'проверка достоверности A = 0 : s1 = 0 : s2 = 0 'сброс переменных endif endif Lop2: Добавлено (08.01.2009, 1:14:07) --------------------------------------------- Небольшое уточнение: if (A = 1) & (s_tr = 0) then.............'проверка требуется и 10 ms прошли ....s1 = s1 + P_x...........................'отсчёт единиц на P_x ....s2 = s2 + 1...............................'отсчёт проверок ....if s2 = 100 then.........................'проверили 100 раз: ........if (s2 - s1) <= 20 then B = 1...'проверка достоверности ........A = 0 : s1 = 0 : s2 = 0...........'сброс переменных ....endif endif
|
|
|
|
retas |
Дата: Пт, 09.01.2009, 20:08 | Сообщение # 13 |
Группа:
Проверенные
Ранг:
Помогаю всем
Сообщений:
445
Замечания:
±
На сайте с 10.09.2007
Статус:
Offline
|
Уважаемый, igorkov! Ваш пример для меня довольно поучителен. Вы предложыли весьма забавную строчку: "s1 = s1 + P_x" - вот это находка, подумалось мне, но PIC Simulator IDE не позволяет так делать, а какая программа позволяет? Всем большое спасибо.
|
|
|
|
igorkov |
Дата: Сб, 10.01.2009, 01:57 | Сообщение # 14 |
Группа:
Проверенные
Ранг:
Новенький
Сообщений:
2
Замечания:
±
На сайте с 12.05.2008
Статус:
Offline
|
я проверял в связке MPLAB IDE v8.15 + PICBASIC PRO Compiler 2.47 - всё работает. можно ещё избавиться от одного 'if' следующим образом: B = ((s2 - s1) <= 20), однако в этом случае В будет принимать значения 0 и 255 в зависимости от результата сравнения.Добавлено (10.01.2009, 1:48:29) --------------------------------------------- а ещё проще, если s2 всегда отсчитывается до 100, проверять только s1: B = (s1 > 80); Добавлено (10.01.2009, 1:57:36) --------------------------------------------- смутившая Вас строка работает также в PROTON + BASIC Compiler v3.2.5.5 microBasic compiler for PIC v6.0.0.0
|
|
|
|
holyuser |
Дата: Сб, 10.01.2009, 03:04 | Сообщение # 15 |
Группа:
Проверенные
Ранг:
Могу и подсказать
Сообщений:
228
Замечания:
±
На сайте с 12.12.2007
Статус:
Offline
|
Quote (igorkov) смутившая Вас строка работает также в PROTON + BASIC Compiler v3.2.5.5 microBasic compiler for PIC v6.0.0.0 Могу еще добавить, что такая "строка" работает в любом бейсике, в т.ч. и в архивном Applesoft BASIC-е, 30-летней давности... Добавлено (10.01.2009, 3:04:06) --------------------------------------------- И вообще, я не понимаю, почему народ так напуган оператором GOTO? Ведь каждый оператор, при неправильном его употреблении приводит к одному и тому-же печальному результату...
Сообщение отредактировал
holyuser - Сб, 10.01.2009, 03:10
|
|
|
|