PDA

View Full Version : Interupts and Command string



Tissy
- 14th March 2006, 10:59
Hi,

I am trying to alter the below piece of code for an interupt driven serial device.

I would like the 'Main' part of the program to run up until a serial command is received. I would also like the device to send comms back to VB, this is the reason i have inserted 'flags'.

The interrupts are only working with a single character. How would i use the interrupt so that it receives a string of commands.

ie using the SERIN command i would use SERIN RxD,baud,[WAIT(254), hrs, min, sec], can someone assist how would i achieve this using interrupts. I would like it so that when the command (254) is received it then stores the received hrs, min and sec variables in EEPROM.

If i can achieve this then it should be a good starting block to the rest of the code.



'
' Simple program to handle USART interrupt using PIC16F877 @20MHZ
' ================================================== =============
'
' This program will Blink a LED on PORTB.0 to show
' that the PIC is running.
'
' This program also allow the user to activate or deactivate
' a LED connected on PORTB.1 pin by sending command from a PC
' terminal software using 9600,n,8,1 setting
'
' User command:
' =============
' 1. If character "1" is received => enable the LED
' 2. if character "2" is received => disable the LED
'
'
DEFINE LOADER_USED 1 ' using bootloader
DEFINE OSC 20 ' running at 20 MHZ
ADCON1 = %00001111

' PORT setting
' ============
'
TRISC=%10000000 ' RC.7 => USART RX pin set to input
' all other pin set to output
'
TRISB=0 ' RB<7:0> set to output

' USART setting
' =============
' Since we will not use HSERIN/HSEROUT, we must
' write directly to internal PIC register
'
TXSTA=$24 ' enable transmit and SPBRGH=1
RCSTA=$90 ' Enable USART and continuous receive
SPBRG=129 ' BAUD RATE = 9600 BAUDS

' Interrupt definition
' ====================
'
PIE1.5 =1 ' enable USART receive interrupt
INTCON.6 =1 ' enable peripheral interrupt

' Alias definition
' ================
'
RCIF var PIR1.5 ' receiver interrupt
StatusLED var PORTB.0 ' the LED who show a 'running process'
UserLED var PORTB.1 ' the LED that user want to control

' Variable definition
' ===================
'
Delay var word '
DataIn var word ' use to store RCREG content
Discard var byte ' use to erase RCREG register
storedloop var byte
Flag var byte

' Hardware/software initialisation
' ================================
'
PORTB=0 ' clear PORTB
on interrupt goto USARTInterrupt


Start:
' Main program loop that make the user happy to
' see a LED flashing to mean that something is
' running
'
If flag = 1 then hserout [" Device Connected"]
if flag = 2 then hserout [" LED is Flashing"]
if flag = 3 then hserout [" LED is ON"]
If flag = 4 then hserout [" LED is OFF"]
flag = 0

toggle statusled
for delay = 1 to 5000 ' use a loop delay to ensure
pauseus 5 ' getting interrupt as fast as
next ' possible
goto start


disable interrupt
USARTInterrupt:
' Here's the interrupt routine who will make the user
' much happy by giving him the feeling to have the
' control on the machine when the status of the user
' LED will change
'
RCSTA=0 ' Disable serial port AND
' clear possible error (FERR,OERR)

datain=RCREG ' Get data

while RCif ' wait untill the RCREG is empty
discard=RCREG ' by reading it and store result in a
wend ' don't care variable

select case datain ' What to do with that data???

case "#" ' User selection = 1
userled=1 ' => Enable the LED
FLAG = 3 ' => disable the LED
case "2" ' User selection =2
userled=0 ' => disable the LED
flag = 4
case "3" ' User selection =321
For storedloop = 1 to 5
High userled
Pause 50
Low userled
Pause 50
Next storedloop
flag = 2
case "9" ' User selection =2
FLAG = 1 ' => disable the LED

end select

RCSTA=$90 ' Re-enable the serial PORT AND
resume ' get out of here
enable interrupt

Many thanks for any help offered.

Steve

