Bank'lar arası CALL çalıştırmak???

Başlatan serdararikan, 06 Nisan 2015, 15:22:59

serdararikan

bir sorunum var.şöyle anlatayım;

16F877 için..

1.durum   =>    bank0 daki bir fonksiyondan bank3 deki bir fonksiyonu çağırıyorum.sorunsuz çalışıyor.
2.durum   =>    kesme rutininden bank2 deki başka bir fonksiyonu çağırıyorum.bu da sorunsuz çalışıyor.
3.durum   =>    1.durum ile 2. durumu aynı anda kullanmaya çalıştığımda bir süre sonra pic 0x0000 adresine gidiyor.biraz çalışıyor tekrar oraya gidiyor.yani hatalı bir çalışma var

kesme programının başında status ve W yi yedekliyorum.hatta bank3 deki fonksiyona giderken PCLATH ı da yedekliyorum.ama sorunu bir türlü çözemedim

RaMu

Stack overflow gibi gözüküyor.
Belki bank değiştirirken geri dönüş bankını ayarlamayı atlıyor da olabilirsin.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

serdararikan

ana program:
list p=16f877a
#include "p16f877a.inc"
_CONFIG EQU  H'2007'
#DEFINE t10ms .158
X0 equ 0x20
Y0 equ 0x21
sonuc equ 0x22
M0 equ 0x23
Bag0 equ 0x24
Bag1 equ 0x25
W_TEMP equ 0x26
STATUS_TEMP equ 0x27
val1 equ 0x28
val1H equ 0x29
val2 equ 0x2A
val2H equ 0x2B
val3 equ 0x2C
val3H equ 0x2D
val4 equ 0x2E
val4H equ 0x2F
result equ 0x30
resultH equ 0x31
count equ 0x32
countH equ 0x33
tmp equ 0x34
tmpH equ 0x35
FUNC_TMP equ 0x36
BitsVar0 EQU 0x37
PCLATH_TMP EQU 0x38
T0val EQU 0xA0
T0valH EQU 0xA1
#DEFINE T0_en BitsVar0,0
#DEFINE T0bit BitsVar0,1
#DEFINE T0LimL 208
#DEFINE T0LimH 7
ORG 0
GOTO ayarlar
ORG 0x08
Interrupt:
MOVWF W_TEMP
SWAPF STATUS,W
MOVWF STATUS_TEMP
CLRF STATUS
MOVLW t10ms
MOVWF TMR0
BCF INTCON,TMR0IF
BSF PCLATH,4
BCF PCLATH,3
GOTO 0x1000
KesmeDon:
SWAPF STATUS_TEMP,W
MOVWF STATUS
SWAPF W_TEMP,F
SWAPF W_TEMP,W
RETFIE
ayarlar:
banksel TRISA
MOVLW 0xFF
MOVF TRISB
CLRF TRISD
MOVLW B'11000110'
MOVWF OPTION_REG
MOVLW B'11100000'
MOVWF INTCON
banksel PORTD
CLRF PORTD
MOVLW t10ms
MOVWF TMR0
CLRF M0
BSF M0,0
BSF M0,1
basla:
BTFSS M0,2
GOTO $+3
BCF M0,2
GOTO $+2
BSF M0,2
MOVF PORTB,W
MOVWF X0
BCF sonuc,0
BTFSC X0,0
BSF sonuc,0
BTFSS sonuc,0
GOTO $+3
BSF T0_en
GOTO $+2
BCF T0_en
;________________________________________________________
BCF sonuc,0
BSF STATUS,RP0
MOVF T0val,W
BCF STATUS,RP0
MOVWF val1
BSF STATUS,RP0
MOVF T0val+1,W
BCF STATUS,RP0
MOVWF val1+1
MOVLW 232
MOVWF val2
MOVLW 3
MOVWF val2+1
MOVF PCLATH,W
MOVWF FUNC_TMP
BSF PCLATH,4
BSF PCLATH,3
CALL cmp_u16
BTFSC sonuc,4
BSF sonuc,0
BTFSS sonuc,0
GOTO $+3
BSF Y0,0
GOTO $+2
BCF Y0,0
;________________________________________________________
MOVF Y0,W
MOVWF PORTD
BCF M0,1
BCF PCLATH,4
BCF PCLATH,3
GOTO basla
ORG 0x1000
BTFSS T0_en
GOTO $+17
BSF STATUS,RP0
MOVF T0val+1,W
SUBLW T0LimH
BTFSS STATUS,Z
GOTO $+5
MOVF T0val,W
SUBLW T0LimL
BTFSC STATUS,Z
GOTO $+5
INCF T0val
BTFSC STATUS,Z
INCF T0val+1
GOTO $+7
BCF STATUS,RP0
BSF T0bit
GOTO $+6
BSF STATUS,RP0
CLRF T0val
CLRF T0val+1
BCF STATUS,RP0
BCF T0bit
MOVLW 0
MOVWF PCLATH
GOTO KesmeDon
ORG 0x1800
#INCLUDE "lib\cmp_u16.inc"
end



