Ik ben bezig met een stukje PICcode waarin een lookuptable verwerkt zit. Het is echter niet zo gemakkelijk als ik aanvankelijk dacht aangezien de tabel meer dan 400bytes bevat. Ik gebruik een 16F877a.
De lookuptable zal later overigens zo'n 800bytes gaan bevatten en misschien zelfs nog wel meer.
(Ja, dat wordt een leuk invoer-werkje...)
Een tweede lookuptable van zo'n 1000bytes zal er ook nog bijkomen.
De maincode neemt praktisch geen geheugen in, dus de lookuptable moet makkelijk in het geheugen passen.
Ik wil het programma nu in page 0 van het geheugen schrijven en de lookuptable in page 1.
De reden is dat ik dan zeker weet dat mijn lookuptable max 2048 waardes kan bevatten.
(de toekomstige 2e lookuptabel wil ik in page 2 schrijven)
Hoe pak ik dit nu aan? Na verschillende samplecodes te hebben bekeken kom ik er niet uit hoe je die pageselect nu toepast. De directive "PAGESEL" is van belang, zover ben ik. Maar hoe gaat dit nu in combinatie met PCL en PCLATH?
EDIT//
Ik zal de 16bit geheugenlokatie naar de PC moeten schrijven. Het probleem zit 'm er in dat je dat in twee stappen moet doen. Als ik eerst PCLATH update springt de PC toch al naar een andere lokatie, voordat ik de PCL kan updaten?
[Bericht gewijzigd door DIY op ]
Fuzzbass
Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com
Nee, PCLATH wordt pas gelatched bij het "handmatig" wijzigen van de program counter.
De 877 kan lezen en schrijven in zijn eigen programmageheugen. Misschien kun je hier gebruik van maken, in plaats van (zoals dat gewoon is bij PICs) met de program counter te sjoemelen - iets waarvoor ik microchip altijd al vervloekt heb.
[Bericht gewijzigd door Fuzzbass op ]
Op 4 oktober 2004 12:36:43 schreef Fuzzbass:
Nee, PCLATH wordt pas gelatched bij het "handmatig" wijzigen van de program counter.
Dit ontdekte ik ook net, maar dank je wel.
Op 4 oktober 2004 12:36:43 schreef Fuzzbass:
De 877 kan lezen en schrijven in zijn eigen programmageheugen. Misschien kun je hier gebruik van maken, in plaats van (zoals dat gewoon is bij PICs) met de program counter te sjoemelen - iets waarvoor ik microchip altijd al vervloekt heb.
Dit snap ik niet helemaal. Ik wil inderdaad gebruik maken van het lezen uit programmageheugen aan de hand van de lookuptable.
Hiervoor zul je toch moeten 'sjoemelen' met de PC?
Ik gebruik immers de retlw instructie.
Aangezien ik dus een gedefinieerd 2k-blok wil gebruiken voor de lookuptabel (en toekomstig dus 2 van die tabels en dus 2 van die blokken), wil ik in control zijn van de pageselect.
Is dit misschien simpel op te lossen door de PCL en PCLATH een offset van 2k mee te geven?
Of zie ik dan toch nog iets over het hoofd?
Fuzzbass
Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com
Kijk ff in de datasheet van de PIC16F877 sectie 4.5, dan wordt alles hopelijk duidelijk. Het uitlezen van het flashgeheugen gaat op vrijwel de zelfde manier (en via de zelfde registers) als het EEPROM.
Op 4 oktober 2004 15:08:13 schreef Fuzzbass:
Kijk ff in de datasheet van de PIC16F877 sectie 4.5, dan wordt alles hopelijk duidelijk.
Hmmm..dit handelt over I/O. Ik denk dat ik je verkeerd begrijp?
Ik heb zojuist een truc met het org-statement uitgehaald en dat lijkt te lukken. Hiermee kan ik in ieder geval de retlw instructies een offset in het programmageheugen geven.
Moet er vandoor, dus ga vanavond weer verder.
Fuzzbass
Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com
Zie het nu ja. Het is de datasheet van de F877, en ik gebruik de 877a. De datasheets zijn onderling anders ingedeeld. Ga het nu even bekijken.
EDIT//
Is het nog gelukt met je dubbele seriele interface?
[Bericht gewijzigd door DIY op ]
@Fuzzbass
Ik denk dat je niet helemaal goed begrepen hebt waar ik naar toe wil. Niet erg, kan ook aan mijn omschrijving van het probleem liggen.
Ik wil, kort door de bocht gezegd, een lookuptable gebruiken, die zo'n 400 values kent en die vooraf hard geprogrammeerd wordt.
Na met verschillende projectfiles van microchip te hebben gewerkt ben ik verschillende keren de directive 'pagesel' tegen gekomen. Ik ging er van uit dat ik dat nodig zou hebben omdat ik de lookuptable in page 2 wil zetten.
Ik heb voor mijn projectje dus ook een 'project' gecreeerd in mplab, bestaande uit 2 ASM-files. Hier kom ik uiteindelijk niet uit omdat dit toch wel wat vraagt van de MPASM-taal (incl de directives).
Goed, zoals ik al eerder zei lijkt het te lukken door toch terug uit te gaan van 1 asm-file, waarin het ORG-statement 3x voorkomt. 1x voor m'n main code, 1x voor ISR en 1x voor de lookuptable.
Ik moet nu die nieuwe manier eens goed gaan testen of dit werkt.
De sektie 4.5 heeft eerder zin als ik die lookuptable on the flow wil wijzigen. Ik dank je dus hartelijk voor deze tip, want dit kan in toekomstige versies wel eens van pas gaan komen. Nu dus nog niet, ik wil nu een hardgecodeerde tabel gebruiken.
Fuzzbass
Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com
Op 4 oktober 2004 18:05:17 schreef DIY:
Ik denk dat je niet helemaal goed begrepen hebt waar ik naar toe wil. Niet erg, kan ook aan mijn omschrijving van het probleem liggen.
Ik wil, kort door de bocht gezegd, een lookuptable gebruiken, die zo'n 400 values kent en die vooraf hard geprogrammeerd wordt.
Hmm, dat kan met het direct uitlezen van het flash-geheugen ook, hoor. Je kunt dan zelfs 14-bit waarden opslaan (=2x7 bits, handig om ASCII op te slaan)
Na met verschillende projectfiles van microchip te hebben gewerkt ben ik verschillende keren de directive 'pagesel' tegen gekomen. Ik ging er van uit dat ik dat nodig zou hebben omdat ik de lookuptable in page 2 wil zetten.
Gaat pagesel niet over het springen van executable code naar een ander 2K-blok?
Ik heb voor mijn projectje dus ook een 'project' gecreeerd in mplab, bestaande uit 2 ASM-files. Hier kom ik uiteindelijk niet uit omdat dit toch wel wat vraagt van de MPASM-taal (incl de directives).
Ik volg je niet. Een gemiddeld project in assembler van mij bestaat uit 6-10 files. Zo hou ik het overzichtelijk.
Goed, zoals ik al eerder zei lijkt het te lukken door toch terug uit te gaan van 1 asm-file, waarin het ORG-statement 3x voorkomt. 1x voor m'n main code, 1x voor ISR en 1x voor de lookuptable.
Lijkt me erg verstandig, zo doe ik dat ook meestal.
Ik moet nu die nieuwe manier eens goed gaan testen of dit werkt.
De sektie 4.5 heeft eerder zin als ik die lookuptable on the flow wil wijzigen. Ik dank je dus hartelijk voor deze tip, want dit kan in toekomstige versies wel eens van pas gaan komen. Nu dus nog niet, ik wil nu een hardgecodeerde tabel gebruiken.
Je hoeft toch niets aan de lookup table te wijzigen om hem te kunnen lezen. In mijn ervaring is het direct lezen van het flashgeheugen eenvoudiger dan de program counter te wijzigen. Als je namelijk een piepklein foutje hierin maakt, crasht heel je programma, omdat het naar een niet-gedefinieerd adres springt.
PS. die tweede seriële poort ga ik met software oplossen (zgn. bit-banging).
Zinnige info. Veel dank hiervoor.
Ik ga er mee verder, en zal de optie van direct flashgeheugen lezen toch opnieuw 'in consideratie' nemen.
Wat betreft het aanmaken van een project met meerdere files: Dit wil ik al heel lang doen, aangezien ik hier codes heb liggen waar je helemaal tureluurs van wordt als je even een stukje subroutine aan het zoeken bent.
Het gaat mis zodra ik een tweede asm toevoeg waar variabelen in voorkomen die ook in de eerste asm voorkomen. Het zijn globale variabelen, dus het zou goed moeten gaan, maar op 1 of andere manier vindt de compiler het niet goed wat ik doe.
Zou je mij in twee of drie zinnen kunnen vertellen wat je hier nu eigenlijk voor moet doen?
Turbokeu
Golden Member
I love watching conspiracy theorists use the airtight logic of the argument from incredulity: "Well I don't understand how it works so it can't be real!!!"
Op 4 oktober 2004 12:04:08 schreef DIY:
Hoe pak ik dit nu aan? Na verschillende samplecodes te hebben bekeken kom ik er niet uit hoe je die pageselect nu toepast. De directive "PAGESEL" is van belang, zover ben ik. Maar hoe gaat dit nu in combinatie met PCL en PCLATH?
Zie ook mijn post hier.
Misschien niet de beste verklaring, maar het werkt in IEDER geval...(ik gebruikte ook grote lookup-tables (512bytes) en RETLW )
CD 
Fuzzbass
Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com
Ik maak geen gebruik van MPLAB. Ik heb 1 hoofdlisting met een .asm extensie en van daaruit "include" ik de andere files, met extensie .inc. Het wordt zo in feite 1 assemblerlisting. Ik hou 1 file bij waarin alle variabelen staan, zodat ik geen dubbele heb. Ik gebruik geen locale variabelen, behalve in macro's (die weer in een aparte .inc staan).
De files bewerk ik in Textpad, en als er ge"build" moet worden laat ik het MPASM doen, met de eigen interface van MPASM.
Voordat anderen gaan roepen: "het kan veel universeler" wil ik even aantekenen dat dit voor mij goed werkt. Ik maak geen gebruik van libraries. Als ik een routine nodig heb die ergens anders vandaan komt, dan bewerk ik die zodanig dat het allemaal weer in één listing past. Met de hoeveelheid programmacode in een gemiddelde PIC is dat allemaal best te overzien.
Het klinkt misschien raar, maar ik maak (of bewerk) ook mijn eigen header files, zodat ik niet hoef te onthouden in welk register de afzonderlijke bits zitten. De bitnaam is voldoende, dus in mijn code zul je bijv. BTFSC Z zien staan. Z is gedefinieerd met #define Z STATUS,2
stukje uit zo'n header:
INDF EQU H'0000'
TMR0 EQU H'0001'
PCL EQU H'0002'
STATUS EQU H'0003'
FSR EQU H'0004'
...
;----- STATUS Bits --------------------------------------------------------
#define IRP STATUS,7
#define RP1 STATUS,6
#define RP0 STATUS,5
#define NOT_TO STATUS,4
#define NOT_PD STATUS,3
#define Z STATUS,2
#define DC STATUS,1
#define C STATUS,0
;----- INTCON Bits --------------------------------------------------------
#define GIE INTCON,7
#define PEIE INTCON,6
#define TMR0IE INTCON,5
#define INTE INTCON,4
#define RBIE INTCON,3
#define TMR0IF INTCON,2
#define INTF INTCON,1
#define RBIF INTCON,0
;----- PIR1 Bits ----------------------------------------------------------
#define ADIF PIR1,6
#define RCIF PIR1,5
#define TXIF PIR1,4
#define SSPIF PIR1,3
#define CCP1IF PIR1,2
#define TMR2IF PIR1,1
#define TMR1IF PIR1,0
Veel werk, maar voor elke PIC hoeft dit maar 1 keer, en je kunt een hoop knippen&plakken.
Okey..ik denk dat het er aan ligt dat ik ze niet .INC heb genoemd..Ga effe proberen.
Dank je!
Die headerfiles waar je het over hebt..die zitten toch gewoon in een folder van MPLAB? Ik neem toch aan dat je die niet allemaal met de hand gemaakt hebt?
Fuzzbass
Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com
Op 4 oktober 2004 22:58:54 schreef DIY:
Die headerfiles waar je het over hebt..die zitten toch gewoon in een folder van MPLAB? Ik neem toch aan dat je die niet allemaal met de hand gemaakt hebt?
De originelen van MPLAB zijn een uitgangspunt, van waaruit ik m'n eigen headerfiles knip/plak/etc.
Ik vond het op een bepaald moment nogal veel werk worden om elke keer te moeten opzoeken in welk register bepaalde bits zaten. Als je dan ook nog eens door elkaar met F84s F628s, F88s, F876s, F452s en F1320s werkt, is de chaos compleet 
Op 4 oktober 2004 18:05:17 schreef DIY:
Goed, zoals ik al eerder zei lijkt het te lukken door toch terug uit te gaan van 1 asm-file, waarin het ORG-statement 3x voorkomt. 1x voor m'n main code, 1x voor ISR en 1x voor de lookuptable.
Zou je kunnen uitleggen hoe je dat precies doet? Hoe bepaal je waar je je lookup-table laat beginnen, en hoe zorg je er voor dat de rest van de code dat niet in de weg zit?
Fuzzbass
Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com
Op 5 oktober 2004 07:43:55 schreef Fub:
[...]
Zou je kunnen uitleggen hoe je dat precies doet? Hoe bepaal je waar je je lookup-table laat beginnen, en hoe zorg je er voor dat de rest van de code dat niet in de weg zit?
Als je bijv. ORG ((high $)+1)*H'0100' gebruikt, dan begint het volgende statement op de nul-byte van de eerstvolgende pagina van 256 bytes. Door een relatief (berekend) adres te gebruiken, zit de code elkaar niet in de weg. Maar je moet wel genoeg geheugen hebben om dit te doen, natuurlijk.
Op 5 oktober 2004 10:30:17 schreef Fuzzbass:
Door een relatief (berekend) adres te gebruiken, zit de code elkaar niet in de weg. Maar je moet wel genoeg geheugen hebben om dit te doen, natuurlijk.
Moet je ORG-statements eigenlijk op volgorde van geheugenlocatie gebruiken? Of kan je ook nog 'terug'?
En hoe zorg je er voor dat je niet hele stukken geheugen niet gebruikt? Statements tellen?
Fuzzbass
Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com
Lees de help file van MPASM eens over de ORG directive. Het is heel simpel. Het is gewoon om aan te geven op welke geheugenlocatie de navolgende instructies moeten komen te staan. Gewoonlijk begin je op H'0000', omdat dat de reset vector is, maar als je wil kan je ook een deel code op H'1F00' zetten, als je bijvoorbeeld een bootloader maakt, die de rest van het geheugen nog moet volschrijven.
Op 4 oktober 2004 22:58:54 schreef DIY:
Okey..ik denk dat het er aan ligt dat ik ze niet .INC heb genoemd..Ga effe proberen.
Nou, geprobeerd heb ik het, maar lukken ho maar..
Ik doe dus iets fout...
Wat heb ik gedaan?
1)een asm-file als maincode (sourcefile)
2)3 inc-files waar subroutines inzitten (headerfiles)
3)3 include statements in de asm-file gezet
Wat gaat er mis?
Ik compileer het project en krijg meteen deze melding:
I/O-error: File not open for input
Klik op OK en dan regent het foutmeldingen:
1)Superceding current maximum RAM and RAM map
2)Include files nested too deep
3)Symbol not previously defined (variabelen die gedeclareerd worden in de ASMfile en gebruikt worden in de INCfile)
4)Overwriting previous address contents
Ik hoop dat Fuzzbass hieruit kan concluderen wat ik fout doe...Ik wil het zo graag weten...
EDIT//
Door in de inc-files een include main.asm toe te voegen vervalt de I/O-error, maar de regen van andere foutmeldingen blijft komen.
[Bericht gewijzigd door DIY op ]
Fuzzbass
Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com
Ik zal een poging wagen, van wat ik denk dat de oorzaak zou kunnen zijn van de foutmeldingen, ik hoop dat het helpt. In volgorde
1) Je hebt teveel ramregisters gedefinieerd of ze staan niet op de juiste locatie (vanaf 0020h) of je gebuikt een verkeerde directive om ze te definieren (CBLOCK...ENDC of EQU)
2) ASM en INC files verwijzen naar elkaar
3) In de ASM gebruik je locale variabelen en de INC verwacht globale
4) in één of meer INC files staat een ORG directive, die een conflict oplevert met de ASM file
het formaat voor includes is:
include <PINS.INC> ;pinout
include <VARIABLE.INC> ;ram registers
include <MACRO.INC> ;macros
RAM registers definieer je zo:
cblock H'0070'
flags_1 ;flag register 1
flags_2 ;flag register 2
a_temp ;temp for main
b_temp ;temp for main
c_temp ;temp for main
d_temp ;temp for main
s_temp ;STATUS temp
w_temp ;W temp
f_temp ;FSR temp
x_temp ;temp for irq
y_temp ;temp for irq
endc
Dank je voor deze toelichting. Ik ga weer verder prutsen..het moet en zal me lukken!
(ook al lijkt het een total rewrite te worden..)
Goed, het wordt dus inderdaad een total rewrite aangezien de code warrig wordt als ik de program counter manipuleer.
Dus Fuzzbass, dank voor de tip over Flashmemory read/write. Ben nu bezig met de code om te schrijven naar dit idee.
Wat me echter nog steeds niet gelukt is om het project op te bouwen met verschillende INC-files.
Ik ben ondertussen dusdanig ver gekomen dat ik alle foutmeldingen heb kunnen elimineren op 1 na:
<<Overwriting previous address contents>>
Deze melding komt zodra de ASM-file wordt 'ge-execute'.
De inc-files zijn al voorbij gekomen en de ASM-file wil dus alle adressen gaan overschrijven...
Hoe los ik dit laatste probleem op?
EDIT/1
Ik heb alleen ORG-statements in de asm-file staan en dan nog wel de 'standaard'-ORGs (0x000 en 0x004).
EDIT//2
Ik geloof dat ik weet wat er aan de hand is. De INC-files kunnen (voor zover ik nu begrijp) alleen gebruikt worden voor het definieren van variabelen (CBLOCK ENDC en EQU) en macro's (MACRO ENDM).
Als dit zo is, houdt het op. Ik wil namelijk subroutines in die losse bestanden zetten en die kun je niet omschrijven naar een MACRO...
Na een hoop MPASM en MPLAB documentatie te hebben gelezen en wederom bestaande projecten met multiple asm-files te hebben bekeken komt het er volgens mij op neer dat ik de linker moet gebruiken. Mijn god...er gaat een wereld voor me open, en die is heel donker...
Iemand ervaring met de linker?
EDIT///3
Ik ben een nieuwe thread over dit onderwerp begonnen aangezien bovenstaande topictitel niet meer klopt met het onderwerp.
[Bericht gewijzigd door DIY op ]