mister_e
- 14th March 2006, 21:31
I remind that code...You remove my name on the top header :)

Well why not simply use HSERIN in the USARTInterrupt section?

Tissy
- 15th March 2006, 00:36
Your quite correct Steve, it was your code which i found at http://www.picbasic.co.uk/forum/showthread.php?t=1877&highlight=Simple+program+handle+USART+interrupt+PI C16F877+%4020MHZ

I didn't remove any of your signatures from the top header as they weren't on the code i found as above. All credits recognised though ;-).

Would you be kind enough to give an example of what you mean using the HSERIN command.

As in the interrupt code you are disabling the serial port first. Are you saying remove these lines, and then treat it with just the HSERIN command.

I am new to serial comms and often learn better from a quick example (if you could oblidge).

Many thanks,

Steve

mister_e
- 15th March 2006, 17:26
Yup that's what i think... just an idea.

So you already figured something like


Disable
USARTInterrupt:
HSERIN [Data1, Data2,....]
'
' Data processing or not here
'
Resume
Enable


Just read the HSERIN section. You may also use STR modifier too. Dpending what kind of data format you'll use.

Tissy
- 15th March 2006, 21:26
Excellent help, thanks.

I have now managed to get variables sent from VB to PIC.

The code now looks like this:



Start:
' Main program loop that make the user happy to
' see a LED flashing to mean that something is
' running
'

Hserout [hours, minutes, seconds]

toggle userled
for delay = 1 to 5000 ' use a loop delay to ensure
pauseus 5 ' getting interrupt as fast as
next ' possible
goto start


disable interrupt
USARTInterrupt:
' Here's the interrupt routine who will make the user

HSERIN [hours, minutes, seconds]

Write 5, hours
Write 6, minutes
Write 7, seconds

resume ' get out of here
enable interrupt


However, i can only send over single numerals, ie 0-9. But in the timing functions for Hrs, Mins and Sec it could be upto 59. How do i get the PIC to reconise the double figures. If i try to send them the PIC just hangs.

The write command is to just store the variables in EEPROM for later use.

Thanks for your help,

Steve

mister_e
- 15th March 2006, 22:07
Suppose the actual time is 1:33:56
Send it as 013356

actual time is 1:02:01
send it as 010201

THEN you use the DEC2 modifier
HSERIN [DEC2 hour, DEC2 Minute, DEC2 Second]

Tissy
- 16th March 2006, 11:18
Yup, that worked very well. I'm trying to figure out the methods of sending and receiveing data on 2 languages, PIC and VB.

I managed to get the combining of the timings and it now it reads and outputs very well. Thank you Steve.

I've been reading about qualifiers, but can only see the WAIT command, where as i'm using an interupt, this isn't really what i want.

I want to look for a command sent from VB to signal what routine to jump too. For example in the interupt if the word TIMINGS is received then it reads and stores the subsequent timing variables. But if the word FLAGS is received then it stores the flag variables etc etc.

In VB i would output something like



MSComm1.Output = "Time" & Format(Hours, "00") & Format(Minutes, "00") & Format(Seconds, "00") & Format(SuSeconds, "00")


Is this possible?

As at the moment it will just deal with the 8 numbers it receives, i want it to be more choosy depending what VB sends accross.

Many thanks,

Steve

mister_e
- 16th March 2006, 14:57
for the HSERIN modifier refer to SERIN2

about VB, here's a quote from VB6 Black book pdf
<img src=http://www.picbasic.co.uk/forum/attachment.php?attachmentid=822&stc=1&d=1142517740>

Tissy
- 16th March 2006, 17:11
Thanks Steve.

At the moment i have this code for the interupt, it works as long as i send "Time" as the qualifier.

So in VB it sends:



MSComm1.Output = "Time" & Format(Hours, "00") & Format(Minutes, "00") & Format(Seconds, "00")

Where the PIC command is:


HSERIN [Wait("Time"), DEC2 hours, DEC2 Minutes, DEC2 Seconds]

