Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC 16F873 resetting by itself?

Status
Not open for further replies.

nclark

New Member
Let's get the technical bits out right away...

I have a project that uses a PIC 16F873, it uses the TMR0 with interrupt to calculate time with a prescaller of 111 (1:256), it also uses 3 ADCs on the chip to monitor voltages. I have a menu system with a 2x20 LCD, 4 LED ports and 4 switches with external pull-ups. I'm running at 4Mhz with an oscillator crystal. I have a pull-up 1k resistor on the MCLR pin that goes trough a 1N4148 diode so I can do ICSP without using a switch. I also have a 1N4148 diode on the +5V supply on pin 20 for the same reason.

Here are the settings used when programming the fuses:

Code:
__config _HS_OSC & _CP_OFF & _WDT_OFF & _PWRTE_ON & _DEBUG_OFF & _WRT_ENABLE_OFF & _BODEN_OFF & _LVP_OFF

Here is the problem, when I leave the project running for a while at any of the sub-menus, either ones wich poll the ADCs and switches or the menus where only the switches are checked for a keypress. The chip just seems to reset and will be at the main startup menu when I return to the project after a few hours. I also tried using XT setting for the oscillator but with same result.

I'm stumped and just can't find why it does this?

Please help with any sugestions,
Nelson
 
First make sure that LVP and watchdog timmer is off.
Then try a 10K pullup only on MCLR, and see if your circuit is causing it.

Good luck
Kent
 
The diodes isn't necessary for most programmers, and is a messy solution with the possibility of creating serious problems. There's like a dozen reasons why you shouldn't do this (starting with the theoretical ability to blow out your pins). And putting a diode after a reg is totally unnecessary, the ones I tested can only source current anyways. Ditch both of them. Just keep the circuit powered externally and having two 5V sources should still be fine.

16F873 was made with different frequency capabilities. However, they are rated @5V, max freq goes down when Vdd is under 5V. You've dropped Vdd to 4.3V.
 
First make sure that LVP and watchdog timmer is off.
Then try a 10K pullup only on MCLR, and see if your circuit is causing it.

LVP and WDT are both off, verified them also by reading back the chip settings. I tried 10K, 1K and direct connection of the MCLR all with the same result!


The diodes isn't necessary for most programmers, and is a messy solution with the possibility of creating serious problems.

I removed both of them to test it out and the chip reseted after about 2 1/2 hours anyway. The frequency of the oscillator did go back to it's rated frequency but this had been corrected in my software by using a frequency counter and adjusting a 1 second count anyway.

I think I read somewhere in a Microchip datasheet to use a diode when doing ICSP so not to power the entire circuit but I might be mistaking, I will research this further and let you know with a reference if I can find it! I really don't like powering the LCD and other stuff around the circuit with my programmer so I might just have to put in a a program/run switch.

Thanks for the suggestions but I still can't find the source of the resets!
 
You could post your code. I would suspect a software problem as a likely cause now that you have removed the diodes. I have not experienced a reset problem that was not ultimately traced to a software bug. Watch out for those computed goto's and recheck the ISR for bugs.
 
Sounds like a bad jump.
Does your program modify PCL or have a table?

If you post your program, we can take a look

Kent
 
ok, well I can't really post the entire program because some stuff is copyrighted from the person that asked me to do this and he does not wan't it to be posted at all :?

But here is a macro that I use with computed gotos to read in tables for the menu display:
Code:
disp            MACRO   Table1, Table2
                local   Display_1
                local   Display_2
                local   Display_3
                local   Display_4

                call    LCD_Clr
                clrf    offset                  ;set offset register to zero
                movlw   d'1'                    ;set count register to the first
                movwf   count                   ;|character in the table
Display_1    
                movf    count, w                ;put count value in offset
                movwf   offset                  ;|
                movlw   LOW Table1              ;get low address of the table
                addwf   offset, f               ;add the low address of the offset value
                movlw   HIGH Table1             ;get high adress of the table
                btfsc   STATUS, C               ;check if carry bit is set from the add operation
                addlw   1                       ;if carry set add 1 to w
                movwf   PCLATH                  ;place the high address in PCLATH
                movf    offset, w               ;place low address in w

                call    Table1                  ;get a character from the text table
                xorlw   0x00                    ;is it a zero?
                btfsc   STATUS, Z               ;check if zero bit is set from the above compare
                goto    Display_2               ;if zero set get out of here
                call    LCD_Char                ;zero not set, display character
                incf    count, f                ;increment count register
                goto    Display_1               ;start again and get next character in table

Display_2       
                call    LCD_Line2
                clrf    offset                  ;set offset register to zero
                movlw   d'1'                    ;set count register to the first
                movwf   count                   ;|character in the table
