Dag iedereen,

Na een jaar in proton IDE geprogrammeerd te hebben hou ik het zowat voor bekeken en zou ik me graag meer verdiepen in assembler. Ik ben begonnen met de tutorial hier op de site grondig te lezen en nu zou ik graag beginnen programmeren.
Helaas loop ik al tegen een eerste probleem aan, op de tutorial van de site zegt men dat het geheugen van de microcontroller opgedeelt is in 2 banken (pic16F84). Ik gebruik echter de pic18F2550 en als ik daar eens in de datasheet kijk, dan beschikt men daar over 15(!) banken.
http://www.circuitsonline.net/img/000029.gifhttp://www.uploadarchief.net/files/download/bank.png
links is de pic16F84 en rechts is de pic18F2550
nu vroeg ik me af welk commando ik moet gebruiken om van de ene bank naar de andere te gaan, aangezien ik dit nergens kan terugvinden in de datasheet, ik vermoed dat het iets is met BCF en BSF maar hoe weet je welk getal erna moet komen? Dit staat jammer genoeg niet vermeld in de tutorial.
Is het overigens normaal dat er zoveel banken gebruikt worden?

Links boven staat BSR<3:0> . Ik neem aan dat dat de bits zijn die je moet gebruiken om van banken te wisselen. Dus

0000 is bank 0
0100 is bank 4
etc etc.

Je moet alleen zelf nakijken in welk register die bits zitten.

bedankt iedereen,
om van bank te wisselen moet ik inderdaad foefelen met bsr

Je kunt ook indirecte adressering gebruiken, dan hoeft bank-switching niet. (zie datasheet)

Access RAM is volgens mij altijd direct te adresseren zonder bank switching.

Ik meen dat je ook

 banksel [variabele]

kunt gebruiken, dan hoef je ook niet op te zoeken in welke bank de variabele zit.

bedankt :) helaas zit ik weeral met een probleem
nadat ik deze code wou assembleren (gewoon als tussentijdse test) dan gaf hij enkele foutmeldingen

       	 	ORG	00h     		;beginadres
		PORTA equ F80h
		TRISA equ F92h

		MOVLW 0FFh			;1111.1111 in werkregister zetten
		MOVWF TRISA			;Alle A poorten zijn inputs

		clrf PORTA			;PoortA low maken


Rij1
ARij1		btfss 01h, 0h		;controleer of er een a moet gezet worden
		goto BRij1		;zoniet ga naar b
		movlw 02h		;0000.0010 naar w-reg verplaatsen
		movwf PORTA		;clock poort van het schuifregister hoog maken
		movlw 03h		;0000.0011 naar w-reg verplaatsen
		movwf PORTA		;data en clock poort van het schuifregister hoog maken
		movlw 03h		;0000.0011 naar w-reg verplaatsen
		movwf PORTA		;data en clock poort van het schuifregister hoog maken
		movlw 03h		;0000.0011 naar w-reg verplaatsen
		movwf PORTA		;data en clock poort van het schuifregister hoog maken
		movlw 02h		;0000.0010 naar w-reg verplaatsen
		movwf PORTA		;clock poort van het schuifregister hoog maken

en dit is de foutmelding:

Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "C:\MPASM Suite\MPASMWIN.exe" /q /p18F2550 "lichtkrant.ASM" /l"lichtkrant.lst" /e"lichtkrant.err"
Warning[207] C:\DOCUMENTS AND SETTINGS\BERT\BUREAUBLAD\LICHTKRANT.ASM 18 : Found label after column 1. (PORTA)
Error[113]   C:\DOCUMENTS AND SETTINGS\BERT\BUREAUBLAD\LICHTKRANT.ASM 18 : Symbol not previously defined (F80h)
Warning[207] C:\DOCUMENTS AND SETTINGS\BERT\BUREAUBLAD\LICHTKRANT.ASM 19 : Found label after column 1. (TRISA)
Error[113]   C:\DOCUMENTS AND SETTINGS\BERT\BUREAUBLAD\LICHTKRANT.ASM 19 : Symbol not previously defined (F92h)
Warning[203] C:\DOCUMENTS AND SETTINGS\BERT\BUREAUBLAD\LICHTKRANT.ASM 604 : Found opcode in column 1. (goto)
Warning[205] C:\DOCUMENTS AND SETTINGS\BERT\BUREAUBLAD\LICHTKRANT.ASM 608 : Found directive in column 1. (end)
Halting build on first failure as requested.