Thing is, I don't want it to wait. I want it to look at the serial command comming in and check for the qualifier. So if the qualifier is TIME, it then takes the DEC2 hours, DEC2 Minutes, DEC2 Seconds strings.

However, if the qualifier is FLAG, then it performs a different command, such as:


HSERIN [flag1, flag2, flag3]


If neither of the qualifiers are met (or any depending how many i need), then it resumes and waits for the next serial input.

Does this make sense, i'm starting to confuse myself !

Cheers,

Steve

mister_e
- 17th March 2006, 01:13
bah as you wish. You can even do some handshake between PIC and PC.

PIC side:

Waiting for Flag (must be Fix format 1,2,3 or more character) Lets'say BEER
choose according procedure to do (Corect HSERIN), Send Confirmation to PC (OK i got Beer, send me another Crate now)


and there still many other way.. it's up to you

Tissy
- 17th March 2006, 02:44
Sorry Steve, don't understand what you mean.

Maybe i haven't had enough 'beer'.

This is what i have come up with so far, but its still not working.



USARTInterrupt:
' Here's the interrupt routine

HSERIN [Qualifier]
Branch QUALIFIER,[Sub1,Sub2,Sub3]

Sub1:
HSERIN [DEC2 hours, DEC2 Minutes, DEC2 Seconds, DEC2 suseconds]
Write 5, hours
Write 6, minutes
Write 7, seconds
write 8, suseconds
HSEROUT ["You sent Red", DEC2 hours, DEC2 Minutes, DEC2 Seconds, DEC2 suseconds]
return

Sub2:
HSEROUT ["You sent Blue"]


Sub3:
HSEROUT ["You send Green"]

Resume
enable interrupt


I guess i want it to check that the qualifier is either 'Red', 'Blue', or 'Green', If it isn't then come out of the interupt and wait for the next serial string. This is the bit of code i am missing and having problems with !!

If for example the qualifier Red is received, then it jumps to the Sub1 routine and captures the other 8 bytes.

Am i on the right tracks with what i have done so far? Can you assist with the qualification side?

Cheers,

Steve

mister_e
- 17th March 2006, 16:31
Something to mess 'round with i guess this weekend for me.. one more ;)

How about that untested version


USARTInterrupt:
' Here's the interrupt routine

HSERIN [DEC Qualifier]
Branch QUALIFIER,[Sub1,Sub2,Sub3]

Sub1:
HSERIN [DEC2 hours, DEC2 Minutes, DEC2 Seconds, DEC2 suseconds]
Write 5, hours
Write 6, minutes
Write 7, seconds
write 8, suseconds
HSEROUT ["You sent Red", DEC2 hours, DEC2 Minutes, DEC2 Seconds, DEC2 suseconds]
Goto GetOutOfHere

Sub2:
HSEROUT ["You sent Blue"]
Goto GetOutOfHere

Sub3:
HSEROUT ["You send Green"]
GetOutOfHere:
Resume
enable interrupt


And be sure you have some delay between each PC send.. i Mean wait between QUALIFIER and the rest of the process. Some VBTimer are really usefull in those case.

Personnally, i never mess with string handling. Just use BRANCH and send the according value. Time saving and work anyway.

Tissy
- 17th March 2006, 21:52
Sorry Steve, that didn't work.

I presume with this code it is looking for 0,1 or to be the qualifier?

If so, how do i get it to look for red, green or blue as the qualifier.

Thats what i would like it to perform as a test example. ie if VB sends out Red, it then goes to the Sub1 routine and then captures the follwoing eight bytes.

If Blue is sent as the qualifier, then it jumps to Sub2 and just sends out a text string.

Any ideas?

I've messed with the code i have so far and with your modified example as above, but no joy.

This is driving me round the twist, been working on this piece of code for about a week now.

Many thanks again,

Steve

mister_e
- 18th March 2006, 00:59
you may look at the Melanie example
http://www.picbasic.co.uk/forum/showthread.php?t=573

Maybe something to play around.

As i said, i never waste my time 'round string parsing in a PIC. I keep my code space for something else than that.