PDA

View Full Version : Help SERIN2/SEROUT2



mike20200
- 31st August 2007, 00:00
Im using PIC16f877A with 20Mhz crystal

and my code is below
================================================== =================
DEFINE OSC 20

Name var BYTE[8]
'To start the progam hit a CR
cmd var byte
CR con 13
CLear

PAUSE 200

main:
Serout2 PORTC.6, $BC,["Option"]
pause 200
Serout2 PORTC.6, $BC,[10,13]
pause 200
Serout2 PORTC.6, $BC,["1:START",10,13]
pause 200
Serout2 PORTC.6, $BC,["2: Enter Name",10,13]
pause 200
Serout2 PORTC.6, $BC,["3: Display Name",10,13]
pause 200
Serout2 PORTC.6, $BC,["4: Shut Down",10,13]
pause 200
Serout2 PORTC.6, $BC,[10,13]
pause 200

goto getinput

getInput:
Serout2 PORTC.6, $BC,["Choose your Option",10,13]
pause 200
serin2 PORTC.7, $BC,[dec1 cmd]

if cmd = "0" Then
GOSUB bad
endif

if cmd = "1" Then
GOSUB dosleep
endif

if cmd = "2" Then
GOSUB doend
endif

if cmd = "3" Then
GOSUB getname
endif

if cmd = "4" Then
GOSUB dispname
endif

bad: Serout2 PORTC.6, $BC,[10,13,"Invalid Command",10,13]
pause 200
return

dosleep: Serout2 PORTC.6, $BC,[10,13,"Night Night..",10,13]
pause 200
return

doend: Serout2 PORTC.6, $BC,[10,13,"BYE BYE",10,13]
pause 200
Return


'---------------------------------------------------------------------
'Get the users name
'---------------------------------------------------------------------
getname: Serout2 PORTC.6, $BC,["What is your name? "]
pause 200
'Read in users name here. Maximum of 30 characters or CR
serin2 PORTC.7, $BC,[str name\30\13]
pause 200
'Display name until 30 characteres or end of data
Serout2 PORTC.6, $BC,["Hello ",str name \30]
pause 200
Serout2 PORTC.6, $BC,[10,13]
pause 200
return

'-----------------------------------------------------------------
'Display the users name
'-----------------------------------------------------------------
dispname: Serout2 PORTC.6, $BC,["Hello ",str name \30]
pause 200
Serout2 PORTC.6, $BC,[10,13]
pause 200
return

end


================================================== ================

I run it with Hyperterminal to test my code. what i get is this infinity non stop loop:

================================================== ================
Choose your Option
Option

1:START
2: Enter Name
3: Display Name
4: Shut Down

Choose your Option
Option

1:START
2: Enter Name
3: Display Name
4: Shut Down

Choose your Option
Option
================================================== ================

How to make the loop stop n to key in what i wan... Pls help me

Clayt_d
- 3rd September 2007, 06:37
Never done any pic programming, but a little basic back in the 80s - so might be completely off the mark here..

Following the code from the top, it displays the menu, then drops through the options - because no valid key has been pressed.
The code then eventually lands on bad: because there is no end point for main:

main:
'code
goto getinput
'there is no end statement here

getinput:
serin2 PORTC.7, $BC,[dec1 cmd] 'does this need to be told how many bytes to wait for? What does dec1 actually do?
'the code should do a return here

bad:
'this code section is executed no matter what happens
return


It appears that the program is returning to the last gosub statement it executed (ie none), perhaps filling the PC register with garbage? Or zeroes? or possibly the address of the program start point from the stack?


Am I right in assuming also that the command in getinput:
serin2 PORTC.7, $BC,[dec1 cmd] does not wait for an input? Instead it only checks the port and continues execution? If it is not told how many bytes to read, does the program assume that no bytes are acceptable input (or a byte value of 0, which is different from "0")?


Try to avoid the use of GOTO statements unless absolutely necessary, and never use them to jump elsewhere in the program - it causes no end of grief.. Try to limit their use for loops that are designed to execute indefinitely. Use the GOSUB, IF/THEN, or BRANCH to jump around, it is much less hassle to debug.

Try this fix - it is ugly, as it still uses a GOTO to continually loop for the check for input, but might be worth trying.

Make these changes:

{move}
Serout2 PORTC.6, $BC,["Choose your Option",10,13]
{up to the line before}
goto getinput
{..Then put a new label eg- checkser: BETWEEN those two lines}

{Change}
goto getinput
{into}
gosub getinput
{then add a new GOTO after that}
goto checkser

getinput:
if cmd = "4" Then
GOSUB dispname
endif
{add the following line, so the program can go back and check for input}
return


Your changed code should look something like this:

main:
'menu options
Serout2 PORTC.6, $BC,["Choose your Option",10,13]
goto getinput

checkser:
gosub getinput
goto checkser

getinput:
'code to check choices
return


Hope this helps.

Clayt_d
- 3rd September 2007, 07:13
Another thing to look at:

If what I read in the language guide is correct, then your IF..THEN statements are actually branching to a non-existent program label called gosub:

Is it possible to compile that without raising an error?

You may have to remove the GOSUBs and the ENDIFs from this bit of code (better make a copy of it lol):

if cmd = "0" Then
GOSUB bad
endif

if cmd = "1" Then
GOSUB dosleep
endif

if cmd = "2" Then
GOSUB doend
endif

if cmd = "3" Then
GOSUB getname
endif

if cmd = "4" Then
GOSUB dispname
endif

Assuming that the manual is correct, I can see why your blocks of IF..ENDIF are not working (not legal), but I am surprised if the compiler isn't catching that!
Is it possible that your PIC is resetting when it encounters the first illegal IF..THEN construct? It would explain everything..

Archangel
- 5th September 2007, 06:19
Hi Mike,
I think you should use the USART and setup a hardware buffer to capture the data choices as I do not believe the code you have will be in the appropriate state when your user is ready to answer the questions, check out Mr. E's keypad routines and the serial backpack code Darrel helped me with. good stuff there. also your main loop simply ends without a directive to goto main so it runs into the subroutines without meeting the criteria your IF THEN loops are asking for. You state hit CR to start the program. The program will simply start and run as is, perhaps a loop to test for a CR is in order so program will not execute beyond the instruction to hit CR until it actually sees a CR.
something like:


row var byte
location var byte
value var byte
start: SERIN 1,N2400,ROW,LOCATION,VALUE
IF value = CR then
goto main
else
goto start

Darn I'm getting rusty at this as I have been working instead of coding . . .