de warnings kunnen normaal geen kwaad, maar waardoor zouden die 2 errors veroorzaakt kunnen zijn?
Als ik F80h verander in 80h dan werkt het plots wel?
hetzelfde met F92h

Gooi alsjeblieft die declaraties voor porta en trisa eruit en gebruik de include file zoals het hoort...
De errors komen doordat je labels niet in kolom 1 staan. (zoals er ook bij de error staat)
Kan zijn dat de compiler een numeriek teken verwacht als waarde (0F92h, of 0xF92, of H'0F92')

jahoe :) die 0 deed het hem
dit is wat er nu staat:

...
        ORG	00h     		;beginadres
		
PORTA 	equ		0F80h
TRISA 	equ 	0F92h


opnieuw 
Rij1
...

Als je (zoals voorgesteld) de .inc file gebruikt heb je geen probleem, omdat daar de juiste declaraties in staan...
Bij de 18f familie moet je trouwens LATx gebruiken voor output, en niet PORTx (is voor input)

De include file is toegevoegd, de config is aangepast en ik heb PORTA vervangen door LATA
Dit is hoe het er uit ziet:

#include P18F2550.inc

;RA0 = Data
;RA1 = CLK
;RA2 = Latch

	CONFIG PWRT 	= 	ON	; Enable power up timer
	CONFIG WDT 	= 	OFF	; disable watchdog timer
	CONFIG MCLRE	= 	ON	; Master CLear Reset pin enabled, RE3 input pin disabled
	CONFIG DEBUG 	= 	OFF	; Background debugger disabled, RB6 and RB7 configured as general purpose I/O pins
	CONFIG LVP 	= 	OFF	; Low-Voltage programming disabled (necessary for debugging)
	CONFIG FOSC 	= 	HS	; High speed oscillator	
    	CONFIG FCMEN 	=	OFF	; Fail-Safe Clock Monitor disabled
    	CONFIG IESO 	= 	OFF	; Oscillator Switchover mode disabled
	CONFIG BOR 	= 	OFF     ; Brown-out Reset disabled in hardware and software
	CONFIG VREGEN 	= 	OFF     ; USB voltage regulator disabled
	CONFIG PBADEN 	= 	ON      ; PORTB<4:0> pins are configured as analog input channels on Reset
	CONFIG STVREN 	=	OFF     ; Stack full/underflow will not cause Reset
	CONFIG XINST 	= 	OFF     ; Instruction set extension and Indexed Addressing mode disabled (Legacy mode)

        ORG	00h     		;beginadres

Delay1	res		1
Delay2	res		1

opnieuw 
Rij1
ARij1	btfss 	01h, 0h	;controleer of er een a moet gezet worden
	goto  	BRij1	;zoniet ga naar b
	movlw	02h	;0000.0010 naar w-reg verplaatsen
	movwf	LATA	;clock poort van het schuifregister hoog maken
	movlw	03h	;0000.0011 naar w-reg verplaatsen
	movwf	LATA	;data en clock poort van het schuifregister hoog maken
	movlw	03h	;0000.0011 naar w-reg verplaatsen
	movwf	LATA	;data en clock poort van het schuifregister hoog maken
	movlw	03h	;0000.0011 naar w-reg verplaatsen
	movwf	LATA	;data en clock poort van het schuifregister hoog maken
	movlw	02h	;0000.0010 naar w-reg verplaatsen
	movwf	LATA	;clock poort van het schuifregister hoog maken
...

ps, de site is veel verbeterd met o.a. die balk bovenaan in het antwoordvenster en natuurlijk ook met de picasm code tags

het programmeren begint al beter te lukken :)
nu vroeg ik me enkel nog af of je de naam van een variabele ook als label mag gebruiken.
Als er een teller op bv 1 staat, moet hij naar label 1 gaan, staat hij op 2 dan moet hij naar label 2 enz.
zou je dit eenvoudig zo kunnen programmeren?

incf variabele, 1      ;variabele met 1 verhogen
movlw 0FFh             ;256 in werkregister plaatsen
cpfslt variabele       ;256 vergelijken met variabele
clrf variabele         ;is variabele >256 dan terug op 0 zetten
goto variabele         ;is variabele = 1 dan naar label 1, enz.

Een variabele zit in het datageheugen, en niet in het programmageheugen, dus daar valt niks naar toe te 'goto-en'...

