PDA

View Full Version : Problem with Numbers object



Adisharr
03-13-2012, 08:22 AM
Hi All,

First time posting here - certainly seems to be no end of brain power in this forum :)

I'm just starting out using my Propeller board I purchased a couple years back and have run into an issue using the numbers.spin object.

I have a number of pins attached to a small parallel LCD and have been able to print out characters from a string variable. No problems there. I have been unable to get the Num.ToStr object interface working though.

See code below:


VAR

BYTE LCD_RS 'LCD REGISTER SELECT (0=COMMAND, 1=DATA)
BYTE LCD_RW 'LCD READ/WRITE SELECT SIGNAL (0=WRITE, 1=READ)
BYTE LCD_E 'LCD OPERATION ENABLE SIGNAL (FALLING EDGE TRIGGERED)
LONG TEST_NUMBER 'USED IN TEST NUMBERS OBJECT
LONG STRINGPOINTER 'USED IN TEST NUMBERS OBJECT
BYTE X 'INDEX VARIABLE
BYTE CHAR_INDEX

OBJ

NUM : "Numbers"

PUB Main

DIRA[0..10]~~ 'SET LCD I/O PINS TO OUTPUT

DELAY(10_000_000)

LCD_RS := 10
LCD_RW := 9

{FORMAT DISPLAY}

LCD_DISPLAY_CTRL
LCD_FORMAT

'CLEAR DISPLAY

LCD_CLEAR
LCD_HOME

{PRINT STRING TEST}

DELAY(1_000_000)

REPEAT CHAR_INDEX FROM 0 TO 9

OUTA[0..7] := TEST_STRING[CHAR_INDEX]
OUTA[LCD_RS]~~
OUTA[LCD_RW]~
OUTA[8]~~
OUTA[8]~

{NUMBER TO STRING TEST}

NUM.INIT 'INITIALIZE NUMBERS OBJECT

TEST_NUMBER := 5678

