hi!
hebben jullie tips hoe je de programmacode die verdeelt is over een aantal paginas , best kunt programmeren?
zo heb ik miserie met tabellen .
ik programeer in asm in mplab
als ik een tabel aanroep via een CALL , kan het gebeuren dat de pcl wel correct is maar niet de pclatch
ik heb mijn tabel ( een subroutine) nu helemaal bovenaangezet , zodat het zowat in pagina nul komt te staan
maar vanzodra ik nieuwe subroutines bijzet , valt gans het programma in panne , (zelfs routines die niet gebruikt zijn in het hoofdprogramma)
dus ik vermoed dat de subroutine de boel , laat verschuiven in mijn paginas
iemand tips ?
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Als je tabellen gebruikt moet je wel zorgen dat PCLATH goed staat voor het adres in de tabel dat je wilt lezen...
Zie AN556 voor uitgebreide info: http://ww1.microchip.com/downloads/en/AppNotes/00556e.pdf
picsels
Volgend project: 7-seg gaming displays; dan dec-1982 labvoeding afmaken, dan funcgen met ad9833 afmaken, dan...
Op 27 maart 2007 00:05:49 schreef Extragroot:
hi!hebben jullie tips hoe je de programmacode die verdeelt is over een aantal paginas , best kunt programmeren?
zo heb ik miserie met tabellen .
ik programeer in asm in mplabals ik een tabel aanroep via een CALL , kan het gebeuren dat de pcl wel correct is maar niet de pclatch
ik heb mijn tabel ( een subroutine) nu helemaal bovenaangezet , zodat het zowat in pagina nul komt te staan
maar vanzodra ik nieuwe subroutines bijzet , valt gans het programma in panne , (zelfs routines die niet gebruikt zijn in het hoofdprogramma)
dus ik vermoed dat de subroutine de boel , laat verschuiven in mijn paginas
iemand tips ?
Ik weet niet precies wat je bedoelt met 'een tabel aanroepen'.
Maar wat je in de gaten moet houden:
1. Als je iets gaat doen waarmee je PCL on the fly aanpast, met je eerst PCLATH goed vullen.
2. Als je een tabel oid gebruikt waar je 'in' springt (bijvoorbeeld voor GOTO's of RETLW's), mag die geen paginagrens overschrijven. De instructie waar je op uitkomt mag uiteraard wel weer buiten deze pagina liggen.
Dus controleer of het begin en einde van de sprongtabel binnen dezelfde pagina liggen.
Ik begin de sprong tabel gewoon standaard in pagina 2.
Pclath aanpassen en jumpen maar.
Zit je met je pagina over de grens dan moet je ff een stukkie code ertussen zetten dat eerst de sprong controleerd en indien nodig pclath aanpast.
mts plus
Life is waiting!
je kan als ik me niet vergis alleen tabellen en andere indirecte adresseringen op het eerste blad hebben staan.
ik begin me tabellen meestal hier
org 000H
en me code pas hier
org 0100H
Op 27 maart 2007 19:57:14 schreef mts plus:
ik begin me tabellen meestal hier
org 000H
Heel knap, want daar zit de reset vector van de PIC. Dat zal dus wel een ander getal zijn.
Maar er zijn twee grenzen waar je rekening mee moet houden:
1) De 256 byte grens wanneer je "computed gotos" gebruikt. Dat is met de instructie addwf PCL,F. Zo'n tabel mag een 256 byte grens niet passeren en je moet PCH laden met de correcte waarde. Met MPASM kan je met macro's foutmeldingen genereren wanneer dit gebeurt. (Handig wanneer je wat code invoegt en de tabel daardoor verschuift)
2) de 2K grens. Hier heb je last van met call en goto instructies, ook hier weer geld: eerst PCLATH laden. Maar ik denk dat er weinig C.O.'ers zijn die zulke grote assembly programmas maken.
picsels
Volgend project: 7-seg gaming displays; dan dec-1982 labvoeding afmaken, dan funcgen met ad9833 afmaken, dan...
Op 27 maart 2007 20:27:25 schreef JoWi:
[...]2) de 2K grens. Hier heb je last van met call en goto instructies, ook hier weer geld: eerst PCLATH laden. Maar ik denk dat er weinig C.O.'ers zijn die zulke grote assembly programmas maken.
Yep, vooral macro's maken het leven makkelijk.
Volgens mij heb je géén last van de 2K grens. Waar je last van zou kunnen krijgen is de 4K grens.
Tot 4K kun je voor zover ik weet doen wat je wil met je calls en goto's (even zo uit het hoofd, meen dat ik zoiets had zien staan in de 16F648A datasheet...)
Nope, de grens is 2K.
Kijk in het datasheet. Je kan het ook uit de instructiedecodering halen: 11 bits in de opcode zijn gereserveerd voor het adres.
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Er is vaak een misverstand over wat nu een geheugen 'page' is. Bij tabellen wordt soms een 256 byte geheugen blok als page gezien, wat eigenlijk niet juist is. Een page is 8k bytes oftewel 4k (14 bits)words.
Met tabellen en PCLATH is er een probleem als er in de tabel in de program counter een 'roll-over' plaats vindt van 0xFF naar 0x00 tussen de instructie aan het begin van de tabel, welke de program counter wijzigt (ADDWF PCL), en de eigenlijke return waarde in de tabbel.
In dat geval moet PCLATH worden aangepast, omdat anders de computed goto op een verkeerd adres uitkomt.
Bij overschrijden van een echte page (8/4k) komt er een extra probleem bij. Bij return van een goto/call moet dan de originele waarde van PCLATH worden hersteld, omdat anders problemen optreden bij volgende goto/calls in page 0
(In plaats van in page 0 zouden die dan in page 1 terecht komen...)
picsels
Volgend project: 7-seg gaming displays; dan dec-1982 labvoeding afmaken, dan funcgen met ad9833 afmaken, dan...
Op 27 maart 2007 23:08:47 schreef Arco:
Er is vaak een misverstand over wat nu een geheugen 'page' is. Bij tabellen wordt soms een 256 byte geheugen blok als page gezien, wat eigenlijk niet juist is. Een page is 8k bytes oftewel 4k (14 bits)words.Met tabellen en PCLATH is er een probleem als er in de tabel een 'roll-over' plaats vindt van 0xFF naar 0x00 tussen de instructie aan het begin van de tabel, welke de program counter wijzigt (ADDWF PCL), en de eigenlijke return waarde in de tabbel.
In dat geval moet PCLATH worden aangepast.
Bij overschrijden van een echte page (8/4k) komt er een extra probleem bij. Bij return van een goto/call moet dan de originele waarde van PCLATH worden hersteld, omdat anders problemen optreden bij volgende goto/calls in page 0
(In plaats van in page 0 zouden die dan in page 1 terecht komen...)
Inderdaad.
Dus samengevat (ik herhaal wat ik eerder al zei):
- blijf je onder de 4K code, heb je sowieso geen problemen met je goto's of calls.
- als je sprongtabel een 256-grens overschrijdt heb je een probleem; dus altijd controleren (via compiler-instructies) of je een grens overschrijdt
- bij springen door aanpassing van PCL (ADDWF PCL) eerst PCLATH goed vullen
dus in principe moet je compileren
en daarna telkens eens kijken in
mplab <>>vieuw>>program memory
en dan u tabel zoeken , e
en dan eventueel uw routines verschuiven
en ook dus uw pcl en pclacht mischien best opslaan in een ramlokatie als buffer , en als je tabel-routine is afgelopen ,
dan je oude pcl en pclatch weer inladen ?
ter info mijn tabel (let niet op de inhoud)
_____________________________
tabel
banksel PCL
addwf PCL,1
retlw 'z'
retlw 'o'
retlw 't'
retlw 't'
retlw 'e'
retlw 'k'
retlw 'o'
retlw 't'
retlw 'z'
retlw 'o'
retlw 't'
retlw '#'
return
_______________________
picsels
Volgend project: 7-seg gaming displays; dan dec-1982 labvoeding afmaken, dan funcgen met ad9833 afmaken, dan...
Of je definieert een macro en gebruikt die, tezamen met de compiler om het voor je te laten uitrekenen:
CHECK_BOUNDARY MACRO FROM
local TableEnd
TableEnd
IF HIGH(FROM) != HIGH(TableEnd)
ERROR ">>> Table/jump " FROM " crosses page boundry in computed addressing/jump"
ENDIF
ENDM
...
tabel
; banksel PCL -> niet nodig
; ... bewaar W ergens
; bijv: movwf TEMP_W
;
movlw HIGH(tabel)
movwf PCLATH
; ... haal W weer op
; bijv: movfw TEMP_W
;
addwf PCL,1
retlw 'z'
retlw 'o'
retlw 't'
retlw 't'
retlw 'e'
retlw 'k'
retlw 'o'
retlw 't'
retlw 'z'
retlw 'o'
retlw 't'
retlw '#'
return
CHECK_BOUNDARY tabel
Is makkelijker dan compileren en handmatig alle tabellen checken 
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
dus in principe moet je compileren en daarna telkens eens kijken in mplab <>>vieuw>>program memory
Nee, dat hoeft niet. Als je de code in example 5 in AN556 gebruikt, wordt automatisch de PCLATH oogehoogd als er een 'page crossing' is...
(Je hebt er dan geen omkijken meer naar...)
Nog wel een waarschuwing:
- Uiteraard nooit tabellen op adres 0x000 omdat dat de reset vector is
- Ook niet op adres 0x004, dit is de interrupt vector. Zet hier altijd een retfie instructie, ook als je geen interrupts gebruikt. Dit voorkomt vervelende en moeilijk op te sporen fouten als je (misschien per ongeluk) een interrupt inschakelt...
Op 27 maart 2007 23:08:47 schreef Arco:
Er is vaak een misverstand over wat nu een geheugen 'page' is. Bij tabellen wordt soms een 256 byte geheugen blok als page gezien, wat eigenlijk niet juist is. Een page is 8k bytes oftewel 4k (14 bits)words.
Vooruit, laat ik het nog maar een keer proberen:
De grens is 2K woorden.
Over bytes kan je eigenlijk niet spreken want de breedte is 14 bit (en niet 16). Dit is een gevolg van de Harvard architectuur. Maar aangezien gewoon de verkeerde info gegeven wordt en het naslaan van datasheets teveel werk is hier wat stukkies uit het PIC16F648 datasheet:
En ook bij de beschrijving van de goto staat het er nog een keer:
Met 11 bits kan je maar 2K adresseren!!!!!!
En als je nu de application note waar naar verwezen wordt (AN556) eens goed bestudeerd zie je daar het volgende:
Let met name op het stuk in het grijze kader 
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Is eenvoudig te doen , was makkelijker dan ik dacht , en je moet logsiche nadenken
de fouten die ik had waren onoplettendheden
zoals : mijn label 'tabel' stond een lijntje voor de org0X320
en ook moet je erop letten dat je dan de bankselctie goed zet vd pclatch
THX voor de nuttige info
ps: http://support2.microchip.com/KBSearch/KB_Ticket.aspx?ID=Tt6UJ9A0004X9
ps2 : mijn werkende asm
___________
laad
BANKSEL PCLATH
movlw HIGH tabel ;STAAT OP ORG0Xà320?HIGHERODERBYTE IS 03
movwf PCLATH
BANKSEL PORTB
movf aanwijzer,w ; 0e element ophalen
call tabel
;;;;;;;;;;;
ORG 0x0320
tabel
banksel PCL
addwf PCL,1
retlw 'z'
retlw 'o'
retlw 't'
retlw 't'
retlw 'e'
retlw 'k'
retlw 'o'
retlw 't'
retlw 'z'
retlw 'o'
retlw 't'
retlw '#'
return
____________________________
[Bericht gewijzigd door Extragroot op ]
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Wat betreft je 'werkende code':
Dit is alleen waar als je een vast adres gebruikt voor de tabel, en er geen 256 byte grens wordt overschreden.
(Als je bijvoorbeeld het tabel adres verandert in 0x1FF of 0x2FF, dan werkt het niet meer...)
Dit is meestal geen probleem als je nog genoeg ruimte vrij hebt in het programma geheugen. Als het wat voller wordt, dan wordt het vaak 'schuiven' met de tabel naar een vrij plaatsje. Hetzelfde geldt als de tabel langer wordt. Je moet dan uitkijken dat 'ie niet over de 256 byte grens heengaat...
Simpeler is het om zoals gezegd de code uit AN556 te gebruiken, zodat het niet uitmaakt waar de tabel ergens staat...
laad
movlw LOW tabel ;Laad tabel low address byte
addwf aanwijzer,w ;Add offset
movlw HIGH tabel ;
btfsc status,c ;Roll-over? (carry is set)
addlw 1 ;Ja, increment hi address byte
movwf PCLATH :Save hi byte in PCLATH
movf aanwijzer,w
call tabel
.
.
.
.
tabel
addwf PCL,f
retlw 'z'
retlw 'o'
retlw 't'
retlw 't'
retlw 'e'
retlw 'k'
retlw 'o'
retlw 't'
retlw 'z'
retlw 'o'
retlw 't'
retlw '#'
De RETURN aan het eind van de tabel heeft geen nut, deze kan weg. Evenals de BANKSEL voor PCL of PCLATH, omdat die in alle banks zijn gemapt...
[Edit]
Je kunt de tabel trouwens eenvoudiger schrijven:
tabel
addwf PCL,f
dt "zottekotzot#"
(is alleen korter en overzichtelijker, maakt in asm code geen verschil...)
[/edit]
