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.