Проблема с опросом порта... - Форум Picbasic.ru
Регистрация | Вход
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Страница 1 из 212»
Модератор форума: ivan_fd 
Форум Picbasic.ru » Программирование МК » PicBasicPro » Проблема с опросом порта...
Проблема с опросом порта...
xxxmonejall Дата: Вт, 01.12.2009, 00:07  |                                                                                                                Сообщение # 1
Группа: Проверенные
Ранг:  Продвинутый
Сообщений: 139
Репутация: 0   ±
Замечания:   ±
На сайте с 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

ЯНДЕКС Дата: 01.12.2009
ADMIN Дата: Вт, 01.12.2009, 03:44  |                                                                                                                Сообщение # 2
Администратор
Группа: Администраторы
Ранг:  Специалист
Сообщений: 1107
Репутация: 24   ±
Замечания:   ±
На сайте с 20.08.2007

Статус: Offline

В протеусе несколько раз? То есть несколько раз уходит на Main1, ждет 2 секунды и т.д.?
terrarus Дата: Вт, 01.12.2009, 13:27  |                                                                                                                Сообщение # 3
Группа: Модераторы
Ранг:  Разобрался
Сообщений: 542
Репутация: 16   ±
Замечания:   ±
На сайте с 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
Группа: Модераторы
Ранг:  Помогаю всем
Сообщений: 335
Репутация: 10   ±
Замечания:   ±
На сайте с 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
Репутация: 0   ±
Замечания:   ±
На сайте с 17.05.2008

Статус: Offline

Понял GOTO не использовать!!!
ADMIN Дата: Вт, 01.12.2009, 19:16  |                                                                                                                Сообщение # 6
Администратор
Группа: Администраторы
Ранг:  Специалист
Сообщений: 1107
Репутация: 24   ±
Замечания:   ±
На сайте с 20.08.2007

Статус: Offline

Для xxxmonejall
Вы хотите решить проблему?
Програма составлена грамотно. Не знаю, что она должна решать, но то, что написано, не должно вызывать таких проблем, поэтому я спросил про протеус.
Для terrarus:
Пауза 150 мс ничего не решает, поскольку программа, обнаружив единицу на porta.0 или porta.1, всегда выполняет одно и то же действие? а именно - переход на ПП, в которой заложена уже задержка на 2000 мс. Дребезг контактов не играет здесь никакой роли. Я поясню, если не понятно: если кнопка предназначена для выполнения только лишь одной функции(а здесь так и есть - переход на ПП), то дребезг не играет никакой роли(если только, естественно, частота дребезга больше частоты следования команд, в чем я сомневаюсь), так как программа в любом случае перейдет на ПП. Дребезг может вносить непредвиденные изменения в случае, когда кнопка отвечает за изменение параметра при КАЖДОМ нажатии, и то, такое может случиться в случае прерывания по INT, например.
Для Brown:
Да какая разница, сколько goto? Если программа составлена правильно, то нет никаких причин думать на свои корявые руки и еще что-то? Может, иногда не стоит полностью доверяться протеусу?
Может, кто-то заметил что то, чего я не увидел?
Порекомендую написать в конце программы слово End.
xxxmonejall Дата: Вт, 01.12.2009, 21:17  |                                                                                                                Сообщение # 7
Группа: Проверенные
Ранг:  Продвинутый
Сообщений: 139
Репутация: 0   ±
Замечания:   ±
На сайте с 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В.

Прикрепления: 8427262.dsn(76Kb) · 6957247.hex(3Kb)
brown Дата: Вт, 01.12.2009, 22:17  |                                                                                                                Сообщение # 8
Группа: Модераторы
Ранг:  Помогаю всем
Сообщений: 335
Репутация: 10   ±
Замечания:   ±
На сайте с 18.09.2007

Статус: Offline

Quote (xxxmonejall)
Понял GOTO не использовать!!!

Зачем же так, без права помилования.

По посту выше:

Quote
goto generation
заменить на Return, вызываешь же подпрограмму
Quote
Gosub mainХ

Quote (ADMIN)
Да какая разница, сколько goto? Если программа составлена правильно, то нет никаких причин думать на свои корявые руки и

В этом случае полностью согласен.


Век живи - век учись! К концу жизни поймешь, что ничего не знаешь...
Сообщение отредактировал brown - Вт, 01.12.2009, 22:29
terrarus Дата: Вт, 01.12.2009, 22:47  |                                                                                                                Сообщение # 9
Группа: Модераторы
Ранг:  Разобрался
Сообщений: 542
Репутация: 16   ±
Замечания:   ±
На сайте с 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
Группа: Модераторы
Ранг:  Специалист
Сообщений: 888
Репутация: 47   ±
Замечания:   ±
На сайте с 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
Группа: Модераторы
Ранг:  Разобрался
Сообщений: 542
Репутация: 16   ±
Замечания:   ±
На сайте с 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
Администратор
Группа: Администраторы
Ранг:  Специалист
Сообщений: 1107
Репутация: 24   ±
Замечания:   ±
На сайте с 20.08.2007

Статус: Offline

По логике программы, в ПП и так огромная пауза в 2 сек, и я не вижу смысла с этих коротких задержек. Вообще, все это проще сделать через прерывания. Вот пример:


Это обеспечит, при корректировке программы обязательный переход.
Это один из вариантов.

Прикрепления: 5084062.png(4Kb)
terrarus Дата: Ср, 02.12.2009, 14:05  |                                                                                                                Сообщение # 13
Группа: Модераторы
Ранг:  Разобрался
Сообщений: 542
Репутация: 16   ±
Замечания:   ±
На сайте с 21.08.2008

Статус: Offline

ADMIN, Естественно если оставить паузы по 2 сек в ПП то не нужны маленькие паузы в операторе IF.
Такая конструкция IF мне просто привычнее, я так делал и мне казалось раньше, что это хорошо (ну точно по пословице - "каждый гад, на свой лад"). Вы заставили меня задуматься, действительно ли это хорошо. Пока в раздумьях...
Насчет приведенной схемы - Я не понимаю, как это должно работать, просветите, пожалуйста, поподробнее. Наверное это будет интересно не только мне.


Если у в Вас что-то не получается, подумай, не стоит ли прочитать инструкцию...!
Сообщение отредактировал terrarus - Ср, 02.12.2009, 14:13
slavauk Дата: Ср, 02.12.2009, 22:24  |                                                                                                                Сообщение # 14
Группа: Проверенные
Ранг:  Понимаю
Сообщений: 68
Репутация: 3   ±
Замечания:   ±
На сайте с 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
Группа: Модераторы
Ранг:  Помогаю всем
Сообщений: 335
Репутация: 10   ±
Замечания:   ±
На сайте с 18.09.2007

Статус: Offline

На счет схемы ADMINа: сначала бегло глянул и программый замысел понял сразу. Но! почитав сообщения terrarus и slavauk, решил привести некоторые пояснения и изменения.
1. Вывод INT-portB.0 настроен на прерывание по переходу с 1 в 0. Также необходимо либо включить внутренние резисторы подтяжки, либо подцепить внешний.
2. Сменить полярность диодов и убрать резисторы.
Пока писал сообщение slavauk правильно заметил
Quote
Только у диодов кажется катод анод поменять местами нужно.


Век живи - век учись! К концу жизни поймешь, что ничего не знаешь...
Сообщение отредактировал brown - Ср, 02.12.2009, 23:08
Форум Picbasic.ru » Программирование МК » PicBasicPro » Проблема с опросом порта...
Страница 1 из 212»
Поиск: