Страница 1 из 1
Проблемы с прерыванием по таймеру 16F84A
Добавлено: Вс окт 13, 2013 08:31:52
CaseBot
Доброго времени суток, товарищи.. Решил сегодня продолжить изучение микроконтроллеров и надумал обучиться работе с таймером и прерыванием на простейшем контроллере..
Весь день мучался: написал простенький код в 20 машинных слов для мигания светодиодом с различимым интервалом, однако, результат совершенно не тот который я задумывал: светодиод мигает (как бы странно это ни выглядело) со случайным интервалом..
Помогите разобраться: что я делаю не так и действительно ли я написал генератор псевдослучайных чисел?
Код:
Код: Выделить всё
LIST P=PIC16F84A
__config 0x3FF1
STATUS EQU .0003
INTCON EQU .0011
OPTION_REG EQU .0001
TMR0 EQU .0001
RP0 EQU .0005
w EQU .0000
f EQU .0001
PORTB EQU .0006
TRISB EQU .0006
Rsec EQU .0015
org 0
goto START
org 04h
goto main
START
bsf STATUS,RP0 ;BANK1
movlw b'00000111'
movwf OPTION_REG
clrf TRISB
bcf STATUS,RP0 ;BANK0
movlw b'10100000'
movwf INTCON
clrf Rsec
loop
goto loop
;--------------------------------------------------
main
incf Rsec, f
btfsc Rsec, 7
retfie
clrf Rsec
comf PORTB, f
retfie
end
писал в MPLAB
прошивал в PicKit2
кварц на 4 мГц
Re: Проблемы с прерыванием по таймеру 16F84A
Добавлено: Вс окт 13, 2013 09:11:48
dosikus
Здесь хорошие уроки
http://www.gooligum.com.au/tut_midrange.html
Конкретно по прерываниям
http://www.gooligum.com.au/tutorials/mi ... id_A_6.pdf
И эта замечательная книга
http://rghost.ru/49342639
К Вам вопрос - что и кто Вам насоветовал 84?
Выбор ИМХО совершенно не понятен .
Re: Проблемы с прерыванием по таймеру 16F84A
Добавлено: Вс окт 13, 2013 09:21:15
CaseBot
пару месяцев назад нашел схемку программатора на 3-х резисторах, который прошивает 84-й, поэтому и приобрел его..
сейчас, конечно, есть уже и 628-й и 887-й, однако, в них много регистров, которые пока не совсем ясны, вот и балуюсь пока на 16F84А..
Re: Проблемы с прерыванием по таймеру 16F84A
Добавлено: Вс окт 13, 2013 09:56:19
dosikus
CaseBot писал(а): однако, в них много регистров, которые пока не совсем ясны, вот и балуюсь пока на 16F84А..
Что мешает изучать периферию постепенно , практически вся она отключена изначально . Единственно порты при старте могут находится в аналоговом режиме.
Re: Проблемы с прерыванием по таймеру 16F84A
Добавлено: Вс окт 13, 2013 10:13:33
CaseBot
Но ведь если в данном контроллере есть таймер и прерывание, то они должны работать..
И должна быть причина такому поведению..
Re: Проблемы с прерыванием по таймеру 16F84A
Добавлено: Вс окт 13, 2013 10:45:14
uldemir
Инициализацию не смотрел, а в прерывании написана какая-то глупость.
CaseBot писал(а):Код: Выделить всё
main
incf Rsec, f
btfsc Rsec, 7
retfie
clrf Rsec
comf PORTB, f
retfie
Получается так, что вы инкрементируете Rsec и когда оно досчитает до 128 должно что-то выполняться. Однако получается наоборот. На каждом шаге вы уходите на clrf Rsec и дальше совсем непонятная конструкция - зачем вам комплиментарное от портаБ? Это раз.
Второе, обрабатывая прерывание вам надо снимать флаг запроса прерывания. Т.е. если прерывание вызвалось по флагу от T0IF - его надо снять внутри прерывания, иначе выйдя из прерывания прерывание снова произойдет сразу!
Ну и научитесь еще и сохранять контекст. В данном примере это не актуально, но в будущем оно будет нужно.
p.s. И еще, бросайте эту дурную затею с толпой EQU... напишите просто include "p16f84.inc" и пользуйтесь на здоровье.
Re: Проблемы с прерыванием по таймеру 16F84A
Добавлено: Вс окт 13, 2013 12:10:22
CaseBot
uldemir писал(а):Получается так, что вы инкрементируете Rsec и когда оно досчитает до 128 должно что-то выполняться. Однако получается наоборот. На каждом шаге вы уходите на clrf Rsec
ну с этим я разобрался, просто когда готовил код (обрезал лишнее) поспешил и перепутал, но суть не в этом, до этого совершенно иными способами прореживался интервал..
uldemir писал(а):и дальше совсем непонятная конструкция - зачем вам комплиментарное от портаБ? Это раз.
комплементарное? впервые слышу.. здесь
http://www.microchip.ru/?mid=3&cid=46 написано иначе
а на этой страничке
http://labkit.ru/html/Assembler_for_PIC?id=334 учат использовать команду "сравнения" XORWF, из за которой я не так давно пол дня убил на поиск ошибки..
uldemir писал(а):Второе, обрабатывая прерывание вам надо снимать флаг запроса прерывания. Т.е. если прерывание вызвалось по флагу от T0IF - его надо снять внутри прерывания, иначе выйдя из прерывания прерывание снова произойдет сразу!
да, Вы правы.. я думал его необходимо снимать только для идентификации источника прерывания (чтобы узнать что вызвало прерывание)
uldemir писал(а):Ну и научитесь еще и сохранять контекст. В данном примере это не актуально, но в будущем оно будет нужно.
а вот здесь не совсем понятно что Вы имели ввиду
Благодарю за оперативную помощь..
Re: Проблемы с прерыванием по таймеру 16F84A
Добавлено: Вс окт 13, 2013 12:28:27
otest
Посмотри пример от производителя и не иди по пути горе учителей из инета.
c:\Program Files\Microchip\MPASM Suite\Template\Code\PIC16F84
Re: Проблемы с прерыванием по таймеру 16F84A
Добавлено: Вс окт 13, 2013 12:29:29
uldemir
Претензия за "комплиментарное" снимается. Действительно, микрочип просто инвертирует все биты (а не инвертирует и прибавляет 1).
Сохранение контекста:
Код: Выделить всё
EXAMPLE 8-1: SAVING STATUS AND W REGISTERS IN RAM
PUSH MOVWF W_TEMP ; Copy W to TEMP register,
SWAPF STATUS, W ; Swap status to be saved into W
MOVWF STATUS_TEMP ; Save status to STATUS_TEMP register
ISR : :
: ; Interrupt Service Routine
: ; should configure Bank as required
: ;
POP SWAPF STATUS_TEMP, W ; Swap nibbles in STATUS_TEMP register
; and place result into W
MOVWF STATUS ; Move W into STATUS register
; (sets bank to original state)
SWAPF W_TEMP, F ; Swap nibbles in W_TEMP and place result in W_TEMP
SWAPF W_TEMP, W ; Swap nibbles in W_TEMP and place result into W
Эта конструкция сделает так, что при вызове прерывания можно установить любую страницу памяти, изменить значение аккумулятора, а по возвращении они восстановятся в то состояние которое было перед вызовом. Чтобы основная программа не потеряла бы данные. Это важно, если основное тело хоть чуть сложнее чем loop: goto loop.
Еще один момент.
Инициализировать Rsec следует
до разрешения прерываний. иначе может быть ситуация, что прерывание уже ждёт и при разрешении сразу же вызывется. А значение переменной, которое используется в прерывании не определено. В результате возможны трудноуловимые глюки, с которыми трудно бороться.
Re: Проблемы с прерыванием по таймеру 16F84A
Добавлено: Вс окт 13, 2013 12:57:35
CaseBot
uldemir писал(а):Эта конструкция сделает так, что при вызове прерывания можно установить любую страницу памяти, изменить значение аккумулятора, а по возвращении они восстановятся в то состояние которое было перед вызовом. Чтобы основная программа не потеряла бы данные. Это важно, если основное тело хоть чуть сложнее чем loop: goto loop.
Да, про это я знаю.. Опустил для упрощения кода..
uldemir писал(а):Инициализировать Rsec следует до разрешения прерываний. иначе может быть ситуация, что прерывание уже ждёт и при разрешении сразу же вызывется. А значение переменной, которое используется в прерывании не определено. В результате возможны трудноуловимые глюки, с которыми трудно бороться.
Про это я не подумал, буду знать..
Еще раз спасибо..
Re: Проблемы с прерыванием по таймеру 16F84A
Добавлено: Пн окт 14, 2013 08:57:26
urry
Re: Проблемы с прерыванием по таймеру 16F84A
Добавлено: Пт ноя 29, 2013 19:23:58
CaseBot
urry писал(а):http://www.pic24.ru/doku.php/osa/articles/mpasm_formatting
Благодарю, то что надо для начинающего программиста
Нарушение пункта 2.7 Правил форума