0
\$\begingroup\$

I'm trying to use the __delay_ms() function to make an LED blink on the PIC16F77A.
The reason I think it stalls on the __delay_ms() function is because whatever I set RB0 to before the delay function always works, while anything after it doesn't (for any value I pass in).

I'm using a PICKit3 and MPLAB X to program my board. I have a 10k pullup on MCLR and a 16MHz oscillator with two 22pF capacitors in parallel on pins 13 and 14 of the PIC, and RB3/PGM wired to ground (basically the same setup as in this tutorial). I've also tried this with a 20MHz oscillator (with 22pF and 33pF capacitors, as specified in the datasheet).

#include <xc.h>

// BEGIN CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF        // 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

#define _XTAL_FREQ 16000000


void main()
{
    TRISB0 = 0; //RB0 as Output PIN
    while(1) {
        RB0 = 0;
        __delay_ms(1000);
        RB0 = 1;
        __delay_ms(1000);
    }
}  
\$\endgroup\$
  • \$\begingroup\$ The code above leaves the LED off. If instead I put RB0 = 1 before RB0 = 0, it leaves the LED on. \$\endgroup\$ – Chris S Mar 4 at 19:26
2
\$\begingroup\$

i.e. The code above should ultimately turn the LED on, but it stays off. –

It doesn't. the PIC probably reset after reaching the end and re-enter the main method. If you want to stop after the last line, add a while (1); at the end.


With 2 times 10ms delay, you would hardly see a LED light up, especially you are not in a loop.

First, put your code in a loop like so so that it keeps executing and only select the pin you want as output:

void main()
{
    TRISB0bits.TRISB0 = 0; //RB0 as Output PIN

while (1) {
    RB0 = 0;
    __delay_ms(10);
    RB0 = 1;
    __delay_ms(10);
}
}  

Then you state:

I have a 10k pulldown on MCLR

You need a 10k pullup, not pulldown.

For the oscillator, try first to use the internal oscillator to make sure you don't have issues in this regard.

\$\endgroup\$
  • \$\begingroup\$ Thanks for your reply. I misspoke when I said I have a 10k pulldown; it's connected as a pullup. I think my example was also somewhat poor. If I have something like this, the LED stays on, but if I swap the order of the LED toggle (i.e. instead have RB0 = 0, then RB0 = 1), it stays off. while(1) { RB0 = 1; __delay_ms(1000); RB0 = 0; __delay_ms(1000); } \$\endgroup\$ – Chris S Mar 4 at 19:13

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.