О великие ГУРУ! Помогите пожалуйста начинающему. Задача: Нажатием на микрик изменять последовательность включения светодиодов (с лева на право и на оборот). ТЗ: На PIC16F877A, где PORTA.0 - кнопка и PORTB - светодиоды (8-шт).
Код:
ADCON1 = %00000111 ' Установим все выводы PORTA как цифровые. TRISB = %00000000 PORTB = %00000000 symbol LEDS = PORTB 'Все светодиоды I var byte B0 VAR BYTE B0 = 0
main: BUTTON PORTA.0,0,255,255,B0,1,Right GOTO Left
Right: PORTA.0 = 0 LEDS = 1 pause 500 for I = 0 to 6 LEDS = LEDS << 1 pause 500 next goto main
Left: PORTA.0 = 1 LEDS = 255 pause 500 for I = 0 to 6 LEDS = LEDS >> 1 pause 500 next goto main
При компиляции и проверке зажигание светодиодов происходит только в одну сторону.
Давай сформулируем задачу поточнее? Проверка кнопки у тебя происходит один раз в секунду. То есть микрик теряет функцию моментального переключения с одного направления, на другое. Потом, как светодиоды должны бегать? Все сразу? или по одному? Во-вторых, зачем нужна команда button? Думаю, устранение дребезга здесь ни к чему. Потом, зачем строчки PORTA.0 = 0 и PORTA.0 = 1? Ни к чему. Потом, зачем паузы перед циклами For...Next? Ответь на вопросы и сформулируй задачу. Потом продолжим
Доброе время суток! Я хочу чтобы светодиоды включались в цикле по одному через пол секунды, то есть зажегся первый потом через 0,5 сек зажжется второй .... и когда зажжется 8 то все потухли и так по циклу. Потом если нажать на микрик то светодиоды должны загораться в обратном порядке, то есть 8 потом 7 .... и до первого. В общем микрик должен определять направление включения светодиодов.
А по поводу: PORTA.0 = 0 и PORTA.0 = 1 таки да полная ерунда.
А, что если так? Пример приметивный, но понять я думаю можно.
ADCON1 = %00000111 ' Установим все выводы PORTA как цифровые. TRISB = %00000000 PORTB = %00000000 Symbol LED=PORTB ' обозвать порт LED b var byte b=0 i var byte portb=0 ' УСТАНОВКА ПОРТА В в логический 0. (если portb=255, то установить все в логическую 1, т.к 255=%11111111, а 0=%00000000) pravo: FOR I = 0 TO 8 if i=0 then LED=%00000001 if i=1 then LED=%00000010 if i=2 then LED=%00000100 if i=3 then LED=%00001000 if i=4 then LED=%00010000 if i=5 then LED=%00100000 if i=6 then LED=%01000000 if i=7 then LED=%10000000 if i=8 then LED=%00000000 Button porta.0,0,255,255,b,1,levo ' смена направления pause 500 next goto pravo
levo: FOR I = 0 TO 8 if i=0 then LED=%10000000 if i=1 then LED=%01000000 if i=2 then LED=%00100000 if i=3 then LED=%00010000 if i=4 then LED=%00001000 if i=5 then LED=%00000100 if i=6 then LED=%00000010 if i=7 then LED=%00000001 if i=8 then LED=%00000000 Button porta.0,0,255,255,b,1,pravo ' смена направления pause 500 next goto levo
Сообщение отредактировал
MiXaS - Пн, 07.02.2011, 08:10
Потому что когда ты нажимаешь на кнопку, иногда программа не обрабатывает оператор button, а находится в паузе, например. Для этих целей лучше использовать прерывание. Можно по таймеру опрашивать кнопку, можно саму кнопку повесить на вход INT.
IF btTest = 1 THEN LEDS = LEDS << 1 IF LEDS = 0 THEN LEDS = 1 ELSE LEDS = LEDS >> 1 IF LEDS = 0 THEN LEDS = 128 ENDIF FOR i = 0 TO 50 pause 10 IF Button_ = 0 THEN btTest = ~btTest ENDIF while button_ = 0 ' Это чтобы за одну проверку бит btTest не менялся несколько раз, а срабатывал только после отпускания кнопки wend NEXT GOTO main
Так 100 % работает. Просто не надо делать большие паузы, а организовывать их циклом, в который можно воткнуть проверку условия(в данном случае, нажатие кнопки
Спасибо MiXaS. Прошил микросхемку, запустил на плате и запускается блок pravo: но при нажатии на Button porta.0,0,255,255,b,1,levo ' смена направления не всегда срабатывает смена направления.
Соглашусь с ADMINом! Это вызвано большой паузой=500 милисекунд. Если подольше держать нажатой кнопку, то может работать стабильнее. Самый правильный вариан, использовать прерывание. http://picbasic.ru/forum/5-568-1. Здесь пример обрабатывания энкодера,но и для кнопки можно приспособить. Еще в книге Хилинского есть описание команды On Interrupt.