If you need assistance, please send an email to forum at 4hv dot org. To ensure your email is not marked as spam, please include the phrase "4hv help" in the subject line. You can also find assistance via IRC, at irc.shadowworld.net, room #hvcomm.
Support 4hv.org!
Donate:
4hv.org is hosted on a dedicated server. Unfortunately, this server costs and we rely on the help of site members to keep 4hv.org running. Please consider donating. We will place your name on the thanks list and you'll be helping to keep 4hv.org alive and free for everyone. Members whose names appear in red bold have donated recently. Green bold denotes those who have recently donated to keep the server carbon neutral.
Special Thanks To:
Aaron Holmes
Aaron Wheeler
Adam Horden
Alan Scrimgeour
Andre
Andrew Haynes
Anonymous000
asabase
Austin Weil
barney
Barry
Bert Hickman
Bill Kukowski
Blitzorn
Brandon Paradelas
Bruce Bowling
BubeeMike
Byong Park
Cesiumsponge
Chris F.
Chris Hooper
Corey Worthington
Derek Woodroffe
Dalus
Dan Strother
Daniel Davis
Daniel Uhrenholt
datasheetarchive
Dave Billington
Dave Marshall
David F.
Dennis Rogers
drelectrix
Dr. John Gudenas
Dr. Spark
E.TexasTesla
eastvoltresearch
Eirik Taylor
Erik Dyakov
Erlend^SE
Finn Hammer
Firebug24k
GalliumMan
Gary Peterson
George Slade
GhostNull
Gordon Mcknight
Graham Armitage
Grant
GreySoul
Henry H
IamSmooth
In memory of Leo Powning
Jacob Cash
James Howells
James Pawson
Jeff Greenfield
Jeff Thomas
Jesse Frost
Jim Mitchell
jlr134
Joe Mastroianni
John Forcina
John Oberg
John Willcutt
Jon Newcomb
klugesmith
Leslie Wright
Lutz Hoffman
Mads Barnkob
Martin King
Mats Karlsson
Matt Gibson
Matthew Guidry
mbd
Michael D'Angelo
Mikkel
mileswaldron
mister_rf
Neil Foster
Nick de Smith
Nick Soroka
nicklenorp
Nik
Norman Stanley
Patrick Coleman
Paul Brodie
Paul Jordan
Paul Montgomery
Ped
Peter Krogen
Peter Terren
PhilGood
Richard Feldman
Robert Bush
Royce Bailey
Scott Fusare
Scott Newman
smiffy
Stella
Steven Busic
Steve Conner
Steve Jones
Steve Ward
Sulaiman
Thomas Coyle
Thomas A. Wallace
Thomas W
Timo
Torch
Ulf Jonsson
vasil
Vaxian
vladi mazzilli
wastehl
Weston
William Kim
William N.
William Stehl
Wesley Venis
The aforementioned have contributed financially to the continuing triumph of 4hv.org. They are deserving of my most heartfelt thanks.
Registered Member #295
Joined: Tue Mar 07 2006, 06:59PM
Location:
Posts: 23
i'm debugging a large lookup table based program and it has been brought to my attention that if my program if longer than the 8-bits contained in the program counter (PCL), a simple "addwf PCL" type lookup table may not function correctly in all cases, and it has somthing to do with pages (which i assume are simply higher order bits of the PCL). i would be greatful if someone would help me understand this concept.
the lookup tables i am reffering to are of this form
Registered Member #27
Joined: Fri Feb 03 2006, 02:20AM
Location: Hyperborea
Posts: 2058
Yes, the most significant 8 bit of the program counter is held in a separate latch called PCLATH, when you update PCL it automatically reads PCLATH at the same time so it is safe to update PCLATH first since it will not affect the program counter.
So if your table crosses a 256 byte page boundary or if you don't know if it does then you need code like this to calculate the value for PCLATH:
;**** Look up 7 segment data in the table and output it to the display
movwf offset7seg
movlw LOW ledLUT ;Get low 8 bits of address
addwf offset7seg ;Do an 8-bit add operation
movlw HIGH ledLUT ;Get high 5 bits of address
btfsc STATUS,C ;Page crossed?
addlw .1 ;Yes then increment high address
movwf PCLATH ;Load high address in latch
movf offset7seg,W ;Load computed offset in w reg
ledLUT addwf pcl, 1
retlw 'data'
retlw 'data'
Registered Member #295
Joined: Tue Mar 07 2006, 06:59PM
Location:
Posts: 23
thank you for the code snippet, i think iunderstand the instructions, let me insure my assumptions are correct. offset7seg is just the (address-1) of the first entry in LUT. it would also make sense that LOW ledLUT, and HIGH ledLUT are, combined, the adress of the entry in the LUT (1 being the first entry). am i on the right path so far? anywayz, my question is how do i go about determining the addresses, should i just count the lines starting from the org? can MPLAB help me with this?
Registered Member #27
Joined: Fri Feb 03 2006, 02:20AM
Location: Hyperborea
Posts: 2058
You are on the right track.
offset7seg is the offset into the table, 0 points to the first data item. ledLUT marks the start of the table, it is at the addwf pcl instruction instead of the first data item because the PC automatically increments by 1, so if offset7seg = 0 then you will have the first item returned when the instruction after the add is run.
LOW ledLUT returns the 8 least significant bits of the address of the table, HIGH ledLUT returns the most significant byte, so all is atomatic, no counting needed. Remember that labels are 16 bit constants calculated at assembly time, HIGH and LOW are just assembler directives.
Remember that this code must be entered by using a CALL instruction or the table would not know where to return to. Just load it in a simulator and single step through it, that should make everything clear.
Also using instruction of this type "addwf pcl, 1" is not very intuitive. "addwf pcl" is the form that was originally though of by the designer before Microchip started messing with it.
Registered Member #295
Joined: Tue Mar 07 2006, 06:59PM
Location:
Posts: 23
very cool, i had no idea that "high" and "low" were compiler directives. i assume they work in combination with any operand that would normally have a label as a parameter. i also didn't realize that i could use lables as literal values (without explicitly declaring them using "equ").
i have never used the MPLAB simulator before, but i'll check it out, looks as if it might become an indispensable tool.
one more question, can i use the call instruction to call functions from pages other than the one the "call" instruction is located in. and does "lcall" have the same effect as call (i'm thinking obsolete instruction)?
Registered Member #27
Joined: Fri Feb 03 2006, 02:20AM
Location: Hyperborea
Posts: 2058
Yes, you can use the HIGH and LOW directives everywhere you have constants. It is very useful for example when you calculate constants at assembly time.
The datasheet for 16F870 says that the call instruction uses 11 bits for the address so it will reach 2048 instructions or 8 pages. If you need to reach longer you need to use macros like lcall or manually update PCLATH. Remember that different PICS are slightly different so read the datasheet for your exact model.
I have figured out how to make a 16 bit optimizing FORTH compiler using only assembler directives but I have not bothered to make it yet. So the assembler is pretty powerful when you manage to figure out how everything works.
This site is powered by e107, which is released under the GNU GPL License. All work on this site, except where otherwise noted, is licensed under a Creative Commons Attribution-ShareAlike 2.5 License. By submitting any information to this site, you agree that anything submitted will be so licensed. Please read our Disclaimer and Policies page for information on your rights and responsibilities regarding this site.