0
\$\begingroup\$

I just started working with PIC microcontrollers and I am currently using MPLAB X IDE with a PIC KIT 3. I've been trying to get a simple LED blink code to run on a PIC16F1829 using the internal oscillator at 16 Mhz. However, the behavior of the LEDs are random. The code I'm using is given below.

#define _XTAL_FREQ 8000000

#include <stdio.h>
#include <stdlib.h>
#include <pic16f1829.h>
#include <xc.h>

// BEGIN CONFIG
#pragma config FOSC = INTOSC // Oscillator Selection bits (Internal oscillator)
#pragma config WDTE = ON // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
//END CONFIG



int main() {

  OSCCON = 0b01110011; 
  OSCTUNE = 0b00000000;
  TRISC6 = 0; 
  TRISC5 = 0;

  while(1)
  {
    RC6 = 1;  // LED ON
    __delay_ms(500); // 0.5 Second Delay
    RC6= 0;  // LED OFF
    __delay_ms(500); // 0.5 Second Delay
    RC5 = 1;
    __delay_ms(500);
    RC5 = 0;
    __delay_ms(400);
  }
  return 0;

}

I'm pretty sure the problem is with the oscillator or the way I set it up since I can switch on either LED at startup. The problem arises when I introduce delays to make the LEDs blink. Using delays of 5000 means that the first LED is turned on and then nothing happens. Using delays of 1000 make the first LED blink with a delay of around 1.5 seconds with the second LED always turned on. Using delays of 500 or less make both LED blink but at different frequencies and patterns.

Could someone help me find what I'm doing wrong?

schematic

\$\endgroup\$
  • \$\begingroup\$ Please post a schematic \$\endgroup\$ – Spehro Pefhany Feb 11 '16 at 6:16
  • \$\begingroup\$ Added an Image. \$\endgroup\$ – user2802349 Feb 11 '16 at 6:24
  • \$\begingroup\$ You can also try using a plain old timer's interrupt to toggle the leds - if you check the microchips site there should be a document explaining how timers work and how to work with their interrupts. \$\endgroup\$ – user100028 Feb 11 '16 at 6:41
  • \$\begingroup\$ seems like your chip is resetting itself \$\endgroup\$ – burkut Feb 11 '16 at 19:17
2
\$\begingroup\$

A few things to look at:

  1. Your code enables the watchdog timer, but you are never issuing any CLRWDT commands. I would recommend disabling the watchdog timer until you get the code working.

    The watchdog timer is basically just a counter. When it overflows, the microcontroller gets reset. To use it properly, your code needs to keep resetting the counter so that it never actually overflows.

    To do this, your code loop should issue a CLRWDT command regularly. The idea is, if the microcontroller gets stuck somehow (either because of a code problem or a hardware glitch), it will stop clearing the watchdog timer. So the timer will overflow and automatically reset the microcontroller instead of just sitting there forever.

    If I remember correctly, the default period of the WDT is 2 seconds, after which the PIC will reset.

  2. Add a decoupling capacitor (to ground) at the PIC's VDD pin. The value isn't critical; anything around 0.1uF or 1uF should be fine.

    Decoupling caps are very important for digital ICs. If you aren't familiar with them, spend some time on Google or here on the Electronics Stack.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks for the help. The problem was the watchdog timer. Circuit works perfectly after I removed that line. I was following the tutorial on the following page and the author hadn't utilized the timer either. electrosome.com/led-pic-microcontroller-mplab-xc8 \$\endgroup\$ – user2802349 Feb 14 '16 at 12:45
  • \$\begingroup\$ @user2802349 Great! Glad it's working. If you haven't already, I would still add the decoupling cap on VDD. Without it the PIC may reset or latch up for no apparent reason... Have fun! \$\endgroup\$ – bitsmack Feb 14 '16 at 15:01
2
\$\begingroup\$

In addition to @bitsmack's correct observation that you've enabled the watchdog and then never 'kick' it - causing your PIC to reset itself over & over, there's an inconsistency in what you describe and what you're doing.

You write in your question "using the internal oscillator at 16 Mhz", but the very 1st line in your program is "#define _XTAL_FREQ 8000000".

The library functions which implement those delay functions you're using need to know how fast the PIC is running and they use that #define value for that, so you're giving them incorrect information.

So change the 8000000 to 16000000 and either disable the watchdog or learn how to kick it and your LEDs should begin to behave as you expect.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You're right about the inconsistancy, but it actually goes in the other direction - the OP is setting his (or her) OSCCON register for 8MHz, and is also defining 8MHz in the code. It's the text of the question which doesn't line up :) \$\endgroup\$ – bitsmack Feb 11 '16 at 15:57
  • \$\begingroup\$ @bitsmack good catch - I didn't even try interpreting the OSCCON bits to see. The problem is probably all in the WDT not being kicked then. \$\endgroup\$ – brhans Feb 11 '16 at 16:01
  • \$\begingroup\$ I'm sorry about the inconsistency, I made a mistake in the text of the question as I was trying out all possible values and thought the last value I used was 16 Mhz. The problem was with the watchdog timer bit. Thanks for all the help \$\endgroup\$ – user2802349 Feb 14 '16 at 12:47

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.