PIC och relocatable code

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
jonas2307
Inlägg: 479
Blev medlem: 11 juni 2005, 08:48:33
Ort: Älvsjö

PIC och relocatable code

Inlägg av jonas2307 »

Hej!

Jag hr skrivit ihop en kodsnutt för att hantera lcd displayer.
Kunna flytta cursor, skriva ut, skriva ut värdet i W som hex osv.
Den fungerar även om den kanske inte är så snygg...

Dock, jag skulle vilja ha den "relocatable", för att enkelt kunna använda rutinerna i andra projekt.
Dock har jag inte lyckats förstå alla detaljer i hur man gör detta.
Jag har suttit med manualen för MPLAB IDE och tillhörande linker, men icke.

Så, har någon en enkel förklaring till vad som ska ändras?
Koden är gjord för en 16F628A.

Tyvärr verkar alla tabuleringar försvinna, koden ser bättre ut i MPlab...

Detta är koden i absolute mode, som fungerar:

Kod: Markera allt

; FOR 			PIC16F628A	
; WDT			OFF 
; CODE PROTECT		OFF
; CLOCK			Internal 4MHz  
; INSTRUCTION CLOCK 	 

; FUNCTION	testing LCD

	list	p=16F628A

;**********  PIC SYSTEM REGISTER FILE EQUATES **********

porta		equ	05h
portb		equ	06h
status		equ	03h
cmcon		equ	1Fh
trisa   	equ	85h 	; bank 1
trisb   	equ	86h		; bank 1

#define		c	status,0	; carry bit
#define		z	status,2	; zero bit
#define		E	porta,0		; Control line E
#define		RW	porta,1		; Control line R/W
#define		RS	porta,2		; Control line RS
#define		rp0	status,5	; Page swap bit
#define		rp1	status,6	; Page swap bit


  cblock 20h
	count_reg
	short_del
	long_del
	save_w
	save_stat
	temp1
	temp2
	
  endc


; ************************* macro's **********************

page1	macro	
	bsf	rp0		; change to page 1
	bcf	rp1
	endm

page0	macro	
	bcf	rp0		; change to page 0
	bcf	rp1
	endm

	org     0

	goto    start

;**************** Interrupt handler *************************
  
	org	4						; Interrupt vector
	goto	start
;**************** subroutines *********************

pulse_e	bsf		E
		nop
		bcf		E
		retlw	0
		
;shortdelay	decfsz	short_del
;			goto	shortdelay
;			retlw	0
			
;longdelay	call	shortdelay
;			decfsz	long_del
;			goto	longdelay
;			retlw	0
			
functionset	bcf		RS
			bcf		RW
			movlw	b'00111000'
			movwf	portb
			call	pulse_e
			call	busywait	;shortdelay
			retlw	0
			
displayon	bcf		RS
			bcf		RW
			movlw	0Fh
			movwf	portb
			call	pulse_e
			call	busywait	;shortdelay
			clrf	count_reg
			retlw	0

;lcd_clr		bcf		RS
;			bcf		RW
;			movlw	b'00000001'
;			movwf	portb
;			call	pulse_e
;			call	busywait
;			clrf	count_reg
;			retlw	0
			
lcd_line1	bcf		RS
			bcf		RW
			movlw	b'10000000'
			movwf	portb
			call	pulse_e
			call	busywait
			clrf	count_reg
			retlw	0
			
lcd_line2	bcf		RS
			bcf		RW
;			movlw	40h
			movlw	b'11000000'
			movwf	portb
			call	pulse_e
			call	busywait
			clrf	count_reg
			retlw	0
			
setadress	bcf		RS
			bcf		RW
			movlw	b'10001000'
			movwf	portb
			call	pulse_e
			call	busywait
			clrf	count_reg
			retlw	0
			
curs_home	bcf		RS
			bcf		RW
			movlw	b'00000010'
			movwf	portb
			call	pulse_e
			call	busywait
			clrf	count_reg
			retlw	0
			
