Crossing bank boundary zegt me nu nog steeds niets, maar de error is weg.
Harm,
Even een poging om dit probleem uit te leggen... ...Maar eerst wat PIC geheugen theorie:
Ik neem als voorbeeld een 16F88 (enkele pagina's terug heb ik gezien dat je daar mee werkt). Neem de datasheet (lap, daar gaat hij weer...) en in het hoofdstuk 'Register File Map' kan je zien dat het RAM geheugen (
random-access memory) verweven zit tussen de SFR's (Special Function Registers). SFR's die niet worden gebruikt, kunnen als RAM worden gebruikt.
In de begindagen van de PIC's was er niet veel RAM nodig en waren die SFR's ook vrij beperkt. Nieuwe types komen, meer SFR is nodig, meer RAM wordt ook noodzakelijk...
...Nieuwe SFR's en meer RAM betekent het volledige ontwerp van de controller hertekenen... Duur, heel duur en niet meer 'backwards compatible' met eerdere types (heel belangrijk!).
Oplossing? Heil zoeken in een reeds oude (en haar sporen verdiende) oplossing: uitbreiding van het geheugen (en SFR's) door parallel aan de bestaande SFR's en vrij geheugen nieuwe geheugenplaatsen te creëeren.
Voordeel? Je kan hetzelfde adresbereik blijven behouden. Nadeel? Eén geheugenadres kan/moet meerdere geheugenlocaties aanspreken. In welke geheugenlocatie je bezig bent hangt af van in welke geheugenbank je op dat moment aan het werken bent.
Je geheugenpointer verwijst naar je geheugenadres, één 'Special Function Register' bepaalt in welke geheugenbank je bezig bent. Heb je bvb een geheugenpointer die 128 plaatsen (plaats 0 tot plaats 127 = 2^7° = 128 bytes) kan aanspreken en je wil een totaal geheugen van 512 bytes (512 = 4 * 128 bytes = 2^9°). Je hebt dan je 7 adresbits en de resterende twee adresbits ga dus 'ergens' moeten halen. Oplossing: maak een 'Special Function Register' waar je die twee resterende adresbits in kwijt kan. Bij een 16F88 is dit bit RP0 en RP1 (SFR -> STATUS<6> en STATUS<5>).
Totdaar de theorie.
Wat is nu jou probleem: iedere vrije RAM plaats is slechts één byte (8 bits). Elke keer je een byte variabele declareert (en initialiseert), wijst je compiler die toe aan een nog vrije geheugenplaats (om het even in welke geheugenbank). Ga je een word-variabele (16 bits = 2 geheugenplaatsen) of een dword (32 bits = 4 geheugenplaatsen) creëren, gaat je compiler die voor zijn eigen gemak in opeenvolgende geheugenplaatsen zetten (opeenvolgende om nadien veel efficiënter met die groter wordende variabelen te kunnen rekenen).
Stel je hebt (zoals bij een 16F88) 128 geheugenplaatsen per bank en de eerst vrije plaats is adres 126. Je vraagt geheugen (declareren) voor een dword (32 bits = 4 * 8 bits = 4 bytes). Je eerste 2 bytes 'passen' nog in die bank en de andere twee moeten sowieso naar een andere bank en dan krijg je het 'Crossing bank boundary' error.
Moet je daar rekening mee houden? Neen! De compiler moet dat doen. Als die ziet dat je slechts 2 bytes meer over hebt op het einde van je bank en je wil er vier voor een variabele, moet hij die in een andere bank steken en die 2 resterende van de vorige bank markeren als 'vrij voor 2 bytes'. Blijkbaar doet jou compiler dat niet (...)!
Moet je daar rekening mee houden? Ja! Als je net als Geert in assembler werkt en als je hersenen dienst doen als compiler. Het grote voordeel is dan dat je alles in de hand hebt, het grote nadeel is dan dat je je datasheet binnenste buiten moet kennen en dat je iedere stap van je controller moet binnenste buiten kennen!
Ik hoop dat mijn uitleg te begrijpen valt...