Parse Strings from (Assembly) Serial Interrupt


Closed Thread
Results 1 to 2 of 2
  1. #1
    Join Date
    Mar 2007
    Posts
    3

    Default Parse Strings from (Assembly) Serial Interrupt

    Hello
    Can someone help me out I am using an example I found here: http://www.melabs.com/resources/samples/18F/serA452.bas

    I want to be able to send commands from a PC such as ADR,GET\r and ADR,SET,100\r etc. I just can't figure out how to decode the incoming data.

    The HSERIN command works but its too slow for my application and it hangs up if I try to send multiple commands at the same time.

    The following code works...but not all the time. It seems to miss (i'm assumming the index_out has something to do with it) I don't know assembly language but is there a way to modify the asm routine to read up to a terminating char such as a CR or LF and clear the buffer?

    I'm using an 18F6722 running a 40MHz xtal

    include "modedefs.bas"
    '************************************************* *********
    DEFINE LOADER_USED 1
    DEfine INTHAND SerialInterrupt
    Define I2C_INTERNAL 1
    DEFINE HSER_CLROERR 1
    define HSER_RCSTA 144
    define HSER_TXSTA 32
    define HSER_BAUD 9600
    define OSC 40

    '************************************************* *********
    Baud con 16468
    Size con 15
    Address var BYTE
    buffer var BYTE[15]
    wsave var BYTE 32 SYSTEM
    ssave var BYTE Bank0 SYSTEM
    fsave var WORD Bank0 SYSTEM
    index_in var BYTE BankA
    index_out var BYTE BankA
    errflag var BYTE BankA

    CREN var RCSTA1.4
    TRISC=128
    TRISD=255

    '************************************************* *********
    goto Initialize

    '************* Assembly Language Serial Receive ***********
    asm
    SerialInterrupt
    ; Save the state of critical registers
    movwf wsave ; Save W
    swapf STATUS, W ; Swap STATUS to W (swap avoids changing STATUS)
    clrf STATUS ; Clear STATUS
    movwf ssave ; Save swapped STATUS

    ; Save the FSR value because it gets changed below
    movf FSR0L, W ; Move FSR0 lowbyte to W
    movwf fsave ; Save FSR0 lowbyte
    movf FSR0H, W ; Move FSR0 highbyte to W
    movwf fsave+1 ; Save FSR0 highbyte

    ; Check for hardware overrun error
    btfsc RCSTA1,OERR ; Check for usart overrun
    GoTo usart_err ; jump to assembly error routine

    ; Test for buffer overrun
    incf _index_in, W ; Increment index_in to W
    subwf _index_out, W ; Subtract indexes to test for buffer overrun
    btfsc STATUS,Z ; check for zero (index_in = index_out)
    GoTo buffer_err ; jump to error routine if zero

    ; Increment the index_in pointer and reset it if it's outside the ring buffer
    incf _index_in, F ; Increment index_in to index_in
    movf _index_in, W ; Move new index_in to W
    sublw _Size-1 ; Subtract index_in from buffer_size-1
    btfss STATUS,C ; If index_in => buffer_size
    clrf _index_in ; Clear index_in

    ; Set FSR0 with the location of the next empty location in buffer
    movlw Low _buffer ; Move lowbyte of buffer[0] address to W
    movwf FSR0L ; Move W to lowbyte of FSR0
    movlw High _buffer ; Move highbyte of buffer[0] address to W
    movwf FSR0H ; Move W to highbyte of FSR0

    ; Read and store the character from the USART
    movf _index_in, W ; W must hold the offset value for the next empty location
    movff RCREG1, PLUSW0 ; Move the character in RCREG to address (FSR0+W)


    ; Restore FSR, PCLATH, STATUS and W registers
    finished
    movf fsave, W ; retrieve FSR0 lowbyte value
    movwf FSR0L ; Restore it to FSR0 lowbyte
    movf fsave+1, W ; retrieve FSR0 highbyte value
    movwf FSR0H ; Restore it to FSR0 highbyte
    swapf ssave, W ; Retrieve the swapped STATUS value (swap to avoid changing STATUS)
    movwf STATUS ; Restore it to STATUS
    swapf wsave, F ; Swap the stored W value
    swapf wsave, W ; Restore it to W (swap to avoid changing STATUS)
    retfie ; Return from the interrupt

    ; Error routines
    buffer_err ; Jump here on buffer error
    bsf _errflag,1 ; Set the buffer flag
    usart_err ; Jump here on USART error
    bsf _errflag,0 ; Set the USART flag
    movf RCREG1, W ; Trash the received character
    GoTo finished ; Restore state and return to program

    EndAsm

    '************************************************* ******************************
    Initialize:
    CLEAR
    ADCON1=15
    PIE1.5=1
    INTCON=192

    '************************ Main Loop *************************
    MAIN:
    if(errflag) then error
    if (index_in == index_out) then goto main
    gosub Serial_Receive
    if(Buffer[index_out + 1]="A") && (Buffer[index_out + 2]="D")&&(Buffer[index_out + 3]="R")&&(Buffer[index_out + 4]=",")&&(Buffer[index_out + 5]="G")&&(Buffer[index_out + 6]="E")&&(Buffer[index_out + 7]="T") then gosub GET_ADDRESS

    goto MAIN

    '******************** Serial Receive *************************
    SERIAL_RECEIVE:

    INTCON=0
    index_out=(index_out + 1)
    if(index_out == Size) then index_out=0
    INTCON=192
    return

    '******************** Receive Error *************************
    ERROR:
    INTCON=0
    errflag=0
    CREN=0
    CREN=1
    INTCON=192
    goto main

    '******************** Read Address *************************
    GET_ADDRESS:

    Peek PORTD,Address
    Hserout["ADR,",#address,13]
    return

  2. #2
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by orlandoG View Post
    Hello...Can someone help me out I am using an example I found here: http://www.melabs.com/resources/samples/18F/serA452.bas
    I want to be able to send commands from a PC such as ADR,GET\r and ADR,SET,100\r etc. I just can't figure out how to decode the incoming data.
    The HSERIN command works but its too slow for my application and it hangs up if I try to send multiple commands at the same time.
    The following code works...but not all the time. It seems to miss (i'm assumming the index_out has something to do with it) I don't know assembly language but is there a way to modify the asm routine to read up to a terminating char such as a CR or LF and clear the buffer?
    I'm using an 18F6722 running a 40MHz xtal
    Guaranteed that a '6722 running at 40mhz can surely handle 9600 baud, whether you're using SERIN2/OUT2 or HSERIN/OUT. It's a matter of setting up your timeout values, and getting your program's flow set up correctly so it doesn't look like it's hanging up anywhere.

    As far as reading up to a CR/LF, check your little green manual. You can receive X characters optionally terminating in a specific character using those same serial commands.

Similar Threads

  1. Can't ID interrupt source with this IntHandler??
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 3rd June 2009, 02:35
  2. 18F2480 asm interrupt
    By Richard Storie in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 5th March 2009, 19:40
  3. Serial and interrupt
    By test153 in forum mel PIC BASIC Pro
    Replies: 20
    Last Post: - 8th February 2009, 14:02
  4. Help with Analog Interrupt
    By brid0030 in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 13th February 2008, 18:14
  5. USART interrupt not interrupting right
    By Morpheus in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 6th March 2005, 01:07

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts