Parse Strings from (Assembly) Serial Interrupt



THE BOOK of DT's INTERRUPTS is an organization of interrupt service routines and other works written by Darrel Taylor, RIP.

Interrupt routines are arranged per Darrel's original list. Darrel Taylor's Instant Interrupts are an extension of the work of Tim Box whom in October of 2002 wrote INT_CTRL.pbp

Many of the forum members felt this is a long overdue project.

THE BOOK of DT's INTERRUPTS
will be a valuable resource and a tribute to Darrel Taylor the "Fanatical Contributor".

THE BOOK of DT's INTERRUPTS is located at http://dt.picbasic.co.uk/

+ Reply to 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

Posting Permissions

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