Display_3    
                movf    count, w                ;put count value in offset
                movwf   offset                  ;|
                movlw   LOW Table2              ;get low address of the table
                addwf   offset, f               ;add the low address of the offset value
                movlw   HIGH Table2             ;get high adress of the table
                btfsc   STATUS, C               ;check if carry bit is set from the add operation
                addlw   1                       ;if carry set add 1 to w
                movwf   PCLATH                  ;place the high address in PCLATH
                movf    offset, w               ;place low address in w

                call    Table2                  ;get a character from the text table
                xorlw   0x00                    ;is it a zero?
                btfsc   STATUS, Z               ;check if zero bit is set from the above compare
                goto    Display_4               ;if zero set get out of here
                call    LCD_Char                ;zero not set, display character
                incf    count, f                ;increment count register
                goto    Display_3               ;start again and get next character in table
Display_4       
                bcf     flags,  SWITCH          ;Changed page, reset SWITCH on button pressed flag
                endm

and 2 like the next one but the other one writes to line2 of an LCD

Code:
displ1          MACRO   Table1, Clear
                local   Display_1
                local   Display_2

                call    Clear
                clrf    offset                  ;set offset register to zero
                movlw   d'1'                    ;set count register to the first
                movwf   count                   ;|character in the table
Display_1    
                movf    count, w                ;put count value in offset
                movwf   offset                  ;|
                movlw   LOW Table1              ;get low address of the table
                addwf   offset, f               ;add the low address of the offset value
                movlw   HIGH Table1             ;get high adress of the table
                btfsc   STATUS, C               ;check if carry bit is set from the add operation
                addlw   1                       ;if carry set add 1 to w
                movwf   PCLATH                  ;place the high address in PCLATH
                movf    offset, w               ;place low address in w

                call    Table1                  ;get a character from the text table
                xorlw   0x00                    ;is it a zero?
                btfsc   STATUS, Z               ;check if zero bit is set from the above compare
                goto    Display_2               ;if zero set get out of here
                call    LCD_Char                ;zero not set, display character
                incf    count, f                ;increment count register
                goto    Display_1               ;start again and get next character in table

Display_2       
                bcf     flags,  SWITCH          ;Changed page, reset SWITCH on button pressed flag
                endm

The LCD subroutine calls are based on nigels LCD subroutines from his tutorials. Thanks Nigel, I've been using them alot :)

The tables look like this...
Code:
SomeTable       movwf   PCL
                dt      "some text to display", 0

The ISR code could not be the problem in my opinion because the chip will reset even when not interrupts are enabled, I enable the TMR0 interrupt only when I use the counter, the rest of the time it's not enabled!

I also noticed that I have a few goto $-2 and the sorts. I will change them to labels and see if this helps!

Thanks for the sugestions,
Nelson
 
The code looks OK except that "SomeTable" should be within the same program (2K word) page as where the calling routine is. Since you are altering PCLATH, the next "goto" or "call" instruction is also affected by the change in the value of PCLATH but not as much as a "movwf pcl,f" is. If it is not on the same page, you have to restore PCLATH to the correct page.

BTW as an after thought, "SomeTable" cannot cross a 2K word page boundary for the same reason above.
 
motion said:
The code looks OK except that "SomeTable" should be within the same program (2K word) page as where the calling routine is. Since you are altering PCLATH, the next "goto" or "call" instruction is also affected by the change in the value of PCLATH but not as much as a "movwf pcl,f" is. If it is not on the same page, you have to restore PCLATH to the correct page.

BTW as an after thought, "SomeTable" cannot cross a 2K word page boundary for the same reason above.

Not quite, you need to be absolutely positive that your tables don't cross a 256 byte boundary - PCL is only 8 bits wide, so if the table spans a 256 byte boundary you have big problems.

I notice you are setting PCLATH before jumping to the table, which is essential if the table isn't in the bottom 256 bytes - but if your tables cross a boundary you will have problems.
 
Not quite, you need to be absolutely positive that your tables don't cross a 256 byte boundary - PCL is only 8 bits wide, so if the table spans a 256 byte boundary you have big problems.

His program adjusts the values of PCLATH and PCL should the table cross a 256 word boundary. However, PCLATH is also used in GOTO's and CALL's and so the resulting value of PCLATH should be in the same 2K boundary as the intended target of the GOTO or CALL.
 
Well I think I might have found the problem with the random reseting. The circuit is still on a breadboard and i was testing it out near a refrigerator. It just happened that I was testing a new menu when the refrigerators motor started and the PIC reseted on me :?

So I moved it to another location and let it run and it has not reseted in 2 days. So I guess that the motor was either emitting a strong EMF on stratup or maybe a spike in the current was doing this. I do have pretty good protection on the circuit with a few capacitors on Vdd and Vcc.

I guess that the problem will be resolved once on a board and within a metal case as planed.

Thanks to everyone who helped me out with this problem,
Nelson
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top