Отговори на тема  [ 6 мнения ] 
Прекъсване от RB0 на 16F873А 
Автор Съобщение
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Пет Фев 13, 2009 10:27 pm
Мнения: 2
Местоположение: Бургас
Мнение Прекъсване от RB0 на 16F873А
Здравейте,

Нов съм във форума.
Правя и първи стъпки в програмирането.

Та проблема ми е следния:
Ползвам прекъсване от RB0. Поставил съм бутон. Първото прекъсване работи. Второ няма.
Преди излизане от програмата за обслужване на прекъсването нулирам INTCON,1.

Необходимо ли е да се прави още нещо?


Пет Фев 13, 2009 10:38 pm
Профил
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Вто Яну 31, 2006 11:11 pm
Мнения: 295
Местоположение: София
Мнение 
така едва ли някой ще помогне. Дай малко код да видиме, какво става в прекъсването


Пет Фев 13, 2009 11:01 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Пет Фев 13, 2009 10:27 pm
Мнения: 2
Местоположение: Бургас
Мнение 
Подпрограмата за обслужване на прекъсването:

org 0x04
INTR
movwf W_Temp ; Save W register
swapf STATUS,W ; Swap status to be saved into W
movwf STATUS_Temp ; Save STATUS register
movfw PCLATH
movwf PCLATH_Temp ; Save PCLATH

goto interupt

banksel INTCON
bcf INTCON,1 ; INTCON,INTF


INTX
movfw PCLATH_Temp
movwf PCLATH ; Restore PCLATH
swapf STATUS_Temp,W
movwf STATUS ; Restore STATUS register - restores bank
swapf W_Temp,F
swapf W_Temp,W ; Restore W register
retfie

И инициализациите на двата регистъра:

banksel INTCON
movlw B'11010000'
movwf INTCON
nop

banksel OPTION_REG
movlw B'10000000'
movwf OPTION_REG


Пет Фев 13, 2009 11:08 pm
Профил
Ранг: Минаващ
Ранг: Минаващ
Аватар

Регистриран на: Нед Авг 17, 2008 10:16 am
Мнения: 58
Местоположение: София
Мнение 
Струва ми се, че не смъкваш флага за прекъсването.

_________________
RadtoDecart (HowRot/2,HowOpen/7.5, &TheZone.Dots[TheZone.CurrentDot].X, &TheZone.Dots[TheZone.CurrentDot++].Y);


Съб Фев 14, 2009 12:41 am
Профил ICQ WWW
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Вто Яну 31, 2006 11:11 pm
Мнения: 295
Местоположение: София
Мнение 
Прексъсването не е наред с тези пипания по PCLATH

Това е достатъчно
Код:
                movwf   w_temp            ; save off current W register contents
      swapf   STATUS,w
                movwf   status_temp       ; save off contents of STATUS register
;--------------------------------------------------------------
      bcf   INTCON,RBIF   ; clear interrupt flag
      
              тук пишеш кода за прекъсването


;--------------------------------------------------------------
                swapf    status_temp,w     ; retrieve copy of STATUS register
                movwf   STATUS            ; restore pre-isr STATUS register contents
                swapf   w_temp,f
                swapf   w_temp,w          ; restore pre-isr W register contents
                retfie                    ; return from interrupt


Ама защо не ползваш някое C вместо assempler


Съб Фев 14, 2009 10:34 pm
Профил
Ранг: Минаващ
Ранг: Минаващ
Аватар

Регистриран на: Пет Апр 18, 2008 8:22 pm
Мнения: 42
Мнение 
16F873А има една неприятна особеност, мястото на записа на W, STATUS и PCLATH регистрите при входа в обработването на прекъсването зависи от състоянието на бита RP0 в самия STATUS регистър. Тоест, ако W_Temp, STATUS_Temp и PCLATH_Temp са декларирани на адреси примерно 70h, 71h и 72h при RP0 = 0 ще се запишат точно там, обаче ако RP0 = 1 ще се запишат на F0h, F1h и F2h. Ако в прекъсването се променя стойността на RP0 резултатите са непредсказуеми, инструкцията banksel INTCON прави точно това. Тя нулира PR0 и W, STATUS и PCLATH ще се възстановят от адреси 70h, 71h и 72h, незаисимо, че са били записани в F0h, F1h и F2h ако RP0 е бил в 1. Между другото INTCON е достъпен във всички банки, така че banksel INTCON е излишна.
Заради тази особеност никога не съм ползвал PIC16F873A/874A, слагам 876A/877A, декларирам W_Temp, STATUS_Temp и PCLATH_Temp някъде между 70h и 7Fh и ми е мирна главата.

Бих предложил следния код:
; Възстановява STATUS както е бил при влизането в прекъсването
swapf STATUS_Temp,W
movwf STATUS ; Restore STATUS register - restores bank

;Регистрите се четат от банката, в която са били записани
movfw PCLATH_Temp
movwf PCLATH ; Restore PCLATH
swapf STATUS_Temp,W
movwf STATUS ; Restore STATUS register - restores bank
swapf W_Temp,F
swapf W_Temp,W ; Restore W register
retfie

Разбира се, ако W_Temp, STATUS_Temp и PCLATH_Temp са на адреси примерно 70h - 72h , адресите F0h - F2h в банка 1 не трябва да се ползват нито в главната програмат, нито в прекъсването.

Гаранции не давам, все пак никога не съм го проверявал :roll:


Нед Фев 15, 2009 6:13 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 6 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 28 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни