Неправильно Работает Программа

11-11-2012, 10:03 От: admin Посмотрели: 933
Пробую обрабатывать на контроллере прирывания по таймеру и по порту B (interrupt on change). Суть проблемы в том, что почему-то нажатие на одной из кнопки обрабатывается не корректно. При генерации прерывания на порту RB5 должен меняться уровень порта RA1, но вместе с этим два раза меняется уровень порта RA0, хотя не должен. Код программы ниже. Скриншот схемы в приложении. Сам проект в MPLAB X и ISIS в архиве в приложении, в нем же видео демонстрирующее проблему.



Суть программы в том, что таймер настроен на 1мс (1024мкс) и прерывание обработки таймера дикриментирует переменную COUNTER и если она равна 0, меняет уровень светодиода на порту RA3, таким образом он моргает примерно раз в четверть секунды. Уровни светодиодов RA0 и RA1 меняются только по нажатию на кнопки.




list p=16f84a
#include "P16F84A.INC"
__config _CP_OFF & _PWRTE_OFF & _WDT_OFF & _HS_OSC

_work equ h'4E'
_status equ h'4F'
COUNTER equ h'0C' ; Счетчик

; Вектор сброса контроллера ----------------------------------------------------
org 000 ; При старте контроллера (адрес программы 000)
goto MAIN ; перейти к метке MAIN

; Вектор прерывания ------------------------------------------------------------
org 004 ; При возникновении прерывания (переход к адресу 004)
goto IRQ_PROCESS ; перейти к метке IRQ_PROCESS

; Фоновая программа начинается с инициализации ---------------------------------
MAIN
bsf INTCON, GIE ; Разрешаем прерывания
bsf INTCON, RBIE ; Разрешаем прерывания на портах RB7:RB4

bsf STATUS, RP0 ; Выбираем первый банк памяти

bcf OPTION_REG, T0CS ; Включаем timer0 в режим таймера, а не счетчика
bcf OPTION_REG, PSA ; Связываем предделитель с таймером
bcf OPTION_REG, PS2 ; Конфигурируем предделитель в соответствии
bcf OPTION_REG, PS1 ; с даташитом в 1:4
bsf OPTION_REG, PS0 ; (Биты PS2:PS0 установлены в 001)
movlw b'00000000' ; Конфигурируем все пины порта А
movwf TRISA ; как выходы
movlw b'00110000' ; Порты RB5:RB4 как входы
movwf TRISB

bcf STATUS, RP0 ; Возвращаемся к нулевому банку памяти

bsf INTCON, T0IE ; Включаем прерывание по таймеру

movlw b'00000' ; Выставляем низкий уровень на всех
movwf PORTA ; пинах порта А

; Бесконечный пустой цикл
M_LOOP
nop ; Ничего не делаем
goto M_LOOP

IRQ_PROCESS
; Сохраняем контекст
movwf _work ; Сохраняем рабочий регистр в памяти данных
swapf STATUS, w ; Считываем регистр STATUS в рабочий регистр не меняя флагов
movwf _status ; И сохраняем его из рабочего регистра в память данных

btfsc INTCON, T0IF ; Если прерывание по таймеру
call IRQ_TMR0 ; вызываем обработчик таймера

btfsc INTCON, RBIF ; Если прерывание по порту B
call IRQ_RB ; вызываем обработчик порта B

; Чтобы сбросить бит RBIF обязательно надо вначале прочитать порт B
; Сбрасывать прерывание на порту B надо всегда, оно постоянно почему-то срабатывает
movf PORTB, w ; Сбрасываем флаг внешнего прерывания, чтобы
bcf INTCON, RBIF ; не получился бесконечный цикл

; Восстанавливаем контекст
swapf _status, w ; Сначала восстанавливаем
movwf STATUS ; регистр STATUS
swapf _work, f ; Затем рабочий регистр
swapf _work, w ; не воздействуя на флаги регистра STATUS

retfie ; И возврат из прерывания в программу

IRQ_TMR0
decf COUNTER

btfsc STATUS, Z
call COUNT_OVER

bcf INTCON, T0IF

return

COUNT_OVER
movf PORTA, w ; Считываем порт А в рабочий регистр
xorlw b'01000' ; и по маске изменяем нужный пин
movwf PORTA ; Записываем изменения в порт А

movlw h'FF' ; Инициализируем счетчик
movwf COUNTER

return

IRQ_RB
; В зависимости от порта, на котором возникло прерывания, вызываем
; соответствующую подпрограмму (проверяем по низкому уровню, т.е. нажатие кнопки)
btfss PORTB, RB4
call IRQ_RB4
btfss PORTB, RB5
call IRQ_RB5

IRQ_RB4
movf PORTA, w ; Считываем порт А в рабочий регистр
xorlw b'00001' ; и по маске изменяем нужный пин
movwf PORTA ; Записываем изменения в порт А

return

IRQ_RB5
movf PORTA, w
xorlw b'00010'
movwf PORTA

return

end


Прикрепленные миниатюры





  • Screenshot - 10.11.png





Прикрепленные файлы:





  • Прикрепленный файл
     pic.rar   536,92 Кб
      7 раз скачано




Раздел: МК для начинающих

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться, либо войти на сайт под своим именем.

Обсудить на форуме


На момент добавления Неправильно Работает Программа все ссылки были рабочие.
Все публикации статей, книг и журналов, представлены на этом сайте, исключительно для ознакомления,
авторские права на эти публикации принадлежат авторам статей, книг и издательствам журналов!
Подробно тут | Жалоба
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.


Опрос

Ваши предпочтения в TRX


Одинарное преобразование
Двойное преобразование
Прямое преобразование
SDR
Другое
Мне всё равно

Популярные новости
Календарь новостей
«    Апрель 2024    »
ПнВтСрЧтПтСбВс
1234567
891011121314
15161718192021
22232425262728
2930