text		addwf	02h,f
			retlw	'H'
			retlw	'E'
			retlw	'L'
			retlw	'L'
			retlw	'O'
			
message		movf	count_reg,w
			call	text
			bsf		RS
			bcf		RW
			movwf	portb
			call	pulse_e
			call	busywait	;shortdelay
			incf	count_reg,w
			xorlw	05h
			btfsc	z
			retlw	0
			incf	count_reg,f
			goto	message
			
lcd_char	bsf		RS			; lcd_char puts value in W on lcd
			bcf		RW
			movwf	portb
			call	pulse_e
			call	busywait
			retlw	0
			
lcd_val				; converts byte in W to two characters and outputs
			MOVWF 	save_w		; save W and STATUS
			SWAPF 	status, w
			MOVWF 	save_stat

			MOVF 	save_w, w	; get back W
			MOVWF 	temp1		; save a copy
			SWAPF 	temp1, w	; high nibble now in lo nibble of W
			ANDLW 	0FH	; 
			MOVWF 	temp2		; copy to TEMP2
			SUBLW 	.9			; W = 9 - TEMP2		
			BTFSS 	c			; TEMP2 > 9
			GOTO 	_ALPHA_HI	 

_NUMERIC_HI
			MOVF 	temp2, W	; get the original nibble
			ADDLW 	'0'	; add character 0
			GOTO 	_OUT_1_DIG_HI

_ALPHA_HI
			MOVF 	temp2, W
			ADDLW 	'0'+7	; for 'A', 'B', 'C', 'D', 'E' and 'F'
	
_OUT_1_DIG_HI
			CALL 	lcd_char
							; now the lower nibble
			MOVF 	temp1, W	; low nibble now in lo nibble of W
			ANDLW 	0FH	; 
			MOVWF 	temp2	; copy to TEMP2
			SUBLW 	.9		; W = 9 - TEMP2		
			BTFSS 	c		; TEMP2 > 9
			GOTO 	_ALPHA_LO	 

_NUMERIC_LO
			MOVF 	temp2, W	; get the original nibble
			ADDLW 	'0'	; add character 0
			GOTO 	_OUT_1_DIG_LO

_ALPHA_LO
			MOVF 	temp2, W
			ADDLW 	'0'+7	; for 'A', 'B', 'C', 'D', 'E' and 'F'
	
_OUT_1_DIG_LO
			CALL 	lcd_char

			SWAPF 	save_stat, W	; restore STATUS
			MOVWF 	status
			SWAPF 	save_w, F	; get back W without altering STATUS
			SWAPF 	save_w, W

			retlw	0
			
busywait	page1
			movlw	b'11111111'		; Set port b to inputs
			movwf	trisb
			page0			; Done!
			bcf		RS
			bsf		RW
			nop
busyread	bsf		E
			nop
			rlf		portb,w
			bcf		E
			nop
			nop
			btfsc	c
			goto	busyread
			page1
			movlw	b'00000000'		; Set port b to output
			movwf	trisb	; Done!
			page0
			retlw	0
			
start
        clrf	short_del    
        clrf	long_del
        clrf	count_reg
        clrf	porta
        movlw	0x07		; Set all inputs on port a to digital I/O
        movwf	cmcon		; Done!
        clrf	portb
        
		page1
		clrf	trisb
		movlw	b'11111000'
		movwf	trisa		; Set pins 0-2 on port a to outputs
		
		page0
		
		call	busywait		; longdelay
		call	functionset
		call	displayon
		call	curs_home
		call	lcd_line1
		call	message
		call	setadress
		call	message
		call	lcd_line2
		movlw	b'01001000'
		call	lcd_val
;		call	message
		
loop	goto loop		; Hang forever

  end
Senast redigerad av jonas2307 5 november 2006, 19:52:48, redigerad totalt 1 gång.
Kaggen
Inlägg: 432
Blev medlem: 29 januari 2005, 03:06:02

Inlägg av Kaggen »

