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


Closed Thread
Results 1 to 10 of 10
  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!

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


    Did you find this post helpful? Yes | No

    Smile

    Hi cncmachineguy

    OOOps !. I have been reading that section of the datasheet over and over again but it didn't click until you highlighted it so I have removed the:-
    Code:
    if PIR1.5 = 1 then 
    Hserin 1,jump,[MI]                                      ' Read a character and clear buffer
    jump:                  
    gosub gratio
    endif
    and replaced by using a "dummi" variable to read RCREG as follows
    Code:
    if PIR1.5 = 1 then 
    dummi = RCREG                              ' Read a character and clear buffer
    gosub gratio
    endif
    That seems to work ok.

    Thanks again

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


    Did you find this post helpful? Yes | No

    Default

    Very likely this is what you need! But I thought you should have control on the direction of your program flow. In this way any byte received will direct you to the gosub indicated and this could also happen out of your control. I personally would have identified the byte received and if the byte was the correct jump_byte then the program could proceed with the jump, any other bytes would be ignored.

    But as I just said above, if this is what you need and you are happy with it, why changing it.

    Al.
    All progress began with an idea

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


    Did you find this post helpful? Yes | No

    Default

    Al, I like your way. But I guess it really depends on what you want to do with the byte. In my upcoming app, I will need something simular to what you have suggested. Just one more reason to LOVE this place. Multiple ways to solve a problem, some better then others depending on the app.
    -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!

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


    Did you find this post helpful? Yes | No

    Default

    Hi all

    I agree that identifying the byte received is beneficial and I have considered using that feature, but I only need (at the moment) to identify when the CCP1 capture has reached a specific point determined by my PC program. When this point is reached I have a requirement for both CCP1 and CCP2 to be sampled for a short period after which it should return to the original gosub measuring CCP1 only. When I have a need to stop and return to my small menu then I currently do that with a button press at PortA.5.

    This is at the moment though because both PIC and PC programs will evolve, I dare say in the future I will allow my PC program to have more control over what the PIC does. I am currently learning lots of new things so I tend to go slowly.

    Anyway thanks for the suggestions and I agree its a good job there are guys like yourselves around to help..... Keep up the good work.

    Chris...........

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