PDA

View Full Version : A little help with shifting out Arrays?



Ryan7777
- 20th September 2012, 17:07
I'm having a little bit of trouble with array variables as of late. From my understanding (and R-ingTFM) to set up my array to contain three bytes:

myArray VAR BYTE[3]

And to access my three bytes as individuals to load data into them:

myArray[0] = 1
myArray[1] = 127
myArray[2] = 255

and then myArray should have 24 bits and if i do this:

SHIFTOUT PORTB.0, PORTB.1, 1, [myArray\24]

It should shift out:

111111110111111100000001

MSB first right? Because something isn't right...

If I do this:

myLong VAR LONG

myLong.BYTE0 = 1
myLong.BYTE1 = 127
myLong.BYTE2 = 255

SHIFTOUT PORTB.0, PORTB.1, 1, [myLong\24]

Everything seems to work as expected.

Do I need to load my array bytes "upside down" perhaps?

myArray[0] = 255
myArray[1] = 127
myArray[2] = 1

This is all on a 18F4550 which is working quite well. I'd love to avoid LONGs if I can save a byte here and there and I'd like to stay away from putting multiple variables in my shiftout to keep my code terse. I can't post more than the pseudo code because I don't have it with me, but I figured a thought about my code during lunch hour would be an effective use of my free time.

Thanks for any and all help as always!

Ryan

HenrikOlsson
- 20th September 2012, 17:58
Hi,
It shifts out each byte in the array MSB first - not the whole array MSB first. myArray[0] MSB first, then myArray[1] MSB first and so on.
Loading the array "backwards" should do the trick I think.

When you do the SHIFTOUT with the LONG, are you sure that it doesn't start at the most significant bit of the variable (myLong.31)?
I would, for sure, have expected it start at the most significant bit of that 32bit variable and then shiftout 24 bits "down" thus not outputting the least significant byte. Not start in the middle of the variable....

/Henrik.

SteveB
- 20th September 2012, 19:18
Henrik,
The "\bits" option shifts out the low order bits, regardless of the mode.

SteveB
- 20th September 2012, 20:03
Ryan,
I’m curious about the actual results you get with your example:

myArray VAR BYTE[3]

SHIFTOUT PORTB.0, PORTB.1, 1, [myArray\24]

Why? Because PBP is not aware of, and never tracks, the array size. In fact, it isn’t an array in the same sense that other languages use arrays (like VBA or .Net). PBP only knows that MyArray[0] is a byte at address $XX. It then ‘skips’ the number of addresses you specify in your array declaration before allocating another variable to a memory location. When you use brackets, it is really only offsetting [y] from $XX. Take this example:

myArray VAR WORD[4]

myArray[5] = 123

This is a perfectly valid expression, but will result in a lot of grief. What PBP will do is insert 123 into the two byte “WORD” located at a 5 WORD offset (10 bytes) from the memory location of myArray[0]. More than likely, that address will be allocated to another variable, so that variable will be corrupted, and your program will go off into a ditch pretty quick.

So back to your problem. When you use that shift out with myArray assigned, it really only understands that myArray is a Byte. Thus, I suspect it is trying to shift out 24 bits of data, but doing so in byte sized chunks. In doing this, it’s starting with the Address of myArray[0], just as Henrick states, and moving to the next address until 24 bits are sent.

But, I could be off track here, so I’m interested in what it’s outputting.

HenrikOlsson
- 20th September 2012, 20:58
Steve,
Ha, you're right, it even says that in the manual. However, and I guess I could try this, but are you (and the manual) saying that when using "\bits" it always shifts out LSB first? The manual really isn't clear as it just says it's the low order bits regardless of the MODE but it doesn't really say if it completely disregards the MODE and does LSB first even if told to do MSB.

I guess, based on Ryans post, that it does shift them out in the correct order, ie \24 on a long will start at the MSB of the third byte and go "down" to the LSB of the first byte.

As for Ryans array example I'd expect the output to be 00000001 01111111 11111111. The first bit going out is the MSB of myArray[0] and the last bit going out is the LSB of myArray[2].

/Henrik.

Ryan7777
- 20th September 2012, 21:14
I'll maybe try both ways and break out my logic analyzer. I get confused with the MSB/LSB stuff though. I guess the analyzer captures on the screen the first bit it sees on the left hand side of the screen and goes from there. So we'll see. I just have to think about what numbers to use to get a result I can fit my little brain around. high voltage modulators and vacuum tubes at work to microcontrollers and digital circuits at home. Maybe I should take up wood working as a hobby instead!