Skulle rekommendera att du gör ett nytt projekt i MPLAB och kopierar mall-filen som följer med för objekt-kod och kopierar och klistrar in din kod (eller de delar som bör vara med) på lämpligt ställe (förslagsvis efter "MAIN CODE" och "start". Ta också bort dina "ORG" satser och kopiera in den koden i de befintliga "CODE" satserna som finns i mallen.

Du hittar mall/template-filen i:

C:\Program\Microchip\MPASM Suite\Template\Object

om du installerat MPLAB i "C:\Program" förstås. Filen för 16F628A heter f628Atmpo.asm

Denna fil är alltså ett kod-skelett som man kan använda när man startar ett projekt.

EDIT: I mallfilen finns också en inkludering av rätt "include"-fil för definition av processor-specefika variabler för PORTA m.fl.:

#include <p16F628A.inc> ; processor specific variable definitions

...så du kan kapa dina definitioner i början av din kod för dessa.
Senast redigerad av Kaggen 2 november 2006, 22:37:32, redigerad totalt 3 gånger.
Användarvisningsbild
Abra Hana
Inlägg: 94
Blev medlem: 12 maj 2005, 13:20:58

Inlägg av Abra Hana »

*

1) Flytta dina macro till en separat fil till exempel "min_makro.inc ".

2) Flytta all deklarative kod till en header fil till
exempel "mina_variabler.inc" .

minavariabler.inc ------------innehåller -------
porta equ 05h
portb equ 06h
.......
......
......
#define c status,0 ; carry bit
......
......
#define rp1 status,6 ; Page swap bit

du kan också flytta dina macro här om dem är beroende av dina
variabler .
-------------------------------------------------------------------------------


2) Flytta helst samtliga subrutiner till en separat assemble eller header fil till exempel "mina_subrutine.asm" .

3) inkludera filer som innehåller deklaration av variabler och macron precis efter list p=16F628A med direktivet #include

till exempel .
list p=16F628A
#include "mina_variabler.inc"
#include "mina_makro.inc"

4) Om du vill så , du kan inkludera filen "mina_subrutin.asm"!? med direktivet #include precis förre direktivet END .
Om du vill placera dina subrutiner i ett bestämt address i program minnet använd direktivet ORG förre #include .

exempel :
ORG #onskat address minnet#
#include "mina_subrutine.asm"
END .


*
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Bara ett par småsaker...

> ; FOR PIC16F628A

Och var är includen av INC filen ??

> ; WDT OFF
> ; CODE PROTECT OFF
> ; CLOCK Internal 4MHz

Och var är __CONFIG direktivet ?

> #define c status,0 ; carry bit
> #define z status,2 ; zero bit

Notera att både "C" och "Z" redan är definierade i include filen och det normala
är att göra "bcf status, c" eller "btfss status, z" eller liknande.

Med dina extra (helt onödiga!) definitioner låser du upp koden till att
C och Z *alltid* ligger som bit "0" resp "2". Vad är fördelen ??

Du skulle kunna göra så här :

> #define C status, C ; carry bit

men jag ser inte nyttan med det.

> #define rp0 status,5 ; Page swap bit
> #define rp1 status,6 ; Page swap bit

Här är det ännu värre... :-)
Använd BANKSEL !!

> porta equ 05h
> portb equ 06h
> status equ 03h
> cmcon equ 1Fh
> trisa equ 85h ; bank 1
> trisb equ 86h ; bank 1

Plocka *omedelbart* bort dom där dumheterna !
INC filen inehåller alla definitioner du behöver.

> page1 macro
> bsf rp0 ; change to page 1
> bcf rp1
> endm
>
> page0 macro
> bcf rp0 ; change to page 0
> bcf rp1
> endm

Ta bort det där och kör med BANKSEL.

> retlw 0

Någon speciell anledning till att *inte* använda RETURN ?

Sen är det generellt svårt att se vad som är subrutiner, var subrutinerna
slutar och var huvudkoden börjar. Det är naturligtsvis en smaksak, men
jag brukar lägga alla subrutiner sist i källkoden, så att main-koden
hamnar först, jag tycker (personligen) att det blir mer logiskt så.

