Shop OBEX P1 Docs P2 Docs Learn Events
Going crazy, can't pass a word variable to a sub routine — Parallax Forums

Going crazy, can't pass a word variable to a sub routine

Capt. QuirkCapt. Quirk Posts: 872
edited 2007-03-17 02:23 in General Discussion
The sub "LCD_5_Digit_Value·SUB·2, 3" will not pass·the first Word value "rpm", but it does pass the Byte value "ADD1"

I am pretty·certain the top of the sub·is wrong, but I have changed it many times and been unable to correct it. Included a .lst code snipet.
The sub has been tested many times with a Static Value, but when I added it to the LCD routine it won't work. But I am sure it would if the sub recieved the data.


Thanks

Comments

  • Sparks-R-FunSparks-R-Fun Posts: 388
    edited 2007-03-16 17:29
    Capt. Quirk,

    I suspect that your rps variable ought to be a WORD variable. I have encountered similar situations where SX/B math operations preformed with a mix of WORD and BYTE variables did not produce the expected results.

    Also... I noticed that you have a LOT of pauses in your program. Maybe you put them there to help see what is going on or to be extra-cautious with your timing. That is fine. What happens, though, is that each use of the 'Pause' statement gets replaced with several lines of assembly instructions when the program is compiled. (For more information see JonnyMac's comments in this thread.)

    To see what a difference this can make, compile your program as usual, then go to Run | Device and scroll the E2FLASH window all the way down to the bottom. Then slowly start scrolling the window back up to the top noting the relative amount of 'FF' entries. The 'FF' entries indicate the free space remaining in your program memory. Then replace all of your 'Pause' statements with a call to a subroutine with 'Pause' in it just once, such as JonnyMac's DELAY_MS subroutine reference above. I think you will be amazed by the program size difference!

    I hope this helps.

    - Sparks
  • JonnyMacJonnyMac Posts: 9,214
    edited 2007-03-16 22:25
    Your code (SUB declaration) can take a byte value but is not handling it -- here's how you can fix that:

    LCD_5_Digit_Value:
      IF __PARAMCNT = 3 then
        tmpW1 = __WPARAM12
        tmpB1 = __PARAM3
      ELSE
        tmpW1 = __PARAM1
        tmpB1 = __PARAM2
      ENDIF
    



    Now you can pass your first parameter as a word or byte. Just a note: if that second parameter is the address of where to write the string you have to use tmpB1; you code is currently doing this:

    LCD_ADDRESS tmpB3
    



    It doesn't look like tmpB3 is being set before the call to the subroutine.

    Post Edited (JonnyMac) : 3/16/2007 10:36:19 PM GMT
  • Capt. QuirkCapt. Quirk Posts: 872
    edited 2007-03-17 00:47
    It doesn't look like tmpB3 is being set before the call to the subroutine. said...
    Yea, Every time I call a subroutine from "LCD_5_Digit_Value" it returns·tmpW1 as a byte value. So I tried moving LCD_ADDRESS·one line before calling··LCD_5_Digit_Value in the main program loop and that didn't work either. Then I moved it above the COUNT line and it worked fine.

    Then I uncomented my "LCDOUT idx" lines, so I could display the values and as soon as it returns from the first "LCDOUT", tmpW1 is modified to a byte again.

    Bean helped me out with this earlier and gave me this snipet, But never got it to work. Last week I trimed it down and it worked fine within testing
    of the SX-Key debug. But as soon as I added to the program, I started having problems.

    Now I think I see why Bean had this at the bottom of the program? There are some parts of this routine that are still beyond my ability. Is it necessary to use the "GOSUB" within a Subroutine?

    I am posting a cleaner version of my program and the cut down version of Bean's snipet

    Thanks everybody
    · digits(4) = digits(4) + value_LSB
    · ' Blank leading zeros
    · idx = 0
    · DO WHILE idx < 4
    ··· IF digits(idx) = "0" THEN······· ' IF digit is Zero...
    ····· digits(idx) = " "············· '·· make it Blank
    ··· ELSE
    ····· idx = 4······················· ' Set counter to done value
    ··· ENDIF
    ··· INC idx
    · LOOP

    · ' Send digits to LCD
    · FOR idx = 0 TO 4
    ··· char = digits(idx)
    ··· GOSUB LCD_Write
    · NEXT
    '
    ' Variables
    '


    digits········· VAR···· Byte (5)················ ' holds digits for display

    '
    LCD_Put_RJ_Value:

    · ' Init digits to all zeros
    · PUT digits, "00000"

    · ' Convert value to ascii digits
    · DO WHILE value >= 10000
    ··· INC digits(0)
    ··· value = value - 10000
    · LOOP
    · DO WHILE value >= 1000
    ··· INC digits(1)
    ··· value = value - 1000
    · LOOP
    · DO WHILE value >= 100
    ··· INC digits(2)
    ··· value = value - 100
    · LOOP
    · DO WHILE value >= 10
    ··· INC digits(3)
    ··· value = value - 10
    · LOOP
    · digits(4) = digits(4) + value_LSB

    · ' Blank leading zeros
    · idx = 0
    · DO WHILE idx < 4
    ··· IF digits(idx) = "0" THEN······· ' IF digit is Zero...
    ····· digits(idx) = " "············· '·· make it Blank
    ··· ELSE
    ····· idx = 4······················· ' Set counter to done value
    ··· ENDIF
    ··· INC idx
    · LOOP

    · ' Send digits to LCD
    · FOR idx = 0 TO 4
    ··· char = digits(idx)
    ··· GOSUB LCD_Write
    · NEXT

    · RETURN
  • Capt. QuirkCapt. Quirk Posts: 872
    edited 2007-03-17 02:23
    Thanks for the help, Bean's code snippet and a few modifications did it.

    If anybody else can use it, here it is

    Thanks again
Sign In or Register to comment.