|
|
View previous topic :: View next topic |
Author |
Message |
Michael88
Joined: 31 Oct 2003 Posts: 6
|
Question about 16F876 USART |
Posted: Fri Jul 21, 2006 3:51 pm |
|
|
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
|
|
Posted: Fri Jul 21, 2006 3:58 pm |
|
|
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
|
|
Posted: Fri Jul 21, 2006 4:19 pm |
|
|
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
|
|
Posted: Fri Jul 21, 2006 5:05 pm |
|
|
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: 1635 Location: Perth, Australia
|
|
Posted: Fri Jul 21, 2006 6:21 pm |
|
|
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
|
Thanks, |
Posted: Mon Jul 24, 2006 9:38 am |
|
|
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 |
|
|
|
|
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
|