1
\$\begingroup\$

I just bought a PIC16F884 and put a simple C program on it using MPLAB:

// CONFIG1
#pragma config FOSC = INTRC_NOCLKOUT// Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP = ON         // Low Voltage Programming Enable bit (RB3/PGM pin has PGM function, low voltage programming enabled)

// CONFIG2
#pragma config BOR4V = BOR40V   // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF        // Flash Program Memory Self Write Enable bits (Write protection off)

#include <xc.h>
#include <stdint.h>

void main(void)
{
    SWDTEN = 0;
    TRISB = 0;
    PORTB = 0;
    // _delay(100000);
    RB1 = 1;

    for (;;)
    {
    }
}

On my board I only connect 5V to pin 11 and ground to pin 12. I was certain the WDT should be off because of the pragma and the SWDTEN = 0;. This code seems to work, as it does bring RB1 to logic high. However, when I remove the comment from the _delay call, the RB1 sits at logic low. From this I assumed that the device is resetting, but I don't know why. The issue persists even when I call _delaywdt instead of _delay. What could be causing the reset? Is it a reset at all, or did I forget to do something/did something incorrectly?

\$\endgroup\$
  • \$\begingroup\$ Make another pin high before the _delay and check whether it stays high. If it doesn't then you can conclude the PIC resets \$\endgroup\$ – Huisman Apr 22 at 22:12
  • 1
    \$\begingroup\$ check = measure with an oscilloscoop \$\endgroup\$ – Huisman Apr 22 at 22:18
  • \$\begingroup\$ Unfortunately I don't own an oscilloscope. \$\endgroup\$ – Enn Michael Apr 22 at 22:22
  • \$\begingroup\$ Look for the time-out bit. If you have a basic debugger attachment (which you should have) you can check it after the following reset. If not and you are just running, then write some code to test that bit and place its status on an output pin you can measure with a voltmeter (and put the code into a forever loop, so you test it.) You can, at least, see if it really is a WDT event or not. \$\endgroup\$ – jonk Apr 22 at 22:34
  • \$\begingroup\$ If you are suspecting a WDT, make your startup code toggle the pin on for a while (1s?). I'd even wire a LED to see the blink. Then you do the long wait. If the WDT is the culprit, you'll see blinks once on each restart. \$\endgroup\$ – anrieff Apr 22 at 22:37
1
\$\begingroup\$

One thing the code definitely lacks is correct initialisation of the output pin. It is unlikely to cause the symptoms you are seeing, but can cause subtle problems in similar circumstances.

From section 3.2.1 of the datasheet:

The state of the ANSEL bits has no affect on digital out- put functions. A pin with TRIS clear and ANSEL set will still operate as a digital output, but the Input mode will be analog. This can cause unexpected behavior when executing read-modify-write instructions on the affected port.

Therefore code which sets analog capable pins to a defined value should work, for example:

RB1 = 1;

However, any read-modify-write will have unexpected results. For example:

RB1 ^= 1;
RB1 &= 1;

Both of these would read the pin value first, which would default to zero (regardless of the current output value).

You should check the documentation for the ANSELH register. Also check section 3.3 of the data sheet, which lists other port functions that can often be relevant.

\$\endgroup\$
  • \$\begingroup\$ This is now the accepted answer. I’d love to know if it fixed your problem, since from the test code it shouldn’t have changed anything. \$\endgroup\$ – David Apr 23 at 21:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.