STRINGPOINTER := NUM.TOSTR(TEST_NUMBER, NUM#DEC)

DELAY(5_000_000)

REPEAT X FROM 0 TO 3

OUTA[0..7] := BYTE[@STRINGPOINTER][X]
OUTA[LCD_RS]~~
OUTA[LCD_RW]~
OUTA[8]~~
OUTA[8]~

DELAY(200_000)

REPEAT

{------------------------------------------------------------------------------------}

PUB LCD_DISPLAY_CTRL

OUTA[0..7] := �001111 'CONTROL DISPLAY COMMAND
OUTA[LCD_RS]~
OUTA[LCD_RW]~

OUTA[8]~~ 'SEND ENABLE PULSE
OUTA[8]~

PUB LCD_CLEAR

OUTA[0..7] := �000001 'CLEAR DISPLAY COMMAND
OUTA[LCD_RS]~
OUTA[LCD_RW]~

OUTA[8]~~ 'SEND ENABLE PULSE
OUTA[8]~

PUB LCD_HOME

OUTA[0..7] := �000010 'HOME DISPLAY COMMAND
OUTA[LCD_RS]~
OUTA[LCD_RW]~

OUTA[8]~~ 'SEND ENABLE PULSE
OUTA[8]~

PUB LCD_FORMAT

OUTA[0..7] := �111100
OUTA[LCD_RS]~
OUTA[LCD_RW]~

OUTA[8]~~
OUTA[8]~

PUB DELAY(TIME)

WAITCNT(TIME + CNT)

DAT

TEST_STRING BYTE "123456789 ",0

The 'Print String' test works fine - the 'Number to string test' just prints garbage.

I've used the print string function in the parallax serial terminal and that seems to work correctly. Any ideas what's going on?

Let me know if you need more information.

Thanks..

kuroneko
03-13-2012, 08:37 AM
TEST_NUMBER := 5678

STRINGPOINTER := NUM.TOSTR(TEST_NUMBER, NUM#DEC)

DELAY(5_000_000)

REPEAT X FROM 0 TO 3

OUTA[0..7] := BYTE[@STRINGPOINTER][X]
OUTA[LCD_RS]~~
OUTA[LCD_RW]~
OUTA[8]~~
OUTA[8]~

STRINGPOINTER is an address. So unless you want to display said address I'd get rid of the @ in which case you'll display the first 4 characters of the string.

MagIO2
03-13-2012, 09:19 AM
Sorry kuroneko, but I think we need to be a little bit more precise with the speach in this case. ALL variables ARE addresses for the compiler! The important question is "What does the variable contain?" and what does the compiler do when using @. STRINGPOINTER CONTAINS an address.

Let's assume we have the following memory map. (This is only hypothetical


RAM-Address Label Content Size
..
$1000 STRINGPOINTER 0 Long
$1004 TEST_NUMBER 0 Long
$1008 X 0 Long
..
$1200 STRBUFFER 0 Byte array [13]
$1201 0
..
$120D 0

What does your progam do with this memory:

TEST_NUMBER := 5678


RAM-Address Label Content Size
..
$1000 STRINGPOINTER 0 Long
$1004 TEST_NUMBER 5678 Long
$1008 X 0 Long
..
$1200 STRBUFFER 0 Byte array [13]
$1201 0
..
$120D 0



STRINGPOINTER := NUM.TOSTR(...)


RAM-Address Label Content Size
..
$1000 STRINGPOINTER 0 Long
$1004 TEST_NUMBER 5678 Long
$1008 X 0 Long
..

$1200 STRBUFFER "5" Byte array [13]
$1201 "6"
$1202 "7"
$1203 "8"
$1204 0

..
$120D 0




STRINGPOINTER := NUM.TOSTR(...)


RAM-Address Label Content Size
..
$1000 STRINGPOINTER $1200 Long
$1004 TEST_NUMBER 5678 Long
$1008 X 0 Long
..
$1200 STRBUFFER "5" Byte array [13]
$1201 "6"
$1202 "7"
$1203 "8"
$1204 0
..
$120D 0


So, what will OUTA be in the first iteration?
REPEAT X FROM 0 TO 3

OUTA[0..7] := BYTE[@STRINGPOINTER][X]


@STRINPOINTER is equal to $1000, so what whe have is
OUTA[0..7] := content of the memory location $1000 + 0 (0 coming from X) := 00

In the next iteration it would be
OUTA[0..7] := content of the memory location $1000 + 1 (1 coming from X) := 12

(if I remember right the prop is least significant byte first)

PS: Adding the missing bit here ;o)
So, @STRINGPOINTER is NOT what you want!
You want to have the content of STRBUFFER and it's following bytes.
STRBUFFER is equal to address $1200 and this value (the address itself) is stored in STRINGPOINTER. So, if you want to read from $1200 you simply say:
OUTA[0..7] := byte[ STRINGPOINTER ][ i ] which is the same as
byte[ $1200 ][ i ] or in other words "give me the content of memory location $1200 + i" which is "5"

Adisharr
03-13-2012, 03:15 PM
Thanks you very much for the detailed reply - I need to take a little time and digest this but I think this will solve my problem. Looks like to need to spend more time understanding the data formats and how things are referenced :innocent:

Adisharr
03-14-2012, 01:51 AM
PS: Adding the missing bit here ;o)
So, @STRINGPOINTER is NOT what you want!
You want to have the content of STRBUFFER and it's following bytes.
STRBUFFER is equal to address $1200 and this value (the address itself) is stored in STRINGPOINTER. So, if you want to read from $1200 you simply say:
OUTA[0..7] := byte[ STRINGPOINTER ][ i ] which is the same as
byte[ $1200 ][ i ] or in other words "give me the content of memory location $1200 + i" which is "5"

Thank you very much - your initial explanation clued me to try the STRINGPOINTER without the '@' and it worked great :smile::smile::smile: