Проблема с опросом порта...
|
|
xxxmonejall |
Дата: Вт, 01.12.2009, 00:07 | Сообщение # 1 |
Группа:
Проверенные
Ранг:
Продвинутый
Сообщений:
139
Замечания:
±
На сайте с 17.05.2008
Статус:
Offline
|
Написал вот прогу для генерации импульсов. Так вот вышла такая загвоздка когда нажимаю на кнопку она опрашивается не раз а несколько раз. Как от этого избавится???? Прилагаю программу! @ device pic16F84, xt_osc, wdt_off, protect_off, pwrt_on DEFINE OSC 4 DEFINE LCD_DREG PORTB DEFINE LCD_DBIT 4 DEFINE LCD_RSREG PORTB DEFINE LCD_RSBIT 1 DEFINE LCD_EREG PORTB DEFINE LCD_EBIT 0 DEFINE LCD_BITS 4 DEFINE LCD_LINES 2 DEFINE LCD_COMMANDUS 2000 DEFINE LCD_DATAUS 50 TrisA = %11111111 czastota var byte impuls var word czastota = 10 ;Начальное значение бралось от фонаря impuls = 3000 LCDOUT $FE,1,"Ing_DIAG" pause 2000 LCDOUT $FE,1 Generation: if portA.0 = 1 then goto main1 ;Вот здесь проблема порт опрашивается несколько раз. Как от этого избавится???? if portA.1 = 1 then goto main2 ;И здесь???? pulsout portb.2,impuls pause czastota goto generation main1: czastota = czastota + 100 pause 2000 LCDOUT $FE,1 LCDOUT $FE,$80, dec czastota LCDOUT $FE,$C0, dec impuls goto generation main2: czastota = impuls + 2000 pause 2000 LCDOUT $FE,1 LCDOUT $FE,$80, dec czastota LCDOUT $FE,$C0, dec impuls goto generation
|
|
|
|
ADMIN |
Дата: Вт, 01.12.2009, 03:44 | Сообщение # 2 |
Администратор
Группа:
Администраторы
Ранг:
Специалист
Сообщений:
1086
Замечания:
±
На сайте с 20.08.2007
Статус:
Offline
|
В протеусе несколько раз? То есть несколько раз уходит на Main1, ждет 2 секунды и т.д.?
|
|
|
|
terrarus |
Дата: Вт, 01.12.2009, 13:27 | Сообщение # 3 |
Группа:
Пользователи
Ранг:
Помогаю всем
Сообщений:
451
Замечания:
±
На сайте с 21.08.2008
Статус:
Offline
|
Чето кажется мне что нужно так: Code @ device pic16F84, xt_osc, wdt_off, protect_off, pwrt_on DEFINE OSC 4 DEFINE LCD_DREG PORTB DEFINE LCD_DBIT 4 DEFINE LCD_RSREG PORTB DEFINE LCD_RSBIT 1 DEFINE LCD_EREG PORTB DEFINE LCD_EBIT 0 DEFINE LCD_BITS 4 DEFINE LCD_LINES 2 DEFINE LCD_COMMANDUS 2000 DEFINE LCD_DATAUS 50 TrisA = %11111111 czastota var byte impuls var word
czastota = 10 ;Начальное значение бралось от фонаря impuls = 3000
LCDOUT $FE,1,"Ing_DIAG" pause 2000 CLS
Generation: if portA.0 = 1 then Pause 150: Gosub main1 ;Вот здесь проблемы больше не будет! if portA.1 = 1 then Pause 150: Gosub main2 ;И здесь тоже не будет!
pulsout portb.2,impuls pause czastota
goto generation
main1: czastota = czastota + 100 pause 2000 ; А ДЛЯ ЧЕГО НУЖНА ЭТА ПАУЗА? Для снижения быстроействия всего устройства чтоли? LCDOUT $FE,1 LCDOUT $FE,$80, dec czastota LCDOUT $FE,$C0, dec impuls Return
main2: czastota = impuls + 2000 pause 2000 ; И эта тоже. Уберите эти паузы, думаю они не нужны. LCDOUT $FE,1 LCDOUT $FE,$80, dec czastota LCDOUT $FE,$C0, dec impuls Return
Если у в Вас что-то не получается, подумай, не стоит ли прочитать инструкцию...!
Сообщение отредактировал
terrarus - Вт, 01.12.2009, 13:34
|
|
|
|
brown |
Дата: Вт, 01.12.2009, 14:19 | Сообщение # 4 |
Группа:
Пользователи
Ранг:
Помогаю всем
Сообщений:
333
Замечания:
±
На сайте с 18.09.2007
Статус:
Offline
|
Может все таки не зря говорят, что нужно стараться поменьше использовать GO TO? Или как в ссылке http://www.picbasic.ru/forum/8-317-1 : Quote Квалификация программиста обратно-пропорциональна количеству операторов GO TO в программе.
Век живи - век учись! К концу жизни поймешь, что ничего не знаешь...
|
|
|
|
xxxmonejall |
Дата: Вт, 01.12.2009, 18:07 | Сообщение # 5 |
Группа:
Проверенные
Ранг:
Продвинутый
Сообщений:
139
Замечания:
±
На сайте с 17.05.2008
Статус:
Offline
|
Понял GOTO не использовать!!!
|
|
|
|
ADMIN |
Дата: Вт, 01.12.2009, 19:16 | Сообщение # 6 |
Администратор
Группа:
Администраторы
Ранг:
Специалист
Сообщений:
1086
Замечания:
±
На сайте с 20.08.2007
Статус:
Offline
|
Для xxxmonejall Вы хотите решить проблему? Програма составлена грамотно. Не знаю, что она должна решать, но то, что написано, не должно вызывать таких проблем, поэтому я спросил про протеус. Для terrarus: Пауза 150 мс ничего не решает, поскольку программа, обнаружив единицу на porta.0 или porta.1, всегда выполняет одно и то же действие? а именно - переход на ПП, в которой заложена уже задержка на 2000 мс. Дребезг контактов не играет здесь никакой роли. Я поясню, если не понятно: если кнопка предназначена для выполнения только лишь одной функции(а здесь так и есть - переход на ПП), то дребезг не играет никакой роли(если только, естественно, частота дребезга больше частоты следования команд, в чем я сомневаюсь), так как программа в любом случае перейдет на ПП. Дребезг может вносить непредвиденные изменения в случае, когда кнопка отвечает за изменение параметра при КАЖДОМ нажатии, и то, такое может случиться в случае прерывания по INT, например. Для Brown: Да какая разница, сколько goto? Если программа составлена правильно, то нет никаких причин думать на свои корявые руки и еще что-то? Может, иногда не стоит полностью доверяться протеусу? Может, кто-то заметил что то, чего я не увидел? Порекомендую написать в конце программы слово End.
|
|
|
|
xxxmonejall |
Дата: Вт, 01.12.2009, 21:17 | Сообщение # 7 |
Группа:
Проверенные
Ранг:
Продвинутый
Сообщений:
139
Замечания:
±
На сайте с 17.05.2008
Статус:
Offline
|
Всем Огромное спасибо. Проект заработал, вікладіваю проект в протеусе и код, может кому-то пригодится. УСТРОЙСТВО ПРЕДНАЗНАЧЕНО ДЛЯ Генерации ИМПУЛЬСОВ ДЛЯ ПРИБОРА НАСТРОЙКИ ГАЗОВЫХ ФОРСУНОК. @ device pic16F84, xt_osc, wdt_off, protect_off, pwrt_on DEFINE OSC 4 DEFINE LCD_DREG PORTB DEFINE LCD_DBIT 4 DEFINE LCD_RSREG PORTB DEFINE LCD_RSBIT 1 DEFINE LCD_EREG PORTB DEFINE LCD_EBIT 0 DEFINE LCD_BITS 4 DEFINE LCD_LINES 2 DEFINE LCD_COMMANDUS 2000 DEFINE LCD_DATAUS 50 TrisA = %11111111 czastota var byte impuls var word czastota = 10 impuls = 1500 LCDOUT $FE,$80,"Injector" LCDOUT $FE,$C0,"Diagnostic v.1,0" pause 2000 LCDOUT $FE,1 LCDOUT $FE,$80,"created by " LCDOUT $FE,$C0,"K2mozga.net" pause 2000 LCDOUT $FE,1 LCDOUT $FE,$80, dec czastota LCDOUT $FE,$C0, dec impuls Generation: if portA.0 = 1 then Pause 400: Gosub main1 if portA.1 = 1 then Pause 400: Gosub main2 if portA.2 = 1 then Pause 400: Gosub main3 if portA.3 = 1 then Pause 400: Gosub main4 pulsout portb.2,impuls pause czastota goto generation main1: czastota = czastota + 5 LCDOUT $FE,1 LCDOUT $FE,$80, dec czastota LCDOUT $FE,$C0, dec impuls goto generation main2: impuls = impuls - 50 LCDOUT $FE,1 LCDOUT $FE,$80, dec czastota LCDOUT $FE,$C0, dec impuls goto generation main3: czastota = czastota - 5 LCDOUT $FE,1 LCDOUT $FE,$80, dec czastota LCDOUT $FE,$C0, dec impuls goto generation main4: impuls = impuls + 50 LCDOUT $FE,1 LCDOUT $FE,$80, dec czastota LCDOUT $FE,$C0, dec impuls goto generation end На днях будет добавлена функция выбора выходного напряжения 3В, 6В, 9В, 12В.
|
|
|
|
brown |
Дата: Вт, 01.12.2009, 22:17 | Сообщение # 8 |
Группа:
Пользователи
Ранг:
Помогаю всем
Сообщений:
333
Замечания:
±
На сайте с 18.09.2007
Статус:
Offline
|
Quote (xxxmonejall) Понял GOTO не использовать!!! Зачем же так, без права помилования. По посту выше: заменить на Return, вызываешь же подпрограмму Quote (ADMIN) Да какая разница, сколько goto? Если программа составлена правильно, то нет никаких причин думать на свои корявые руки и В этом случае полностью согласен.
Век живи - век учись! К концу жизни поймешь, что ничего не знаешь...
Сообщение отредактировал
brown - Вт, 01.12.2009, 22:29
|
|
|
|
terrarus |
Дата: Вт, 01.12.2009, 22:47 | Сообщение # 9 |
Группа:
Пользователи
Ранг:
Помогаю всем
Сообщений:
451
Замечания:
±
На сайте с 21.08.2008
Статус:
Offline
|
Нет ребята!!! Прав brown говоря: "Квалификация программиста обратно-пропорциональна количеству операторов GOTO в программе." Программа написанная на любом языке долна быть структурированная, а это значит, в том числе, нужно избегать частого применения оператора GOTO. Иначе это плохой стиль программирования. Все подпрограммы обозначенные метками main1: ..... main4: долны заканчиваться операторами Return, a не Goto. Тут я с автором приведенной программы КАТЕГОРИЧЕСКИ НЕ СОГЛАСЕН!!! Почитайте как следует описание оператора Gosub. Это оператор вызова подпрограммы, а подпрограмма в свою очередь должна содержать оператор Return - "Подпрограмма, на которую ссылается команда GoSub, должна иметь в своем начале адресную метку Label:, и заканчиваться командой Return. Когда в конце подпрограммы встречается команда Return, происходит возвращение к основной программы в место расположенное сразу после команды GoSub в основной программе. ".
Если у в Вас что-то не получается, подумай, не стоит ли прочитать инструкцию...!
Сообщение отредактировал
terrarus - Вт, 01.12.2009, 22:51
|
|
|
|
ivan_fd |
Дата: Вт, 01.12.2009, 23:35 | Сообщение # 10 |
Группа:
Модераторы
Ранг:
Специалист
Сообщений:
894
Замечания:
±
На сайте с 12.01.2009
Статус:
Offline
|
xxxmonejall, Вам правильно говорят Quote main1: ..... main4: долны заканчиваться операторами Return, a не Goto . Вы в Протеусе смотрели на его сообщения, проблемы со Стеком. Команда GoSub вызывает подпрограмму, и записывает в стек адрес следуючий за командой GoSub, а вы командой GoTo переезжаете куда вам надо, вот вам и: Stack overflow executing CALL instruction. Stack underflow executing RETURN instruction.
|
|
|
|
terrarus |
Дата: Ср, 02.12.2009, 10:47 | Сообщение # 11 |
Группа:
Пользователи
Ранг:
Помогаю всем
Сообщений:
451
Замечания:
±
На сайте с 21.08.2008
Статус:
Offline
|
Eще 2 замечания. 1-e. Все подпрограммы лучше располагать после оператора END. Естественно подпрограммы должны заканчиваться оператором Return. 2-е. Если воспользоваться разработанной нашим Админом програмкой ProtonHeadMaker (любой из её версий), то очень легко заставить микроконтроллер выводить на экран сообщения на русском языке. РЕКОМЕНДУЮ!" Кстати, эта функция программы годится не только для Протона но и для той версии языка Basic, на котором вы написали программу. А теперь для админа, в ответ на его замечания по поводу паузы в операторе if portA.0 = 1 then Pause 150: Gosub main1 ;Вот здесь проблемы больше не будет!. Основная задача этой паузы замедлить программу при нажатии пальцем на кнопку. И лучше даже ее увеличить до 250 мсек. Без этой паузы, так как вся программа маленькая, может произойти следующее - пока человек нажмет на кнопку и уберет палец с нее, выполнится не один раз оператор Gosub и соответствующая подпрограмма. Поэтому реплика ";Вот здесь проблемы больше не будет!." относится и к паузе и к оператору Gosub, при условии, что подпрограмма на которую этот оператор адресует заканчивается оператором Return. А паузу в 2 сек из подпрограммы думаю лучше убрать. Хотя можно и так замедлить выполнение подпрограммы, тогда естественно не нужна пауза в операторе IF.
Если у в Вас что-то не получается, подумай, не стоит ли прочитать инструкцию...!
Сообщение отредактировал
terrarus - Ср, 02.12.2009, 11:29
|
|
|
|
ADMIN |
Дата: Ср, 02.12.2009, 11:34 | Сообщение # 12 |
Администратор
Группа:
Администраторы
Ранг:
Специалист
Сообщений:
1086
Замечания:
±
На сайте с 20.08.2007
Статус:
Offline
|
По логике программы, в ПП и так огромная пауза в 2 сек, и я не вижу смысла с этих коротких задержек. Вообще, все это проще сделать через прерывания. Вот пример: Это обеспечит, при корректировке программы обязательный переход. Это один из вариантов.
|
|
|
|
terrarus |
Дата: Ср, 02.12.2009, 14:05 | Сообщение # 13 |
Группа:
Пользователи
Ранг:
Помогаю всем
Сообщений:
451
Замечания:
±
На сайте с 21.08.2008
Статус:
Offline
|
ADMIN, Естественно если оставить паузы по 2 сек в ПП то не нужны маленькие паузы в операторе IF. Такая конструкция IF мне просто привычнее, я так делал и мне казалось раньше, что это хорошо (ну точно по пословице - "каждый гад, на свой лад"). Вы заставили меня задуматься, действительно ли это хорошо. Пока в раздумьях... Насчет приведенной схемы - Я не понимаю, как это должно работать, просветите, пожалуйста, поподробнее. Наверное это будет интересно не только мне.
Если у в Вас что-то не получается, подумай, не стоит ли прочитать инструкцию...!
Сообщение отредактировал
terrarus - Ср, 02.12.2009, 14:13
|
|
|
|
slavauk |
Дата: Ср, 02.12.2009, 22:24 | Сообщение # 14 |
Группа:
Проверенные
Ранг:
Понимаю
Сообщений:
64
Замечания:
±
На сайте с 14.03.2009
Статус:
Offline
|
А мне вообще не понятно зачем здесь столько переходов или вызовов процедур. DEFINE OSC 4 DEFINE LCD_DREG PORTB DEFINE LCD_DBIT 4 DEFINE LCD_RSREG PORTB DEFINE LCD_RSBIT 1 DEFINE LCD_EREG PORTB DEFINE LCD_EBIT 0 DEFINE LCD_BITS 4 DEFINE LCD_LINES 2 DEFINE LCD_COMMANDUS 2000 DEFINE LCD_DATAUS 50 TrisA = %11111111 czastota var byte impuls var word czastota = 10 impuls = 1500 LCDOUT $FE,$80,"Injector" LCDOUT $FE,$C0,"Diagnostic v.1,0" pause 2000 LCDOUT $FE,1 LCDOUT $FE,$80,"created by " LCDOUT $FE,$C0,"K2mozga.net" pause 2000 LCDOUT $FE,1 LCDOUT $FE,$80, dec czastota LCDOUT $FE,$C0, dec impuls Generation: if portA.0 = 1 then Pause 400 czastota = czastota + 5 endif if portA.1 = 1 then Pause 400 impuls=impuls - 50 endif if portA.2 = 1 then Pause 400 czastota=czastota - 5 endif if portA.3 = 1 then Pause 400 impuls = impuls + 50 endif pulsout portb.2,impuls pause czastota LCDOUT $FE,1 LCDOUT $FE,$80, dec czastota LCDOUT $FE,$C0, dec impuls goto generation end Добавлено (02.12.2009, 22.24.39) --------------------------------------------- Quote (terrarus) Насчет приведенной схемы - Я не понимаю, как это должно работать На диодах собрана схема логического "и". Нажатие любой кнопки приведет к вызову прерывания. В обработчике прерывания проверяется состояние портов (в этой схеме porta.0 и porta.1) и т.д. Только у диодов кажется катод анод поменять местами нужно.
Сообщение отредактировал
slavauk - Ср, 02.12.2009, 22:54
|
|
|
|
brown |
Дата: Ср, 02.12.2009, 23:04 | Сообщение # 15 |
Группа:
Пользователи
Ранг:
Помогаю всем
Сообщений:
333
Замечания:
±
На сайте с 18.09.2007
Статус:
Offline
|
На счет схемы ADMINа: сначала бегло глянул и программый замысел понял сразу. Но! почитав сообщения terrarus и slavauk, решил привести некоторые пояснения и изменения. 1. Вывод INT-portB.0 настроен на прерывание по переходу с 1 в 0. Также необходимо либо включить внутренние резисторы подтяжки, либо подцепить внешний. 2. Сменить полярность диодов и убрать резисторы. Пока писал сообщение slavauk правильно заметил Quote Только у диодов кажется катод анод поменять местами нужно.
Век живи - век учись! К концу жизни поймешь, что ничего не знаешь...
Сообщение отредактировал
brown - Ср, 02.12.2009, 23:08
|
|
|
|