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