Abra Hana > "Om du vill placera dina subrutiner i ett bestämt address i program minnet använd direktivet ORG..."

Eftersom han specifikt frågade efter *relokerbar* kod, så fungerar inte det.
Sen är det ovanligt att man vill lägga subrutiner på en viss adress.

Här är ett enkelt 628A program som kanske kan ge lite ledtrådar :

Kod: Markera allt

;**********************************************************************
;   Enkelt blink-a-led, 16F628A.                                       *
;                                                                     *
;**********************************************************************
;    Files required:  P16F628A.INC                                     *
;                     16F628A.LNK                                      *
;                                                                     *
;**********************************************************************


	list      p=16f628A
	#include <p16f628A.inc>
	
	__CONFIG   _DATA_CP_OFF & _CP_OFF & _LVP_OFF & _BODEN_OFF & _BOREN_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC & _MCLRE_OFF

RESET_VECTOR    CODE    0x000     ; processor reset vector
	    goto    start             ; go to beginning of program


INT_VECTOR      CODE    0x004     ; interrupt vector location
        goto    isr_routine       ; goto main interrupt service routine.
        

;***************************************************************
MAIN    CODE

start

        banksel cmcon
        movlw   h'07'
        movwf   cmcon            ; Stäng av ADC.

        banksel trisa
        clrf    trisa
        clrf    trisb             ; Alla pinnar = utgångar.

        banksel t1con
        movlw   b'00110001'
        movwf   t1con             ; Se datablad...
        
        banksel pie1
        movlw   b'00000001'
        movwf   pie1              ; Enable avbrott från TMR1.

        banksel intcon	
        bsf     intcon, peie
        bsf     intcon, gie       ; Enable avbrott...

loop
        goto loop                 ; Vänta på avbrott...
 


;***************************************************************
ISR_ROUTINE  CODE

isr_routine

        banksel portb
        comf    porta            ; Blinka !!

        banksel pir1
        bcf     pir1, tmr1if     ; clear avbrotts flagga.

        retfie

		end
BoF
EF Sponsor
Inlägg: 222
Blev medlem: 7 oktober 2006, 16:43:37

Inlägg av BoF »

banksel portb
comf porta ; Blinka !!

Kan ju göra en nybörjare undrande!

Nu ligger PORTB på samma bank som PORTA ( på en 628A) men borde det inte varit
banksel porta
comf porta

För att inte vilse leda oss dummy :wink:
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Korrekt !
Det ska naturligtsvis vara porta i båda fallen.
Det är justerat i originalfilen...
jonas2307
Inlägg: 479
Blev medlem: 11 juni 2005, 08:48:33
Ort: Älvsjö

Inlägg av jonas2307 »

Hm....

Nu har jag försökt följa råden i tråden ovan, men utan någon större framgång...
Koden som jag började tråden med, som inte är relokerbar, fungerar.

Nu har jag använt include filen och lnk filen som följer med mplab.
Men applikationen fungerar inte, vet inte riktigt hur långt den kommer eftersom det bara blir fyllda fyrkanter på första raden på displayen.

Koden som den ser ut nu, ickefungerande:

Kod: Markera allt

