Перейти к содержанию

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


Рекомендуемые сообщения

Пробую обрабатывать на контроллере прирывания по таймеру и по порту 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

pic.rar

post-156072-0-72448900-1352574564_thumb.png

Изменено пользователем metallic
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Вот блин :vava:

Столько времени убить из-за невнимательности :))

П.С. на соседнем форуме мне тут говорят, что не стоит использовать подпрограммы в прерываниях (именно в пиках), а лучше использовать метки и goto, это правда? И с чем это связано?

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Правда. Связанно с ограниченным уровнем стека.

Ну это понятно. У 8-ми битных 8-ми уровневый стек, если не ошибаюсь. Но если учитывать этот момент, больше никаких подводных камней?

Ссылка на комментарий
Поделиться на другие сайты

Ну вот Вы учитывали, да не учли - запнулись о камень :)

Внутри обработчика нет смысла в подобных вызовах, всё можно сделать через goto. Тем более, в Вашем случае :)

Ссылка на комментарий
Поделиться на другие сайты

Вот блин :vava:

Столько времени убить из-за невнимательности :))

это системная ошибка

примите за правило писать сразу начало и конец(возврат) процедуры и только потом тело процедуры

name_proc_1
................
...............
name_proc_1_end    return

это касается и меток к goto

ну и маленькие замечания: дабы компилятор не выдавал кучу 302-х предупреждений

после объявления инклюда добавляем отключение:

list	  p=16f628A		 
#include <p16F628A.inc>   
errorlevel  -302			  ; suppress message 302 from list file

а вот 305 это уже можно считать ошибкой - забыли указать куда записывать результат декремента....

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

    • @korsaj Так сейчас вчитывался ещё раз и ничего как то на ум так и не идёт. Сложновато получается. Данную функцию да тем более с массивами на сравнение я точно не осилю.
    • Собрал тиристорное зарядное. И не совсем понятно как измерять его ток заряда. Вот так показывают два неплохих мультиметра на измерении постоянного тока  (уверен что стрелочный покажет то же самое )   но , Мы же понимаем , что после тиристора идёт не постоянный ток , а импульсный  и вот такое теперь показывают мультиметры в режиме измерения переменного тока  один РМС, другой не рмс.   Что считать правдой ?
    • А чего бы не поставить рядом с DS18B20 некрупный конденсатор между VDD и GND? 
    • Я вскрываю металлической линейкой. Очень часто у таких блоков есть паз вдоль шва, туда вставляю линейку по всей длине шва и как рычагом вскрываю корпус. Если вначале немного промять корпус вдоль шва (бывает достаточно пальцами), то шансы легко вскрыть значительно увеличиваются.
    • При включении в ранее опубликованном виде устройство стало генератором. Частота до 140кГц, на индуктивности размах (от мин. до макс.) до 20В при напряжении на испытуемом БП ~3В. Добавил несколько конденсаторов, в том числе как рекомендовали Z_VIP и Starichok. Немного изменил номиналы резистора в компараторе. Удалил шунтирующее сопротивление на резисторе регулятора тока. Компаратор буду еще отлаживать - в приведённой ниже схеме срабатывает при 4В, но не не отпускает при отсутствии напряжения.  Ограничение тока выставил на 4А. Регулировка тока плавная от 0 до  4А. Выставленный ток стабильный при изменении напряжения от 1В до 10В. Напряжение выше 10В пока не поднимал. Ниже 0,95В ток снижается пропорционально напряжению. Схема в приложении. Все изменения-дополнения делал на существующей плате навесным монтажом. Позже выложу актуальную разводку. Отлаживал с транзисторами AP60T30 (ранее выкладывал фото транзисторов на радиаторе) - без обдува при комнатной температуре длительно держат 20Вт (10В, 2А) при температуре радиатора ~40гр.C. Приобрёл транзисторы IRFP460. С радиатором пока не определился. Схема и фото отладки на текущий момент времени. На фото стрелочный прибор - амперметр с током полного отклонения 6А. и в DipTrace:  
    • Ведь этож надо... такое совпадение. И я тоже делаю без сверлений. Более того, прилагаю фото имеющихся у меня  "хоть чуток острых предметов", несмотря на наличие которых, столь несложный и общедоступный  способ зачистки, к.м.к.  имеет право на демонстрацию в данной теме. Вдруг кому-то пригодится... Тем более, что тема простаивает аж с марта, будто на белом свете нет ничего, что можно было бы сюда  разместить,  хотя бы для сведения. 
×
×
  • Создать...