PIC16F88 HSERIN to LCD Problem


Closed Thread
Results 1 to 10 of 10

Hybrid View

  1. #1
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    The BIG problem with your particular app is that LCDOUT is just too darn slow to keep up with a continuous incoming stream of serial data at 9600 bps. And were's why...

    At 1200 baud it takes longer for the hardware USART FIFO buffer to fill. This gives you more time for LCDOUT to finish before the 3rd byte is clocked into the hardware USART, which causes a buffer overrun error, and the USART simply stops receiving data.

    At 9600 baud it takes less time to overrun - so you end up with missed characters at the higher baud rate.

    So - if your inbound serial data stream takes < time than it takes to output the string to your LCD, it's just not going to work.

    A couple of options might be to wait until a serial data input array is filled, then send whatever's in the buffer to your LCD, or setup an interrupt to receive characters in the background, then output to the LCD.

    Either way - you'll still want some control over the sending device so you have time to handle sending everything to your LCD, which is going to be a good deal slower than receiving serial data at 9600 bps.

    Check the Receive Overrun Error section of the data sheet for a full explanation.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  2. #2
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    Ah Say, Ugh, Lookie Here !
    http://www.picbasic.co.uk/forum/showthread.php?t=4972 Darrel's post 16, you alter it to fit that 88 chip and you got it. Use a pullup resistor on the Rx line. Ring Buffer up to 64 bytes.
    Last edited by Archangel; - 3rd June 2009 at 02:15.
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  3. #3
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Yep. The priority event with the hardware USART is to read or empty the FIFO buffer before it overruns. LCDOUT can handle being interrupted and never appear to miss a beat if you keep the int handler short & sweet.

    And, of course, DT ints make it all relatively painless for the newbie....;o}
    Last edited by Bruce; - 3rd June 2009 at 02:28.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  4. #4
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Bruce View Post
    And, of course, DT ints make it all relatively painless for the newbie....;o}
    Even for newbies into their 3rd year as a newbie . . .
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  5. #5
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Even for newbies into their 3rd year as a newbie . . .
    Heck yes. I'm still a newbie myself....;o}
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  6. #6
    Join Date
    Jun 2009
    Posts
    4


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Joe S. View Post
    Ah Say, Ugh, Lookie Here !
    http://www.picbasic.co.uk/forum/showthread.php?t=4972 Darrel's post 16, you alter it to fit that 88 chip and you got it. Use a pullup resistor on the Rx line. Ring Buffer up to 64 bytes.
    Thanks very much Joe,

    That code looks promising on "post 16", I’ll give it a try and let you know how it goes.

    Thanks,
    robbrownuk

  7. #7
    Join Date
    Jun 2009
    Posts
    4


    Did you find this post helpful? Yes | No

    Thumbs up Success!

    Thanks again Joe. That code worked very well and of course thanks to Darrel Taylor for his DT_INTS code.

    The final code is posted here should anyone need it:

    Code:
    '-------------------------------------
    ' STARTUP CODE
    '-------------------------------------
    
    'MPASM generates an warning because of tabs around the macro (this prevents it)
    @ errorlevel -207
    
    'Config settings for MPASM
    @ __CONFIG _CONFIG1, _HS_OSC & _CP_OFF & _WDT_OFF & _PWRTE_ON & _MCLR_ON & _BODEN_OFF & _LVP_OFF & _CPD_OFF & _DEBUG_OFF & _CCP1_RB0
    
    'Using a 20Mhz XTAL
    define OSC 20
    
    'Register setup
    ADCON1 = %00000111          ' Disable A/D converter
    ANSEL = %00000000           ' all analog pins to digital
    CCP1CON = %00000000         ' Disable CCP Module
    CMCON = %00000111           ' Turn off comparator
    INTCON = %00000000          ' Interrupts disabled
    
    'Setup & Clear the ports
    TRISA = %00000000           'All O/P's
    TRISB = %00001101           'All O/P's
    PORTA = 0                   'Zero PortA O/P's
    PORTB = 0                   'Zero PortB O/P's
    
    '-----------------------------------------------------------------------------
    INCLUDE "DT_INTS-14.bas"
    INCLUDE "ReEnterPBP.bas"     ; Include if using PBP interrupts
    
    ASM
        INT_LIST  macro   ; IntSource,  Label,          Type,       ResetFlag?
            INT_Handler    RX_INT,      _INT_Serin,     PBP,        no
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    @   INT_ENABLE   RX_INT     ; enable external (INT) interrupts
    '-----------------------------------------------------------------------------
    
    'Setup the hardware USART for 9600 baud
    DEFINE HSER_RCSTA 90h       ' Enable serial port & continuous receive
    DEFINE HSER_TXSTA 24h       ' Enable transmit, BRGH = 1
    DEFINE HSER_SPBRG 129       ' 9600 Baud @ 0.16%
    DEFINE HSER_CLROERR 1       ' Clear overflow automatically
    
    'Define the LCD
    Define LCD_DREG PORTA
    DEFINE LCD_DBIT 0
    DEFINE LCD_RSREG PORTB
    DEFINE LCD_RSBIT 0
    DEFINE LCD_EREG PORTA
    DEFINE LCD_EBIT 4
    DEFINE LCD_BITS 4
    DEFINE LCD_LINES 2
    DEFINE LCD_COMMANDUS 1500
    DEFINE LCD_DATAUS 50
    
    'Alias & Vars
    RCIF VAR PIR1.5             ' Receive  interrupt flag (1=full , 0=empty)
    TXIF VAR PIR1.4             ' Transmit interrupt flag (1=empty, 0=full)
    OERR VAR RCSTA.1            ' Alias OERR (USART Overrun Error Flag)
    CREN VAR RCSTA.4            ' Alias CREN (USART Continuous Receive Enable)
    BufMax CON 64               ' Sets the size of the ring buffer, set up from 32
    Buffer VAR BYTE[BufMax]     ' Array variable for holding received characters
    Ptr_in VAR BYTE             ' Pointer - next empty location in buffer
    Ptr_out VAR BYTE            ' Pointer - location of oldest character in buffer
    Bufchar VAR	BYTE            ' Stores the character retrieved from the buffer
    ErrFlag VAR	BYTE            ' Holds error flags
    ptr_in = 0                  ' Clear buffer pointer (in)
    ptr_out = 0                 ' Clear buffer pointer (out)
    Errflag = 0                 ' Clear error flag
    
    'Skip over the interupt handler & subroutines
    goto ShowSplash
    
    '-------------------------------------
    ' INTERUPT HANDLER
    '-------------------------------------
    
    INT_Serin:                  ' Serial Interrupt routine
    
    IF OERR Then usart_error	' Check for USART errors
    ptr_in = (ptr_in + 1)       ' Increment ptr_in pointer (0 to 63)
    IF ptr_in > (BufMax-1) Then ptr_in = 0	'Reset pointer if outside of buffer
    IF ptr_in = ptr_out Then Buffer_Error	' Check for buffer overrun
    HSerin [buffer[ptr_in]]	    ' Read USART and store data in next empty location
    IF RCIF Then INT_Serin		' Check for another character while we're here
    @ INT_RETURN   		        ; Return to program
    
    Buffer_Error:               ' Error - Run out of buffer space
    
    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.	
    ptr_in = (ptr_in - 1) MIN (BufMax - 1)	
    HSerin [buffer[ptr_in]]	    ' Overwrite the last data stored (clear the int.)
    
    USART_Error:                ' Error - USART has overrun (data too fast?)
    
    errflag.0 = 1               ' Set the error flag for hardware	
    @ INT_RETURN   		        ; Return to program
    
    
    '-------------------------------------
    ' Subroutines
    '-------------------------------------
    GetBuf:					    ' move the next character in buffer to bufchar
    
    @ INT_DISABLE  RX_INT       ; Dont want to interupt this, Disable interupts
    
    ptr_out = (ptr_out + 1)     ' Increment ptr_out pointer (0 to 63)                           
    IF ptr_out > (BufMax-1) Then ptr_out = 0  ' Reset pointer if outside of buffer	
    bufchar = buffer[ptr_out]   ' Read buffer location
    
    @ INT_ENABLE  RX_INT        ; All done, Enable interupts
    Return
    
        
    '-------------------------------------
    ' SPLASH SCREEN
    '-------------------------------------
    ShowSplash:
    
    pause 60   'Power up delay
    
    'Display a splash screen for 2 seconds
    LCDOUT $FE,1,"RS232 to LCD"
    LCDOUT $FE,$C0,"Display Test"
    pause 2000
    
    'Now ready for COMMS...
    LCDOUT $FE,1,"Waiting for PC"
    LCDOUT $FE,$C0,"to send data..."
    
    '-------------------------------------
    ' RS232 TO LCD
    '-------------------------------------
    MainLoop:
    
    IF errflag Then ErrorHandler	      ' Handle error if needed
    IF ptr_in = ptr_out Then MainLoop	  ' loop if nothing in buffer
    
    GoSub getbuf        ' Get a character from buffer (stored in bufchar)	        	
    LCDOut bufchar      ' Send the character to LCD	        
    
    goto MainLoop       'Loop forever
    
    '-------------------------------------
    ' Error Handler
    '-------------------------------------
    ErrorHandler:
    
    ' Display error message if buffer has overrun
    IF errflag.1 Then	                  ' Determine the error
        LCDOut $FE,$1,"Buffer Overflow"   ' Display buffer error
    Else
        LCDOut $FE,$1,"USART Overrun"	  ' Display usart error
    EndIF
    		
    errflag = 0			' Reset the error flag
    CREN = 0			' Disable continuous receive to clear overrun flag
    CREN = 1            ' Enable continuous receive
    
    GoTo MainLoop       ' Errors cleared, time to work.

Similar Threads

  1. Newbie? Problem with LCD
    By lew247 in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 7th December 2009, 19:48
  2. RX TX modules - intermitent communication
    By ruijc in forum mel PIC BASIC Pro
    Replies: 13
    Last Post: - 11th June 2009, 00:13
  3. PIC HSERIN problem
    By shaiqbashir in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 20th July 2008, 11:08
  4. LCD Problem
    By karenhornby in forum General
    Replies: 3
    Last Post: - 19th June 2008, 11:43
  5. Replies: 8
    Last Post: - 7th December 2006, 15:42

Members who have read this thread : 1

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

Tags for this Thread

Posting Permissions

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