Help with array of addresses
mynet43
Posts: 644
I'm using an array of addresses to produce data driven code.
I ran across something I don't understand.
I have eight strings defined in my DAT block. To access these in the code, I've defined an array of addresses to these strings.
When I access these addresses using an index, such as "calib_string_top", I find that the address pointed to in the array is wrong.
In order to make it work right, I have to add 16 to each of the addresses in the array. Once I do this, the code works fine.
Can someone please help me understand why I have to add 16 to the addresses in the array.
Thank you for your help.
Jim
Here's a sample of the code I'm using:
I ran across something I don't understand.
I have eight strings defined in my DAT block. To access these in the code, I've defined an array of addresses to these strings.
When I access these addresses using an index, such as "calib_string_top", I find that the address pointed to in the array is wrong.
In order to make it work right, I have to add 16 to each of the addresses in the array. Once I do this, the code works fine.
Can someone please help me understand why I have to add 16 to the addresses in the array.
Thank you for your help.
Jim
Here's a sample of the code I'm using:
CON
' *****NHD standard display 4x20 character LCD***** '
' CRYSTAL SETUP 80MHz
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
' DATA PINS FOR DISPLAY
D0 = 8
D1 = 9
D2 = 10
D3 = 11
D4 = 12
D5 = 13
D6 = 14
D7 = 15
' CONTROL PINS FOR DISPLAY
RS = 16
RW = 17
EN = 18
' POWER FOR PROCESSOR
LATCH = 22 ' supply for power to screen and LED
PWR = 23
' OUTPUT FROM 16 TO 4 ENCODER
A0 = 24
A1 = 25
A2 = 26
A3 = 27
' PARAMETERS
screen_timeout = 1 ' time after switch is off before screen turns off
debug = 1 ' debug on = display on serial terminal
connected = 1 ' 1 if connected to main board, 0 if using debug terminal = eliminates waiting for ack
action_timeout = 20 ' time before action failed to finish
VAR
byte ack_back[64] ' buffer for ack when coming back from light board
byte light_flag ' light is on or off
byte pwr_flag ' power is on or off
byte calib_mode ' calib mode status flag
byte clear_flag ' clear screen flag
long gs_index ' index used for getstr
OBJ
DAT
Version byte "1.0", 0
ack byte "ack", 0 ' look for 'ack' from main control board
nak byte "nak", 0 ' if nak, command failed to send
fin byte "fin", 0 ' action has finished
entr byte "I" ' enter
cal byte "J" ' calibration
ext_cal byte "K"
ret_cal byte "L"
center_cal byte "M"
STOP byte "S" ' light stopped moving. also means no switch was pressed
' KEYS FOR BUTTON FLAGS
pwr_btn long 0
lgt_btn long 1
ret_btn long 2
ext_btn long 3
cal_btn long 4
entr_btn long 5
' DISPLAY INITIALIZATION
init_cmd long %0011_0000, %0011_0000, %0011_0000, %0011_1000, %0000_1000, %0000_0001, %0000_0110, %0000_1100, %1000_0000, 0
' DEBOUNCE FLAGS FOR BUTTONS
btn_flags long 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
' CALIBRATION DATA
calib_data long 0, 0, 0, 0
calib_send long @ext_cal, @ret_cal, 0, @center_cal
calib_steps long 4 ' number of steps in the calibration process
calib_string_top long @calib1_top + 16, @calib2_top + 16, @calib3_top + 16, @calib4_top + 16
calib_string_bot long @calib1_bot + 16, @calib2_bot + 16, @calib3_bot + 16, @calib4_bot + 16
calib1_top byte "Extend light", 0
calib1_bot byte "to 120 degrees", 0
calib2_top byte "Retract light", 0
calib2_bot byte "to 0 degrees", 0
calib3_top byte "Extend light", 0
calib3_bot byte "to 90 degrees", 0
calib4_top byte "Rotate light", 0
calib4_bot byte "To center", 0
PUB calib_start | i
calib_mode := 1 ' tell main board you're calibrating
clear(0)
repeat i from 0 to calib_steps - 1
stringdraw(2, 0, calib_string_top[i])
stringdraw(3, 0, calib_string_bot[i])
stringdraw(4, 0, string("Enter when done."))
' wait while user calibrates
repeat until btn_flags[entr_btn] ' wait for button press
check_switches
repeat until not btn_flags[entr_btn] ' wait for button release
check_switches
if i <> 2 ' don't care about third step data
send_usb_data(calib_send[i])
calib_mode := 0 ' set back to manual mode before leaving calibration
PRI check_switches | input, i
input~ ' initialize input low
input := ina[A0..A3] ' number of the pressed button
return input ' return hex number displaying which button was pressed
PRI clear(line) ' clear line on display screen
PRI send_usb_data(d) | jdata, temp ' send data to usb
PRI stringdraw(line, offset, text) | cmd
case line ' pick correct line, starting address for each line
1: cmd := $80 ' line 1
2: cmd := $C0 ' line 2
3: cmd := $94 ' line 3
4: cmd := $D4 ' line 4
cmd += offset ' add offset to get true starting position
writecmd(cmd)
writedata(text) ' display text
PRI writecmd(cmd) ' send out a command by toggling EN signal
outa[RS]~ ' RS low for command
outa[D7..D0] := cmd
!outa[EN]
waitcnt(clkfreq/1000 + cnt)
!outa[EN]
outa[RS]~~
PRI writedata(data) | jdata ' send data by toggling EN signal
outa[RS]~~
repeat while (jdata := byte[data++]) <> 0
outa[D7..D0] := jdata
!outa[EN]
waitcnt(clkfreq/1000 + cnt)
!outa[EN]

Comments
As that is done below.
calib_string_top long @calib1_top + 16, @calib2_top + 16, @calib3_top + 16, @calib4_top + 16
calib_string_bot long @calib1_bot + 16, @calib2_bot + 16, @calib3_bot + 16, @calib4_bot + 16
calib1_top byte "Extend light", 0
But there is a special operator: @@ which adds the object offset. See Propeller Manual page 173 (the example is exactly what you do).
Andy
Perfect explanation Andy. Now I fully understand it.
Jim