çağırılan fonksiyon;
;val1>val2 => sonuc,2
;val1=val2 => sonuc,3
;val1<val2 => sonuc,4
cmp_u16:
movlw B'11100011'
andwf sonuc,F
MOVF val2+1,w
SUBWF val1+1,w
BTFSS STATUS,C
GOTO $+13 ;val1<val2
BTFSS STATUS,Z
GOTO $+9 ;val1>val2
MOVF val2,w
SUBWF val1,w
BTFSS STATUS,C
GOTO $+7 ;val1<val2
BTFSS STATUS,Z
GOTO $+3 ;val1>val2
BSF sonuc,3    ;val1=val2
GOTO $+4
BSF sonuc,2    ;val1>val2
GOTO $+2
BSF sonuc,4    ;val1<val2
bcf INTCON,7
movf FUNC_TMP,W
movwf PCLATH
bsf INTCON,7
return


http://s3.dosya.tc/server/yk1vmq/sim.rar.html

portb nin 0. pinine lojik 1 girdiğinizde timer sayıyor 1000 den küçükse portd.0=1 değilse portd.0=0 oluyor.

burada kesme ve altprogramı aynı bankta çalıştırınca sorun olmuyor.ama kurduğum yapı gereği kesmenin bank2 altprogramın bank3 de çalışması gerekiyor

RaMu

#3
cmpu_16.inc de
    GOTO $+13 ;val1<val2

burada 13 derleyici ayarlarına göre
çok büyük ihtimalle neredeyse kesin olarak
decimal 13 olarak algılanmaz,
deciaml olarak kullanmak istediğiniz sayıların başına nokta koyabilirsiniz
veya decimal değerinin karşılığını hex olarak yazabilirsiniz,
burada,
    GOTO $+.13 ;val1<val2

olmalı
veya
    GOTO $+0x0D ;val1<val2

yazılabilir.

Programın birçok ksımında decimal olarak kullanılan sayılar hatalı yazılmış,
veya ide ayarlarını değiştirip bu yazımın decimale tekabul ettiğini söylemişsinizdir.


Birde
ORG 0
GOTO ayarlar
ORG 0x08
Interrupt:


kısmı kesme için 0x04 adresini kullanmalı.
ORG 0
GOTO ayarlar
ORG 0x04
Interrupt:


Şimdilik bunlar gözüme çarptı,
algoritmanız doğrumu bakmadım.


mesaj birleştirme:: 06 Nisan 2015, 17:34:54

Birde bank geçişi için şöyle bir kolaylık vardı,
uzun zamandır asm ile program yazmadığım için bazı şeyleri net hatırlamıyorum,
ama buna benzer şeyleri araştırabilirsin;
     pagesel    MySub   ; çağrılacak altprogramın label ini kullanarak bankına geçiyoruz
     call       MySub   ; altprogramı çağırıyoruz
     pagesel         ; altprogramdan döndüğünde şuanki program sayfamızın bankını seçtiriyoruz



stack overflow oluşması için
call ile bir altprogram çağrıldığında
bu altprogramdan return ile dönülmemiş olunması gerekir.