**********************************************************************
;   This file is a basic code template for object module code         *
;   generation on the PICmicro PIC16F628A. This file contains the     *
;   basic code building blocks to build upon.  As a project minimum   *
;   the 16F628A.lkr file will also be required for this file to       *
;   correctly build. The .lkr files are located in the MPLAB          *
;   directory.                                                        *
;                                                                     *
;   If interrupts are not used all code presented between the         *
;   code section "INT_VECTOR and code section "MAIN" can be removed.  *
;   In addition the variable assignments for 'w_temp' and             *
;   'status_temp' can be removed.                                     *
;                                                                     *
;   If interrupts are used, as in this template file, the 16F628A.lkr *
;   file will need to be modified as follows: Remove the lines        *
;     CODEPAGE   NAME=vectors  START=0x0      END=0x4      PROTECTED  *
;   and                                                               *
;     SECTION    NAME=STARTUP  ROM=vectors                            *
;   and change the start address of the page0 section from 0x5 to 0x0 *
;                                                                     *
;   Refer to the MPASM User's Guide for additional information on     *
;   features of the assembler and linker (Document DS33014).          *
;                                                                     *
;   Refer to the respective PICmicro data sheet for additional        *
;   information on the instruction set.                               *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Filename:	    xxx.asm                                           *
;    Date:                                                            *
;    File Version:                                                    *
;                                                                     *
;    Author:                                                          *
;    Company:                                                         *
;                                                                     *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Files required:                                                  *
;                    16F628A.lnk                                      *
;                     p16F628A.inc                                    *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Notes:                                                           *
;                                                                     *
;                                                                     *
;                                                                     *
;                                                                     *
;**********************************************************************

	list      p=16F628A           ; list directive to define processor
	#include <p16F628A.inc>       ; processor specific variable definitions

;	errorlevel  -302              ; suppress message 302 from list file


	__CONFIG   _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT 


; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See data sheet for additional information on configuration word settings.


#define		E	porta,0		; Control line E
#define		RW	porta,1		; Control line R/W
#define		RS	porta,2		; Control line RS

;***** VARIABLE DEFINITIONS (examples)

; example of using Shared Uninitialized Data Section
INT_VAR		UDATA_SHR	;	0x71   

count_reg	RES	1
short_del	RES	1
long_del	RES	1
save_w		RES	1
save_stat	RES	1
temp1		RES	1
temp2		RES	1
;w_temp		RES     1		; variable used for context saving 
;status_temp	RES     1		; variable used for context saving


;**********************************************************************
RESET_VECTOR	CODE	0x000		; processor reset vector
		goto    start              ; go to beginning of program


INT_VECTOR	CODE	0x004		; interrupt vector location
		goto	start
;		movwf   w_temp            ; save off current W register contents
;		movf	STATUS,w          ; move status register into W register
;		movwf	status_temp       ; save off contents of STATUS register


; isr code can go here or be located as a call subroutine elsewhere


;		movf    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


MAIN	CODE

pulse_e	bsf		E
		nop
		bcf		E
		return
		
functionset	bcf		RS
			bcf		RW
			movlw	b'00111000'
			movwf	portb
			call	pulse_e
			call	busywait
			return
			
displayon	bcf		RS
			bcf		RW
			movlw	0Fh
			movwf	portb
			call	pulse_e
			call	busywait	
			clrf	count_reg
			return
			

lcd_line1	bcf		RS
			bcf		RW
			movlw	b'10000000'
			movwf	portb
			call	pulse_e
			call	busywait
			clrf	count_reg
			return
			
lcd_line2	bcf		RS
			bcf		RW
			movlw	b'11000000'
			movwf	portb
			call	pulse_e
			call	busywait
			clrf	count_reg
			return
			
setadress	bcf		RS
			bcf		RW
			movlw	b'10001000'
			movwf	portb
			call	pulse_e
			call	busywait
			clrf	count_reg
			return
			
curs_home	bcf		RS
			bcf		RW
			movlw	b'00000010'
			movwf	portb
			call	pulse_e
			call	busywait
			clrf	count_reg
			return
			
text		addwf	02h,f
			retlw	'H'
			retlw	'E'
			retlw	'L'
			retlw	'L'
			retlw	'O'
			
message		movf	count_reg,w
			call	text
			bsf		RS
			bcf		RW
			movwf	portb
			call	pulse_e
			call	busywait
			incf	count_reg,w
			xorlw	05h
			btfsc	status, z
			return
			incf	count_reg,f
			goto	message
			
lcd_char	bsf		RS			; lcd_char puts value in W on lcd
			bcf		RW
			movwf	portb
			call	pulse_e
			call	busywait
			return
			
