Interrupt driven Buffered Serial Input


Closed Thread
Results 1 to 16 of 16

Hybrid View

  1. #1
    Join Date
    May 2007
    Posts
    17

    Default Interrupt driven Buffered Serial Input

    Hi, I'm going mad for the past few days here since my interrupts are not working. I am trying to make a interrupt driven buffered serial input but without success since my program doesn't do anything when it should deal with the interrupts (it just stays on that "While CounterA <= 70 : WEND" forever) (nothing is printed out when I send something to it's serial port). Here is my code (part of it at least that deals with the serial part)

    Code:
        DEFINE OSC 20
        
        DEFINE HSER_TXSTA 24h
        DEFINE HSER_RCSTA 90h
        DEFINE HSER_BAUD 19200
        DEFINE HSER_SPBRG 64 ' 19200 Bauds
        DEFINE HSER_CLROERR 1
    
        RCIF	VAR	PIR1.5		' Alias RCIF (USART Receive Interrupt Flag)
        OERR	VAR	RCSTA.1		' Alias OERR (USART Overrun Error Flag)
        CREN	VAR	RCSTA.4		' Alias CREN (USART Continuous Receive Enable)
        LED     VAR	PORTD.0 	' Alias LED to PORTD.0
    
        buffer_size	CON	32		' Sets the size of the ring buffer
        buffer	VAR	BYTE[buffer_size]	' Array variable for holding received characters
        index_in	VAR	BYTE	' Pointer - next empty location in buffer
        index_out	VAR	BYTE	' Pointer - location of oldest character in buffer
        bufchar	VAR	BYTE		' Stores the character retrieved from the buffer
        i		VAR	BYTE		' loop counter 
        errflag	VAR	BYTE		' Holds error flags
    
        CMCON=%00000111		' Disable Comparators
        TRISA=%00000000		' PORTA all set to Output 
        TRISB=%11111111		' PORTB all set to Input
        T0CON=%00000111     ' OFF,16BIT,PRESCALE=256
        ADCON0 = 0
        CMCON=7
        INTCON.5=1          'T0IE : TMR0 Overflow Interrupt Enable bit
    
    ON interrupt GOTO GestIntrerupts        ' Deal with interrupts
    
    ReadSerial:
       DataRec var byte[5] : DataRec = 0
       PIE1.5 = 1   			' Enable interrupt on USART
       While CounterA <= 70 : WEND
       PIE1.5 = 0				' Disable interrupt on USART
            
       FOR COUNTERB=0 to COUNTERA
            SEROUT2 SerWRT,16416,[SerDATA(COUNTERB)]
            NEXT COUNTERB
    
       Goto ReadReadyLoop 
    
    
    ' Subroutines
    Disable					' Don't check for interrupts in this section
    
    getbuf:					' move the next character in buffer to bufchar
    	index_out = (index_out + 1)			' Increment index_out pointer (0 to 63)
    	IF index_out > (buffer_size-1) Then index_out = 0	' Reset pointer if outside of buffer
    	bufchar = buffer[index_out]			' Read buffer location
    Return
    
    error:					' Display error message if buffer has overrun
    	errflag = 0			' Reset the error flag
    	CREN = 0			' Disable continuous receive to clear overrun flag
    	CREN = 1			' Enable continuous receive
    	GoTo display		' Carry on
    
    buffer_error:
    	errflag.1 = 1		' Set the error flag for software
    ' Move pointer back to avoid corrupting the buffer. MIN insures that it ends up within the buffer.	
    	index_in = (index_in - 1) MIN (buffer_size - 1)	
    	HSerin [buffer[index_in]]	' Overwrite the last character stored (resets the interrupt flag)
    
    usart_error:
    	errflag.0 = 1		' Set the error flag for hardware
    Resume					' Return to program
    
    GestIntrerupts:
        IF INTCON.2 = 1 then
            T0CON.0 = 0 ' Disable timer
            TMR0L = 0   ' Reset timer
            TMR0H = 0   ' Reset timer
            TimeCount = TimeCount + 1
            T0CON.0 = 1 ' Enabled timer
            INTCON.2 = 0
        ELSE : IF RCIF = 1 THEN
            IF OERR Then usart_error			' Check for USART errors
    	    index_in = (index_in + 1)			' Increment index_in pointer (0 to 63)
    	    IF index_in > (buffer_size-1) Then index_in = 0	'Reset pointer if outside of buffer
    	    IF index_in = index_out Then buffer_error	' Check for buffer overrun
    	    HSerin [buffer[index_in]]			' Read USART and store character to next empty location
            SEROUT2 SerWRT,16416,[buffer(index_in)]
            SerData(CounterA)=buffer(index_in)
            CounterA = CounterA + 1	    
    	    IF RCIF Then GestIntrerupts   		' Check for another character while we're here 
        ENDIF : ENDIF
        resume
    ENABLE
    Any input is appreciated!
    Last edited by johnmiller; - 10th May 2007 at 18:06.

  2. #2
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Code:
    DISABLE before here
    ENABLE after your interrupt subroutine
    Jump over your interrupt subroutine with a Goto Main or something
    ON interrupt GOTO GestIntrerupts        ' Deal with interrupts
    ReadSerial:
       DataRec var byte[5] : DataRec = 0 : PIE1.5 = 1
       While CounterA <= 70 : WEND
       PIE1.5 = 0				' Disable interrupt on USART
       FOR COUNTERB=0 to COUNTERA:SEROUT2 SerWRT,16416,[SerDATA(COUNTERB)]:NEXT COUNTERB
       Goto ReadReadyLoop 
    Not really a good idea inside an interrupt subroutine
    ' Subroutines
    Disable				' Don't check for interrupts in this section
    getbuf:				' move the next character in buffer to bufchar
    index_out = (index_out + 1):IF index_out > (buffer_size-1) Then index_out = 0
    bufchar = buffer[index_out]:Return
    error:     errflag = 0:CREN = 0:CREN = 1:GoTo display		' Carry on
    buffer_error:
    errflag.1 = 1:index_in = (index_in - 1) MIN (buffer_size - 1):HSerin [buffer[index_in]]
    usart_error:     errflag.0 = 1		' Set the error flag for hardware
    Resume					' Return to program
    GestIntrerupts:
    IF INTCON.2 = 1 then
    T0CON.0 = 0:TMR0L = 0:TMR0H = 0:TimeCount = TimeCount + 1:T0CON.0 = 1:INTCON.2 = 0
    ELSE COLON isn't needed but IF RCIF = 1 THEN moved to next line is needed : IF RCIF = 1 THEN
    IF OERR Then usart_error			' Check for USART errors
    index_in = (index_in + 1):IF index_in > (buffer_size-1) Then index_in = 0
    IF index_in = index_out Then buffer_error	' Check for buffer overrun
    HSerin [buffer[index_in]]:SEROUT2 SerWRT,16416,[buffer(index_in)]:SerData(CounterA)=buffer(index_in)
    CounterA = CounterA + 1	    
    IF RCIF Then GestIntrerupts   		' Check for another character while we're here 
    ENDIF : ENDIF
    resume
    ENABLE
    Where is your main loop?
    You're using HSerIn with interrupts. HSerIn will wait for the NEXT character into the USART receive register after the interrupt trips.
    Lots of little problems with this code...rework it a bit, straighten it out, actually READ thru it from top to bottom and see how it executes, repost, and we'll work it from there...
    Last edited by skimask; - 10th May 2007 at 18:35.

  3. #3
    Join Date
    May 2007
    Posts
    17


    Did you find this post helpful? Yes | No

    Default

    Well how would you suggest me to do it? Should I use serin2 instead of hserin?
    I need it to be a interrupt driven buffer serial read since if I send the data too quickly it just discards some data. I tried to read the date with serin, serin2 and now hserin. My only problem now is
    Code:
       PIE1.5 = 1          ' Enable interrupt on USART
       While CounterA <= 70 : WEND
       PIE1.5 = 0		   ' Disable interrupt on USART

  4. #4
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by johnmiller View Post
    Well how would you suggest me to do it? Should I use serin2 instead of hserin?
    Any one of the SerIn functions can catch data very quickly, even at 19,200 and much higher. It mostly depends on how much time you actually need to process that data once received. Like I said, re-read thru your code, figure out what you really NEED vs. what you want to do. Write down a 'quick-n-dirty' flowchart of how you want/need things to work.
    What are you buffering the serial port for?
    Is this a FIFO or a LIFO type buffer (probably FIFO type)?
    What is the main function of the program going to be? What is this program going to do for you?

  5. #5
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    1. i don't see any PIC #
    2. i don't see any config fuses.
    3. I don't see any INTCON and other interrupt related registers

    Fast reading of your code but it may work. now just comment out your whole ISR and toggle a led in and then clear RCIF falg by reading RCREG untill it's empty.

    Is the thing work or not? If not, your baudrate, config fuses and or hardware is faulty.

    Easier way, HSERIN/HSEROUT to echo your incomming data to you PC.

    Is this working or not?
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  6. #6
    Join Date
    May 2007
    Posts
    17


    Did you find this post helpful? Yes | No

    Default

    Well my program needs to read the data from a serial connection and than it should save that data into a string. The only problem that I have is that if the date comes too quickly the PIC just discards that data. Any ideea why is that?

  7. #7
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Possibly because you are sending anything received back out at the same speed within the interrupt handler.

    You should get in and out of the handler as quick as possible.
    Then let the mainloop empty the buffer when it has time.
    Preferably at a higher speed.

    Also, T0CON is different than T1CON.
    TMR0ON is bit 7, and bit 0 is part of the prescaler setting.
    <br>
    DT

Similar Threads

  1. Won't go back to SLEEP after 1st Interrupt
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 32
    Last Post: - 29th June 2009, 09:00
  2. 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
  3. 18F2480 asm interrupt
    By Richard Storie in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 5th March 2009, 19:40
  4. Serial Question + General Review
    By Freman in forum General
    Replies: 2
    Last Post: - 20th June 2008, 22:27
  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 : 0

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