hoe zou ik dit het best kunnen oplossen?
in totaal zou ik zo'n 255 adresseringen moeten hebben, iedere keer call ... is nogal tijd- en geheugenrovend.
Het komt erop neer dat ik een teller verhoog (van 0 t.e.m. 255) en dat ik afhankelijk van die waarde een andere instructie doorvoer (1'en en 0'en inschuiven in een schuifregister)
de bits schuiven in het schuifregister is geen probleem, het is meer de link leggen tussen de teller en de labels dat nogal moeilijk is

Waarde in W (0...8) zetten. Uit te breiden tot 255


command		addlw	LOW  cmd_tab			
                movwf	tempreg			
		movlw	HIGH  cmd_tab			
		btfsc	status,c			
		addlw	d'1'				
		movwf	pclath				
		movf    tempreg,w

cmd_tab		movwf	pcl				
		goto	cmd_00				
		goto	cmd_01				
		goto	cmd_02				
		goto	cmd_03				
		goto	cmd_04				
		goto	cmd_05				
		goto	cmd_06				
		goto	cmd_07				
		goto	cmd_08				
;........................................................
cmd_00          ;...
                goto    cmd_end
cmd_01          ;...
                goto    cmd_end
cmd_02          ;...
                goto    cmd_end
cmd_03          ;...
                goto    cmd_end
cmd_04          ;...
                goto    cmd_end
cmd_05          ;...
                goto    cmd_end
cmd_06          ;...
                goto    cmd_end
cmd_07          ;...
                goto    cmd_end
cmd_08          ;...
                goto    cmd_end
cmd_end         return

Erg bedankt!
Als ik het goed doorheb dan gaat hij (afhankelijk van de waarde die je in w zet) ofwel kijken naar de eerste 8 bits ofwel naar de laatste 8 bits van cmd_tab en gaat hij via tempreg bepalen welke hij precies moet nemen van die 8 bits

Als ik het goed doorheb dan gaat hij (afhankelijk van de waarde die je in w zet) ofwel kijken naar de eerste 8 bits ofwel naar de laatste 8 bits van cmd_tab

Geen van beide. Het 'goto' adres zijn de laatste 11 bits. (Zie datasheet)

phoeh, de standaardinstructies zijn goed te doen, maar is er ergens een tutorial waar er uitleg gegeven wordt over lookup tables?
Deze worden nogal veel gebruikt als ik zo eens rondkijk, maar waar is er ergens een goede uitleg over het programmeren van dergelijke lookup tables. Een zoektocht op CO leverde alvast niet erg veel op

Waarom loopt programmeren nooit zoals je het wilt :)
dit programma heb ik gemaakt om een subroutine uit te voeren afhankelijk van de waarde van een variabele. De eerste instructie moet nog vervangen worden door een variabele, maar dat komt nog.

		movlw 4 * 01h
		addwf	PCL, 1
		goto letter1
		goto letter2
		goto letter3
		goto letter4
		goto letter5
		goto letter6
		goto letter7

Zoals je ziet breng ik eerst een waarde in het w-register waarna ik deze waarde optel bij de program counter. Hierdoor neemt hij telkens een andere "goto" en gaat hij bijgevolg elke keer naar een andere letter.
Nu redeneer ik als volgt: Je telt bv. 4 op bij de program counter dus slaat hij 4 instructies over waarna hij de (4+1=) 5e goto neemt.
Vreemd genoeg blijkt dit maar te werken als ik deze waarde 4 vermenigvuldig met 4, vandaar ook de * 4 in het programma
Ik herinner me nog van de assembler programmeercursus dat de waarde van het kristal gedeeld moest worden door 4 om de instructiesnelheid te weten, zou dit hier iets mee te maken kunnen hebben?

Zie net dat je een 18f MCU gebruikt, je moet dan wel met 2 vermenigvuldigen. (Program counter werkt met bytes, bij 12/16f was dat met words...) Je moet ook zorgen dat je binnen de 256 byte page blijft...


		movlw 4 * 01h
		addwf	PCL, f
		addwf	PCL, f  ; Extra add (= *2)  
		goto letter1
		goto letter2
		goto letter3
		goto letter4
		goto letter5
		goto letter6
		goto letter7

Als je 2 x add na elkaar zet dan heeft de tweede add toch geen effect?
Hij springt reeds bij de eerste add vooruit, dus slaat hij de tweede gewoon over?

Klopt, je hebt gelijk... Dus gewoon movlw 4*2 doen...

helaas zit ik dan met het probleem dat het werkregister maar 8 bits groot is, en dus maximum de waarde 255 kan bevatten
Als ik ooit 256 "goto's" wil zetten dan moet ik mininum de waarde 4 * 256 = 1023 in het w register krijgen.