PDA

View Full Version : Help with stopping a loop with a serial receive on 16F876.



Ceetee
- 24th December 2010, 15:52
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:



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.

cncmachineguy
- 24th December 2010, 16:27
RCIF

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

aratti
- 24th December 2010, 17:13
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.

Ceetee
- 24th December 2010, 21:36
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
:)

Ceetee
- 26th December 2010, 19:43
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.



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......

cncmachineguy
- 27th December 2010, 14:45
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

Ceetee
- 27th December 2010, 17:37
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:-


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


if PIR1.5 = 1 then
dummi = RCREG ' Read a character and clear buffer
gosub gratio
endif


That seems to work ok.

Thanks again :rolleyes:

aratti
- 27th December 2010, 21:39
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.

cncmachineguy
- 27th December 2010, 22:18
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. :)

Ceetee
- 28th December 2010, 19:48
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...........