Veya içiçe 7 den fazla call kullanılmış olması gerekir,
bu 7 nin içinde bir tanede kesme için kullanılacağı hesaba katılmalı.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

RaMu

#4
Sizin kodlar üzerinde düzenleme yapmıştım,
algoritmanıza bakmadım ama uygulama stack overflow yapmıyor bu düzenlemeyle:

,Ana program
ERRORLEVEL -203,-205,-302,-305,-306
messg " "
messg "UYARILARI GORMEK ICIN errorlevel SATIRINI YORUM YAPIN _____ RaMu ______"
messg " "
list p=16f877a
#include "p16f877a.inc"
#INCLUDE "cmp_u16.inc"
_CONFIG EQU  H'2007'
#DEFINE t10ms .158
X0 equ 0x20
Y0 equ 0x21
sonuc equ 0x22
M0 equ 0x23
Bag0 equ 0x24
Bag1 equ 0x25
W_TEMP equ 0x26
STATUS_TEMP equ 0x27
val1 equ 0x28
val1H equ 0x29
val2 equ 0x2A
val2H equ 0x2B
val3 equ 0x2C
val3H equ 0x2D
val4 equ 0x2E
val4H equ 0x2F
result equ 0x30
resultH equ 0x31
count equ 0x32
countH equ 0x33
tmp equ 0x34
tmpH equ 0x35
FUNC_TMP equ 0x36
BitsVar0 EQU 0x37
PCLATH_TMP EQU 0x38
T0val EQU 0xA0
T0valH EQU 0xA1
CBLOCK 39h
w_temp
status_temp
pclath_temp
fsr_temp
ENDC
#DEFINE T0_en BitsVar0,0
#DEFINE T0bit BitsVar0,1
#DEFINE T0LimL .208
#DEFINE T0LimH .7
   
ORG 0
GOTO ayarlar
ORG 0x04
Interrupt:
movwf w_temp ;given multiple banks, and no global memory
;you need to make a w_temp in each because you cannot change status prior to saving it.
swapf STATUS,w ;The swapf instruction, unlike the movf, affects NO status bits, which is why it is used here.
clrf STATUS ;point to bank 0 and clear all the flags
movwf status_temp
movf PCLATH,w ;save PCLath
movwf pclath_temp
clrf PCLATH ;assume that this ISR is in page 0
;bcf status,irp ;This bcf is redundant & unnecessary unless the clrf status (above) is removed
movf FSR,w
movwf fsr_temp
;----------------------isr starts here-------------------
pagesel bin_etiket
    call bin_etiket
pagesel $
KesmeDon:
;-----------------------isr ends here---------------------
movf fsr_temp,w
movwf FSR
movf pclath_temp,w
movwf PCLATH
swapf status_temp,w
movwf STATUS
swapf w_temp
swapf w_temp,w
;********************
    RETFIE
ayarlar:
    banksel TRISA
       
    MOVLW 0xFF
    MOVF TRISB
    CLRF TRISD
    MOVLW B'11000110'
    MOVWF OPTION_REG
   
    MOVLW B'11100000'
    MOVWF INTCON
    banksel PORTD
    CLRF PORTD
    MOVLW t10ms
    MOVWF TMR0
    CLRF M0
    BSF M0,0
    BSF M0,1
basla:
    BTFSS M0,2
    GOTO $+3
    BCF M0,2
    GOTO $+2
    BSF M0,2
    MOVF PORTB,W
    MOVWF X0
   
    BCF sonuc,0
    BTFSC X0,0
    BSF sonuc,0
    BTFSS sonuc,0
    GOTO $+3
    BSF T0_en
    GOTO $+2
    BCF T0_en
;________________________________________________________
    BCF sonuc,0
    BSF STATUS,RP0
    MOVF T0val,W
    BCF STATUS,RP0
    MOVWF val1
    BSF STATUS,RP0
    MOVF T0val+1,W
    BCF STATUS,RP0
    MOVWF val1+1
    MOVLW .232
    MOVWF val2
    MOVLW 3
    MOVWF val2+1
    MOVF PCLATH,W
    MOVWF FUNC_TMP