SteveB
- 20th September 2012, 23:26
Henrik,
What "low order bits" means in this case is that "\X" will always shift out the x lowest bits. So myByte\4 or myWord\4 or myLong\4 would all just output the 4 lowest bits. Now that the correct bits have been determined, it will shift them out based on the mode. So you can think of "\X" as "Shift out the lowest X bits of the variable"

This is why I'm curious about the actual output of the the shift statement used, which could be understood as, "Shift out the lowest 24 bits in the byte called myArray". As you can see, it doesn't make a lot of sense, but it's going to try to do something, and I am wondering what that something is.

SteveB
- 21st September 2012, 03:46
myArray VAR BYTE[3]

myArray[0] = 1
myArray[1] = 127
myArray[2] = 255

SHIFTOUT PORTB.0, PORTB.1, 1, [myArray\24]

Prediction:
The above code will shift out the following:
00000000 00000000 00000001

With myArray[0] = 127:
00000000 00000000 01111111

With myArray[0] = 255:
00000000 00000000 11111111

The values in myArray[1] and myArray[2] have no effect on the outcome.

Ryan7777
- 24th September 2012, 16:19
Sorry for not getting back to this. I've had my logic analyzer tied up for something else and haven't been able to get back to that project let alone this one due to some things beyond my control. I will however report back when I do get to it. I hate starting a question and not getting to the answer.

Best Regards,

Ryan

SteveB
- 24th September 2012, 16:30
I haven't had a chance to test it either. But my prediction is based on looking at the asm code produced. Although I noticed that I compiled it using PBPLong.

Using the non-long PBP, the results will be a little different, but likely still have 0000000000 00000001 as part of the result, since the internal temporary variable PBP uses is a 2-byte word, and it clears the top byte before entering the shift-out routine, then shifts out 24 bytes.

Bottom line, to do what you want, either of the following will work:
- Use 3 seperate BTYE variables
- 1 BYTE and 1 WORD variable
- 1 LONG variable

There may be some other, more creative way to work out the problem, but these are striaght foward and simple. The code may not look as 'tight', but it will work the way you expect/desire.

SB

HenrikOlsson
- 24th September 2012, 18:23
Hi guys,
I just did some tests here. Here's the testcode:

Leader VAR BYTE
myArray VAR BYTE[3]
Trailer VAR byte

Leader = 170
Trailer = 85

Test1:
myArray[0] = 1
myArray[1] = 127
myArray[2] = 255
PortB.5 = 0
SHIFTOUT PortB.6, PortB.7, 1, [myArray\24]
PortB.5 = 1

PauseUs 10

Test2:
myArray[0] = 255
myArray[1] = 127
myArray[2] = 1
PortB.5 = 0
SHIFTOUT PortB.6, PortB.7, 1, [myArray\24]
PortB.5 = 1

Pauseus 10

Test3:
myArray[0] = 1
myArray[1] = 127
myArray[2] = 255

PortB.5 = 0
SHIFTOUT PortB.6, PortB.7, 1, [myArray[0], myArray[1], myArray[2]]
PortB.5 = 1

Pause 100
END
The idea with the Leader and Trailer bytes was to see if the memory is alocated in the order it declared and if the shiftout would "fall into" those - turns out that's not the case in this example. Here are the captured results:
6677
I was a bit surprised that both test 1 and test 2 gave the same results but it did.

/Henrik.

SteveB
- 24th September 2012, 21:19
I was a bit surprised that both test 1 and test 2 gave the same results but it did.

That IS a bit suprising.

But, it difinately shows that shifting out the array in the original post won't work, but doing it as seperate bytes of the array will work. So that is a 4th method that will work.

Thanks Henrik!

Ryan7777
- 16th October 2012, 16:31
Hey! thanks Henrik!!! I seriously meant to get back to that but got hung up on other issues and it got lost in the bottom of my pile of a million things to get done. I did get my code working in respect to this just loading the individual bytes of a long variable, and then shifting out the long. so I guess stuck with what worked. Thanks for the test. Makes it easier to wrap my little brain around it now. Why long works is another story. I would expect the 4th "empty" byte that I'm not using would cause issues. it may still be yet, it may be that my hardware isn't choking on it enough to be noticed. Oh well. Works good enough for me!