CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Question about 16F876 USART

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Michael88



Joined: 31 Oct 2003
Posts: 6

View user's profile Send private message

Question about 16F876 USART
PostPosted: Fri Jul 21, 2006 3:51 pm     Reply with quote

Hi all,

I used " #use rs232 ( baud = 19200, xmit=pin_c6, rcv = pin_c7, errors) " to setup my com port. The problem is that if incoming data is too large, the receiver will be locked up. Even watchdog or reset_cpu() does not help. Any suggestion to release com port from locked up?

Thank you!

Michael
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 21, 2006 3:58 pm     Reply with quote

If you have the ERRORS directive in the #use rs232() statement,
then any overrun condition should be detected and cleared by the
code inserted by the compiler. If this is not happening, then post
a small test program that shows the problem. Keep the program
very small. (Do not post a 200 line program). Show all #include,
#use, and #fuses statements. The program should be compilable
as posted.

Also post your compiler version. This will be a number such as
3.191, 3.236, or 3.249, etc.
Michael88



Joined: 31 Oct 2003
Posts: 6

View user's profile Send private message

PostPosted: Fri Jul 21, 2006 4:19 pm     Reply with quote

Thanks PCM.

My compiler version is 3.072. like you said, I'd like to write a small test program to do more test. The hard thing is that problem happened in the filed maybe once a month or weeks. In my code, there are some operations like writting to the EEPROM and NVRAM. It most likely the problem happened during the NVRAM and EEPROM writting. I do not think the test code will be less than 200 lines.
What I do not understand is that even I used watchdog and reset_cpu(), it still does not work, unless I use a jump to reset cpu.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 21, 2006 5:05 pm     Reply with quote

How do you know for sure that the UART receiver is locking up ?
Have you tested this in your lab ? Can you duplicate the field problem ?

I'm wondering if it's something else. Does this unit run continuously
or is it turned on and off ? What sort of power supply is used ?
If the voltage dropped, potentially the PIC could act in a flaky manner.
That's why the BROWNOUT fuse would help to fix this problem. Do you
have it enabled ? Also, do you have the PUT fuse enabled ?

Another thing that can cause random lockups is a missing NOLVP fuse,
or a floating MCLR pin (i.e., no pull-up resistor), or the lack of bypass
caps on the Vdd pins.

One more thing -- I don't have PCM vs. 3.072. I do have vs. 3.068.
I installed it and looked at the code generated by the compiler to handle
overrun errors, and it's identical to the code in the latest version, 3.249.
So it's likely that 3.072 is the same. Here is the code for 3.068:
Code:

0036        00241 BTFSS  0C.5   Wait in loop for RCIF high
0037        00242 GOTO   036

0038        00243 MOVF   18,W   Read RCSTA
0039        00244 MOVWF  28     Save it

003A        00245 MOVF   1A,W   Read RCREG
003B        00246 MOVWF  78     Save it

003C        00247 BTFSS  28.1   Skip if got OERR
003D        00248 GOTO   040    Jump to 040 if no OERR
003E        00249 BCF    18.4   Disable the receiver
003F        00250 BSF    18.4   Re-enable it
0040        00251 NOP
0041        00252 BCF    0A.3
0042        00253 BCF    0A.4
0043        00254 GOTO   045 (RETURN)
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Fri Jul 21, 2006 6:21 pm     Reply with quote

Michael88 wrote:

What I do not understand is that even I used watchdog and reset_cpu(), it still does not work, unless I use a jump to reset cpu.


When writing to on chip EEPROM the code disables interrupts (The PIC requires this) It can take several milliseconds to write to the EEPROM and the result is that it is possible and likely that over time an overrun error will occur locking up the UART. The errors flag is supposed to put the code in place to handle this.

It is possible for a poorly coded serial handler to make matters worse. Consider the following scenario: a serial handler inputs a seriers of characters from the serial port into a target buffer until it detects a <CR> character. Normally the message it receices is eight buyes long. To play it safe the programmer declared a 10 byte target array. Every thing is working fine - so far we have 7 characters in the array and the next should be the <CR> however at this time we write to EEPROM and as a result the <CR> and a couple of characters following are missed. The CCS code correctly detects the Serial port is locked up and clears and resets the SPEN bit enabling the serial port. The handler continues accepting characters however it alreeady had several characters in the buffer and it now accepts another 8. Here we have overrun the buffer space corrupting other application variables.

Why does the WDT not work? I wonder if you have RESET_WDT as one of the options in the #use delay directive. If so there is a good chance this is the problem. If your code wonders off into some branch it should not have done (as a result of a decision based on the variables being corrupted) and that code fragment uses any delay function then the WDT will be being coninuously reset.

My rule of thumb with WDT is NEVER enable the RESET_WDT in the #use delay directive. If your delays are that long then replace the delay code with a timer based alternative.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Michael88



Joined: 31 Oct 2003
Posts: 6

View user's profile Send private message

Thanks,
PostPosted: Mon Jul 24, 2006 9:38 am     Reply with quote

Thanks PCM and Andrew,

To PCM:

The reason that I think the UART receiver is locked up is that because everything (including timer, IO ports etc) works fine except UART. I tried to increase data flow by hundred times in my lab and duplicated the field problem in minutes instead of weeks in the filed.

This unit should run continuously all the time. We use battery plus charger supply the power. So the voltage should be no drop.

The FUSE I used in my code is
"#fuses HS,WDT,PUT,NOPROTECT,BROWNOUT,NOLVP,NOCPD,WRT"

I will check my code and hardware as your suggestions and do more test.
Thanks so much!

To Andrew,

I think you are right. I just know that I need disable interrupts when writing to on chip EEPROM.
Two tests I did this morning:
1, Turn off GIE before writting to the EEPORM and turn on again after writting. The problem is still there.
2, Turn off UART before writting to the EEPORM and turn on again after writting. Seems it works fine. So I will consider this as a temporary solution.

Maybe I did not explain my question about WDT clearly. When the problem happened, The WDT can reset the PIC, but the UART receiver is still locked up untill I used a jumper to hardware reset The PIC. So my question is why the code already restarted but UART was still locked up?

Thanks again!

Regards, Michael
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group