Problem with setting/reading to a port
Curtis Brooks
Posts: 38
Okay, this works but not like it should.
I have code setup to write/read to the port based on data received from serin.
I can set the port just fine but when I go to read from the port it'll work so long as the value received is not 11 (so far that is the first value I found to not work). If the BS2 received·11 or (BIN 1011) it sets the port to that value just fine BUT, when I set the port to input and read the state of the port into a variable, it shows up as DEC 3 (BIN 0011). I'm not understanding why this happens. All other values I have tested works just fine like it should. I even tried reading each pin separatedly, setting up a routine to add all port pin status up to a byte value and still get the same results when I read the data on the port. Any sugggestions as to what could be wrong? I have tried the same procedure on a PIC and get the same results. Could it be somehow the BS2 is mistaking the serial input 11 as meaning binary 11?
Thanks,
Curtis
I have code setup to write/read to the port based on data received from serin.
I can set the port just fine but when I go to read from the port it'll work so long as the value received is not 11 (so far that is the first value I found to not work). If the BS2 received·11 or (BIN 1011) it sets the port to that value just fine BUT, when I set the port to input and read the state of the port into a variable, it shows up as DEC 3 (BIN 0011). I'm not understanding why this happens. All other values I have tested works just fine like it should. I even tried reading each pin separatedly, setting up a routine to add all port pin status up to a byte value and still get the same results when I read the data on the port. Any sugggestions as to what could be wrong? I have tried the same procedure on a PIC and get the same results. Could it be somehow the BS2 is mistaking the serial input 11 as meaning binary 11?
Thanks,
Curtis
Comments
What you are attempting to do isn't particulalry clear from your message. If you provide the program code with comments, that would probably help a great deal in getting an answer to your questions.
Regards,
Bruce Bates
WritePortB = OUTH 'Alias for output pins 8-15
ReadPortB = INH 'Alias for input pins 8-15
MyVal VAR Byte 'Variable used to store value read from port
serin RxD,baud,[noparse][[/noparse]wait(254),cmd1,indata] 'Wait for sync byte, get menu command, pattern to write to port or format to send to PC
'indata will either be a serial string for the pattern to set on the BS2 or a number representing the format of the data to
'send to the PC i.e. 1 to send in DEC, 2 to send in BIN, or 3 to send in HEX
main:
if cmd1 = 0 then WriteToPort
if cmd1 = 1 then ReadFromPort
goto main
WriteToPort:
WritePortB = indata 'Write pattern received from PC to portB (pins 8-15)
goto main
ReadFromPort:
INPUT ReadPortB 'Set PORTB as input
MyVal = ReadPortB 'Read current pattern of portB
if cmd2 = 1 then
serout TxD, baud,[noparse][[/noparse]DEC MyVal] 'Send data to PC as decimal
elseif cmd2 = 2 then
serout TxD, baud,[noparse][[/noparse]BIN MyVal] 'Send data to PC as Binary
elseif cmd2 = 3 then
serout TxD, baud,[noparse][[/noparse]HEX MyVal] 'Send data to PC as Hexadecimal
endif
goto main
Now, if I set the port to any value other than 11 and read the status of the port it works fine. But, if I set the port to value of 11 and read status of port it shows a value of 3 and also sets the port to 3. The problem comes in when I set the port as an input.
It's still not clear to me exactly what you are trying to do, but let me say this. No where in the code segment you've provided do you use the DIRS or DIRH command, thus, no pin ports 8-15 are being set by your code to INPUT or OUTPUT.
I hope that is helpful. Sorry if I seem to be dense.
Bruce
I forgot to type it into the code posted, but I set DIRH = %11111111 to setup the port as an output.
THe object of the code is to wait until the PC sends a serial stream to the BS2 telling it to set the entire port to a pattern value 0-255. The BS2 sets the specified pattern onto PortB pins 8-15. Next, the code goes back to the main routine and waits for more serial data. If it receives the cmd1 to read port status and send back to the PC, it jumps to that routine and this time cmd2, as received from the PC, is a value 1-3 telling the BS2 the format to send the serial data back to the PC as. Again, 1 for DEC, 2 for BIN, and 3 for Hex.
Now, say I send the value 10 from the PC, the BS2 to will make the associated pins on PortB to high BIN (0000 1010). If I read the status and tell the BS2 to send back to the PC as BIN it will send back 0000 1010. Now, I can repeat this routine will different values and it works fine until I send the value 11 from the PC to the BS2. If I go to the routine to read the port after setting the port to 11 BIN (0000 1011), the port gets set to 0000 0011 instead of staying 0000 1011. That's not supposed to happen at all. Also, the value sent to the PC is 0000 0011. It should be value 11 instead. The code posted above is the routines used (I copied the routines from my PIC version and changed to match up to BS2 standards). I'm not seeing why all other values work but 11 screws it all up. If I set 24 onto· PORTB then 24 gets set, if I then set the port to input so I can read it, it should not change the value of it. I just read the status of the port not change any of the pins.
That is what I cannot figure out.
To see what I am saying, use a routine to set OUTH to 00001011 and then use another routine to set the port as an input and read the status out to a debug screen and tell me if anyone gets the same as I did. I also get the same results on my PIC16F628. Not sure why.
Again I appreciate all the help
If you are reading the status of a pin set to OUPUT you may not be getting what you're expecting to get. There is a bit of an anomaly which you may want to learn about. Take a look at the TOGGLE command in the Parallax PBASIC Stamp Manual for a full explaination.
Additionally, there is the read-modify-write situation which occurs on all PICs and is well documented in most PIC datasheets. I'm not sure if that applies here or not. Here is an excerpt from the '628 datasheet:
quote
Reading PORTB register reads the status of the pins, whereas writing to it will write to the port latch. All write operations are read-modify-write operations. So a write to a port implies that the port pins are first read, then this value is modified and written to the port data latch.
end quote
You may also want to take a look at the Parallax PBASIC REVERSE command for additional comments on altering pin ports from INPUT to OUTPUT. The dual meaning of "input" may have bearing as well here, particularly if there is external circuitry to contend with.
At the possible risk of being accused of speaking PIC rather than Stamp, by way of comparison, I believe TRISB = DIRH from a functional point of view.
Regards,
Bruce Bates
To test, tried to cheat a little bit to see if there was a work around so I wrote the code below for the read routine:
GetPortStatus:
TRISB = %11111111 'Make PortB pins output
If IN8 = 0 THEN
BitStatus0 = 0
ELSEIF IN8 = 1 THEN
BitStatus0 = 1
ENDIF
If IN9 = 0 THEN
BitStatus1 = 0
ELSEIF IN9 = 1 THEN
BitStatus1 = 2
ENDIF
If IN10 = 0 THEN
BitStatus2 = 0
ELSEIF IN10 = 1 THEN
BitStatus2 = 4
ENDIF
If IN11 = 0 THEN
BitStatus3 = 0
ELSEIF IN10 = 1 THEN
BitStatus3 = 8
ENDIF
If IN12 = 0 THEN
BitStatus4 = 0
ELSEIF IN12 = 1 THEN
BitStatus4 = 16
ENDIF
If IN13 = 0 THEN
BitStatus5 = 0
ELSEIF IN13 = 1 THEN
BitStatus5 = 32
ENDIF
If IN14 = 0 THEN
BitStatus6 = 0
ELSEIF IN14 = 1 THEN
BitStatus6 = 64
ENDIF
If IN15 = 0 THEN
BitStatus7 = 0
ELSEIF IN15 = 1 THEN
BitStatus7 = 128
ENDIF
pattern = BitStatus0+BitStatus1+BitStatus2+BitStatus3+BitStatus4+BitStatus5+BitStatus6+BitStatus7
serout TxD, baud,[noparse][[/noparse]DEC pattern]
RETURN
Now, if I set the port to a value of 11 (0000 1011) and read from the port, the status returned is still 3 (0000 0011) but the port does not get modified from the value of 11 as it did when I read/wrote to the port directly.
Before you start banging your head again, you may want to cushion it first. All set?
What do 3 and 11 have in common? They are the SAME NUMBER! One of them, "3" is the decimal number three, and "11" or better stated 0000 0011 is BINARY THREE! Oops!
Bruce
You're really chewing up a whole lot of code for a simple task ... look, you can do your inputs with one line of code:
pattern = INH
The [noparse][[/noparse]internal] variable INH corresponds to the input group of P8 - P15, with P8 being the LSB and P15 being the MSB.
You are using a BASIC Stamp, aren't you? ...I noticed your TRIS_B reference so I need to ask).· If yes, making those pins inputs works like this:
DIRH = %00000000
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Dallas, TX· USA
Post Edited (Jon Williams) : 1/2/2005 5:11:23 PM GMT
Bruce, I think you misunderstood me above. I am not sending the data from the PC as BIN. I am sending it as ASCII and allowing the controller to do the conversion. It's just once I set the port to 11 (0000 1011) and then read the status of the port, it returns (0000 0011) instead of (0000 1011).
Jon, I wrote that above to see if I could force the port to return the correct value when I read it. I initially did just what you stated. Sorry if I mixed code a bit, I am testing the code on both a BS2 and a PIC 16F628. I am having the same problem on both.
Bruce, I read the data sheet and saw in there that there could be a problem if you read from the port after you write to the port on a PIC. I also looked at the documentation for the BS2. I am still stomped on a fix for this.
Jon, I copied and pasted code but you are right, it should be DIRH = %00000000. That is what I have in there, I copied and pasted from the wrong editor. Also, I removed DIRH = %00000000 from the routine and place it at the beginning of the program.
Jon, fatigue is a killer when it comes to fixing problems. Sometimes we need to just get up and walk away to clear our heads.
I poured through the many versions of the code that I have and noticed that I did not use INH properly. In my code, I attempted to set the port as an input first which happened to be the reason I was having a problem in the first place. I though I needed to set the port as an INPUT before reading the Port status into a variable. I was wrong. I went back and removed that and then used pattern = INH and it works fine now.
I still don't understand what was causing the problem before, maybe someone could explain that to me. It also fixed the problem with the version of the code for my PIC controller. Again, I still don't understand why I can't set the port as an input first and then read the status into a variable instead of using INH. But, it works so I'll stick with that for now.
Again, I appreciate all the help provided here. You guys came through when no one in another forum that I post to for the Basic Compiler that I use could help. I figured between the two I would get a solution. I stand behind my BS2 all the way and always comeback to it as a complete developer tool before moving to a PIC.
DIRH = %11111111
makes P8 = P15 ouputs. You can still read the INH register, but it will simply reflect the last value written to DIRH.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Dallas, TX· USA
Thanks again,
Parallax products are a little more than PICs but you get far more in return in reliablilty and support.
Get the file here: http://forums.parallax.com/showthread.php?p=517621
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Dallas, TX· USA