Help with stopping a loop with a serial receive on 16F876.


Closed Thread
Results 1 to 10 of 10

Hybrid View

  1. #1
    Join Date
    Dec 2010
    Location
    Colchester England
    Posts
    20

    Default Help with stopping a loop with a serial receive on 16F876.

    Greetings

    Can any one assist me in a small problem (I think!). I have code for a 16F876, using MCS and PBP, that in one section captures CCP1 in a constant loop and sends the result out through the USART port (HERSOUT). In order to stop this looping I utilise a button press on PortA.5, but what I am looking to try and do is stop this looping code when a single character is received at the PIC USART from my PC.
    I have been looking at various registers hoping for some kind of bit change that would indicate a character has just been received, but the only bit regarding receiving data seems to be PIR1.5. This though is “The USART receive buffer is full” bit, so unless I sent lots of characters I am not sure this is what I am looking for?.

    A point in the right direction as where to look for an answer would be greatly appreciated.

    Below is part of my code:

    Code:
    DEFINE OSC 20
    DEFINE ADC_BITS 10                      ' Number of bits in ADCIN result
    DEFINE ADC_CLOCK 3                      ' ADC clock source (rc = 3)
    DEFINE ADC_SAMPLEUS 20                  ' ADC sampling time in microseconds
    
    DEFINE HSER_BAUD 115200
    DEFINE HSER_CLROERR 1                   ' Automatically clear over-run errors
    DEFINE HSER_SPBRG 10                    ' 20 = 57600 . 21 may be option. 115200 = 10
    DEFINE HSER_RCSTA 90h                   ' Enable USART receive
    DEFINE HSER_TXSTA 24H                   ' Set TXSTA to allow for higher baud rate 
    
    TRISA = %11111111                       ' PortA all inputs
    TRISC = %11111111                       ' PortC all inputs
    ADCON1 = %10000100                      ' Set PORTA analog
    ADCON0 = %00000001                      ' Configure and turn on A/D Module
    PIE1.0 = 1                              'enables the tmr1 overflow interrupt 
    
    capture VAR PIR1.2			            ' CCP1 capture flag
    capture2 var PIR2.0                     ' CCP2 capture flag
    overflow VAR PIR1.0                     ' Timer1 overflow flag
    OERR    VAR RCSTA.1                     ' Alias USART over-run bit
    CREN    VAR RCSTA.4                     ' Alias USART continuous receive enable bit
    ExhTemp var word                        ' AFM input
    AirTemp var word                        ' Air Temp Sensor Input
    period var Word                         ' Pulse 1 Rising edge trigger
    period2 var word                        ' Pulse 2 Rising edge trigger
    MI var word                             ' Serial Input character
    I var word                              ' Loop variable
    mycount var word
    
    
    menuselect:
    Hserin [MI]                             ' Wait for Character input to start
    if MI = "A" then gosub About
    if MI = "S" then gosub sloop
    if MI = "G" then gosub gratio
    if MI<>"A" or "S" or "G" then goto menuselect
    goto menuselect
    
    sloop:
    
    T1CON = %00100000                       ' TMR1 prescale=1:4 Timer OFF _ %00010000 1:2
    TMR1H = 0                               ' Zero the Timer High
    TMR1L = 0                               ' Zero the Timer Low
    capture = 0
    CCP1CON = %00000110                     ' Every 4th = 00000110. Every = 00000101
    StartLoop:
    IF (capture = 0) Then StartLoop      	' Wait here for the first capture
        T1CON.0 = 1                         ' Start the Timer
        capture = 0                         ' Reset  the capture flag
    CaptureLoop:
    	IF (capture = 0) Then CaptureLoop	' Wait here until captured
    	period.lowbyte = CCPR1L	           	' Store the captured value in
    	period.highbyte = CCPR1H	        ' period variable
    T1CON.0 = 0                             ' Turn off Timer1
    
    if PIR1.0 = 1 then                      ' Check for Timer1 overflow
    period2 = 65535
    PIR1.0 = 0 
    endif
    Hserout [DEC5 period,DEC5 period2,"T",13,10]
    IF PORTA.5 = 0 THEN return               ' If PORTA, pin 5 is low (0), return to menu
    
    “This where I would like to check for USART receive”
    
    period2 = 0
    GoTo sloop					             ' Do until signal to stop or do something else
    Many thanks and Merry Christmas.

  2. #2
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    RCIF

    As I understand it, this flag should get set when there is a received byte in the buffer.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  3. #3
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default

    Hserout [DEC5 period,DEC5 period2,"T",13,10]
    'IF PORTA.5 = 0 THEN return ' If PORTA, pin 5 is low (0), return to menu

    HSERIN 100, skip,[MI]

    “This where I would like to check for USART receive”

    If MI = "Z" then return
    Skip:


    period2 = 0
    GoTo sloop

    If you want to get out of the subroutine when you receive a byte (I used "Z" but you can use any byte) the above three lines of code will solve the problem. I have used a timeout of 100 millisecs but you can short it if too long for your need.

    Merry Christmas to you too.

    Al.
    All progress began with an idea

  4. #4
    Join Date
    Dec 2010
    Location
    Colchester England
    Posts
    20


    Did you find this post helpful? Yes | No

    Wink

    Thanks to both of you.

    I will be trying both methods as soon as I can and report back.

    Thanks for your quick response's

  5. #5
    Join Date
    Dec 2010
    Location
    Colchester England
    Posts
    20


    Did you find this post helpful? Yes | No

    Default Sorted

    Hi

    As a follow up I have used a combination of both suggestions.

    I have to say that watching PIR1.5 (RCIF suggested by cncmachineguy)for a change is my preferred method of checking for a character received in the USART buffer. This seems to cause me less problems with my CCPx capture i.e. less time delay. Unfortunately the down side is that it is read only and I have not found a way (yet!) to reset/clear the USART buffer by using the registers. So I have utilised the HSERIN, with a small timeout, command as aratti suggested. Using this then clears the USART buffer and appears to work fine.

    Code:
    if PIR1.5 = 1 then 
    Hserin 1,jump,[MI]           ' 1mS timeout then read the character and clear buffer
    jump:                        ' Character is any because it is only used as an interupt
    gosub gratio
    endif
    Thanks again much appreciated......

  6. #6
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Ceetee View Post
    Unfortunately the down side is that it is read only and I have not found a way (yet!) to reset/clear the USART buffer by using the registers.

    From datasheet:
    Flag bit RCIF is a read-only bit which is
    cleared by the hardware. It is cleared when the RCREG
    register has been read and is empty
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

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