pagesel cmp_u16
    CALL cmp_u16
pagesel $
    BTFSC sonuc,4
    BSF sonuc,0
    BTFSS sonuc,0
    GOTO $+3
    BSF Y0,0
    GOTO $+2
    BCF Y0,0
;________________________________________________________
    MOVF Y0,W
    MOVWF PORTD
    BCF M0,1
pagesel basla
    GOTO basla
pagesel $
ORG 0x1000
bin_etiket    BTFSS T0_en
    GOTO $+.17
    BSF STATUS,RP0
    MOVF T0val+1,W
    SUBLW T0LimH
    BTFSS STATUS,Z
    GOTO $+5
    MOVF T0val,W
    SUBLW T0LimL
    BTFSC STATUS,Z
    GOTO $+5
    INCF T0val
    BTFSC STATUS,Z
    INCF T0val+1
    GOTO $+7
    BCF STATUS,RP0
    BSF T0bit
    GOTO $+6
    BSF STATUS,RP0
    CLRF T0val
    CLRF T0val+1
    BCF STATUS,RP0
    BCF T0bit
;    MOVLW 0
;    MOVWF PCLATH
;rpagesel KesmeDon
    ;GOTO KesmeDon
return
;ORG 0x1800
;#INCLUDE "cmp_u16.inc" ;PROGRAMIN BAŞINDA HALLEDİLDİ
end



Alt program
;val1>val2 => sonuc,2
;val1=val2 => sonuc,3
;val1<val2 => sonuc,4
ORG 0x1800
cmp_u16
    movlw B'11100011'
    andwf sonuc,F
    MOVF val2+1,w
    SUBWF val1+1,w
    BTFSS STATUS,C
    GOTO $+.13 ;val1<val2
    BTFSS STATUS,Z
    GOTO $+.9 ;val1>val2
    MOVF val2,w
    SUBWF val1,w
    BTFSS STATUS,C
    GOTO $+.7 ;val1<val2
    BTFSS STATUS,Z
    GOTO $+.3 ;val1>val2
    BSF sonuc,3    ;val1=val2
    GOTO $+.4
    BSF sonuc,2    ;val1>val2
    GOTO $+.2
    BSF sonuc,4    ;val1<val2
nop
;    bcf INTCON,7
;    movf FUNC_TMP,W
;    movwf PCLATH
;    bsf INTCON,7
    return





Buda isis ve mplab çalışma dosyaları.
https://www.dropbox.com/s/crf6u98e09kh3ju/sarikan_bank_1.rar?dl=0

mesaj birleştirme:: 09 Nisan 2015, 23:01:53




Buradada detayları anlattığım bir konu açtım
https://www.picproje.org/index.php?topic=58682.new#new
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Pyrodigy

GOTO $+.13 ;val1<val2
şeklinde program yönlendirmesi doğru bir programcılık örneği değil. İlerde altına bir kod dizimi yazman gerekse ve komut satırı sayısını hesaplamazsan hapı yuttun demektir.
Onun yerine ASM de Label yani etiket atayarak bu yönlendirmeni şu şekilde yaparsın
;KODLAR
goto  SURAYA_GIT
; DAHA FAZLA KOD
SURAYA_GIT:
; DALLANMADAN SONRAKİ KODLAR

Böylece ilerde programını değiştirmek zorunda kaldığında satır sayısı hesap etmeden rahatlıkla ekler veya çıkarırsın.
Persistance is the name of the game in this business....

Tagli

Sorunun temelinde eski PCLATH'ın kesme içinde yedeklenmemesi yatıyor bence. RaMu gerekli düzeltmeyi yapmış.

Bu arada, soruda bank ve page kavramları karıştırılmış.
Gökçe Tağlıoğlu

serdararikan

Normalde C kullanıyorum.Ilk defa program yazmıyorum.yapmak istedigim programı assembler ile yazmak istiyorum.bi mantığı var tabiki.
Goto olayına gelince bilerek ve isteyerek label kullanmadım, kullanmamam da gerekiyor.uzun zaman oldu assembly ile uğraşmayali.unutmuşuz bazı şeyleri.