lcd_val							; converts byte in W to two characters and outputs
			MOVWF 	save_w		; save W and STATUS
			SWAPF 	status, w
			MOVWF 	save_stat

			MOVF 	save_w, w	; get back W
			MOVWF 	temp1		; save a copy
			SWAPF 	temp1, w	; high nibble now in lo nibble of W
			ANDLW 	0FH	; 
			MOVWF 	temp2		; copy to TEMP2
			SUBLW 	.9			; W = 9 - TEMP2		
			BTFSS 	status, c			; TEMP2 > 9
			GOTO 	_ALPHA_HI	 

_NUMERIC_HI
			MOVF 	temp2, W	; get the original nibble
			ADDLW 	'0'	; add character 0
			GOTO 	_OUT_1_DIG_HI

_ALPHA_HI
			MOVF 	temp2, W
			ADDLW 	'0'+7	; for 'A', 'B', 'C', 'D', 'E' and 'F'
	
_OUT_1_DIG_HI
			CALL 	lcd_char
							; now the lower nibble
			MOVF 	temp1, W	; low nibble now in lo nibble of W
			ANDLW 	0FH	; 
			MOVWF 	temp2	; copy to TEMP2
			SUBLW 	.9		; W = 9 - TEMP2		
			BTFSS 	status, c		; TEMP2 > 9
			GOTO 	_ALPHA_LO	 

_NUMERIC_LO
			MOVF 	temp2, W	; get the original nibble
			ADDLW 	'0'	; add character 0
			GOTO 	_OUT_1_DIG_LO

_ALPHA_LO
			MOVF 	temp2, W
			ADDLW 	'0'+7	; for 'A', 'B', 'C', 'D', 'E' and 'F'
	
_OUT_1_DIG_LO
			CALL 	lcd_char

			SWAPF 	save_stat, W	; restore STATUS
			MOVWF 	status
			SWAPF 	save_w, F	; get back W without altering STATUS
			SWAPF 	save_w, W

			return
			
busywait	;page1
			BANKSEL	trisb
			movlw	b'11111111'		; Set port b to inputs
			movwf	trisb
;			page0			; Done!
			bcf		RS
			bsf		RW
			nop
busyread	bsf		E
			nop
			rlf		portb,w
			bcf		E
			nop
			nop
			btfsc	status, c
			goto	busyread
;			page1
			BANKSEL	trisb
			movlw	b'00000000'		; Set port b to output
			movwf	trisb	; Done!
;			page0
			return
			
start
		clrf	short_del    
        clrf	long_del
        clrf	count_reg
        clrf	porta
        movlw	0x07		; Set all inputs on port a to digital I/O
        movwf	cmcon		; Done!
        clrf	portb
        
;		page1
		BANKSEL	trisb
		clrf	trisb
		BANKSEL	trisa
		movlw	b'11111000'
		movwf	trisa		; Set pins 0-2 on port a to outputs
		
;		page0
		
		call	busywait		; longdelay
		call	functionset
		call	displayon
		call	curs_home
		call	lcd_line1
		call	message
		call	setadress
		call	message
		call	lcd_line2
		movlw	b'01001000'
		call	lcd_val
	
loop	goto loop

end
Senast redigerad av jonas2307 5 november 2006, 19:48:49, redigerad totalt 1 gång.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

V.v. redigera ditt inlägg så att koden blir läsbar.
Använd

Kod: Markera allt

[code]
...
...
...
[/code] om du inte gör det.
jonas2307
Inlägg: 479
Blev medlem: 11 juni 2005, 08:48:33
Ort: Älvsjö

Inlägg av jonas2307 »

Jag förstår inte hur man får den bifogade koden att bli likadan som i mplab.
Gör jag copy and paste så blir det som ovan.

Vad menar du med code: i ditt exempel?

Ledsen att jag inte hajar...


- Jonas
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

jonas2307
Inlägg: 479
Blev medlem: 11 juni 2005, 08:48:33
Ort: Älvsjö

Inlägg av jonas2307 »

Ah, nu har jag lärt mig något nytt, igen....

-- Jonas
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Här går det fel :

Kod: Markera allt

busywait
         BANKSEL   trisb
         movlw     b'11111111'      ; Set port b to inputs
         movwf     trisb
         bcf       RS
         bsf       RW
         nop 
RS och RW ligger på PORTA och PORTA ligger inte i samma bank som TRISB.

Prova något i stil med:

Kod: Markera allt

busywait
         BANKSEL   trisb
         movlw     b'11111111'      ; Set port b to inputs
         movwf     trisb
         BANKSEL   porta
         bcf       RS
         bsf       RW
         nop 
Sen har jag inte kollat längre, det kan finnas fler
likande fel...
jonas2307
Inlägg: 479
Blev medlem: 11 juni 2005, 08:48:33
Ort: Älvsjö

Inlägg av jonas2307 »

Jag hade en fundering åt det hållet när jag studerade map-filen, jag förstod inte hur man kom tillbaks till bank 0 igen.
Det har man ju koll på om man styr det själv som jag gjorde innan.

Har jag rätt om jag misstänker att man måste använda banksel överallt, när man väl har börjat så att säga?
Användarvisningsbild
Icecap
Inlägg: 26662
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Byter du bank måste du byta tillbaka igen, oberoende av vilken metod du använder!

Om du gör det med banksel är det enklare att överskåda bara, du måste fortfarande tänka till själv.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> jag förstod inte hur man kom tillbaks till bank 0 igen.

Eller "tillbaks till bank 1" eller någon annan. Det är ingen skillnad.
Finessen med BANKSEL är att du inte behöver veta att du ska "tillbaka"
till den ena eller den andra banken. Du behölver inte ens veta vilen bank
som ett register ligger i, det tar MPASM hand om.

> Har jag rätt om jag misstänker att man måste använda banksel överallt, när man väl har börjat så att säga?

Som Icecap säger, byta till "rätt" bank måste du *alltid* göra, fördelen med
BANKSEL (jämfört med direkta BCF/BSF mot STATUS registret) är att du inte
behöver slå upp i databladet vilken bank ett register ligger i, det gör
MPASM åt dig.

Sen är det naturligtsvis så, att när man börjar bli lite varm i kläderna så
ser man många ställen där en BANKSEL är onödig. T.ex så behöver vissa
register *aldrig* en BANKSEL (t.ex PCL, OPTION, STATUS, PCLATH och INTCON
i fallet med 16F628A. Samt de sista 16 bytes RAM "shared memory" eller
"unbanked RAM"). I dessa fall är registret mappat över alla 4 bankerna.
Se "Data Memory Map" i databladet sid 16 så är det tydligt.

D.v.s att du inte behöver någon BANKSEL före registren ovan och inte
heller före access av någon av dina variabler. Om du däremot hade lagt
dom i "Banked RAM" (genom att skriva "INT_VAR UDATA" istället för
"INT_VAR UDATA_SHR", så hade det behövts BANKSEL före variablerna.

Alltså förstår man då att man skall använda "UDATA_SHR" till frekventa
variabler och "UDATA" till det som man inte behöver komma åt lika ofta...

Notera också att "UDATA" kommer själv att sprida variablerna över
tillgängligt minne i bank 0, 1 och 2. BANKSEL kommer dock alltid
att välja "rätt" bank. D.v.s att från build till en annan, så kan vissa
variabler att byta bank, men BANKSEL kommer automatiskt att
korrigera för det. Snyggt, eller hur !! Tänk hur det hade varit med
hårdkodade BCF/BSF (eller "bank0, bank1 o.s.v macron) !! Jäkligt
svårhittade buggar kan det bli...

Slutligen så kan man alltså säga att genom att utnyttja direktiven i
MPASM (och genom att köra rellokerbart) så försvinner faktiskt de flesta
av "problemen" med bankningen av minnet.
Skriv svar