# How do I write and upload a LED blink program on a PIC (pic16f59)?

I have a PIC16F59 and I want to get started with it by writing a blinking LED program. I am using HI-TECH C for the PIC10/12/16 MCU Family and the PICkit3 and MPLAB X as my IDE. Here is my attempted code which is supposed to turn on all LEDs on port B.

#include <stdio.h>
#include <stdlib.h>
#include <htc.h>

int main(int argc, char** argv)
{
while (1)
{
// Put delay code here
PORTB=1;
// Put delay code here
}
return (EXIT_SUCCESS);
}


The program compiles fine. However, when uploading the hex file using the PICkit3 I get this error message:

Program operation of Program Memory failed


What I am I doing wrong? Are there any configuration settings that I am not aware of?

-
I don't think anything is wrong with your code. I would inspect the connections with your devboard/application. – BrianV May 4 '12 at 20:48
Actually there is potential coding issue, besides your problem with programming the micro. PORTB=1 will only turn on the LED (or turn it off, depending on how its wired). Your title says "How to write an LED blink program." You need to add PORTB=0 after the second delay in order to blink it. Also, PORTB=1 only affects bit 0, whereas you say "which is supposed to turn on all led on port B". – tcrosley May 4 '12 at 21:01
Thanks everyone for your reply. I have been trying all your suggestions, changed the pic, rewired the pickit but still no luck – Nirupama May 5 '12 at 1:53
@Nirupama 99.99% of the time, it is not the PIC that is faulty. – abdullah kahraman Jun 5 '12 at 15:48

The error message you get indicates a communication failure between the PicKit and the chip. It has nothing to do with the contents of your program. It would help if you showed the schematic of exactly what is around the PIC and how the PicKit is connected. Possible issues are:

1. Something is loading the PGC or PGD pin, which prevents the programmer from communicating.

2. Something is not allowing MCRL to be raised to the programming voltage. I didn't look up the programming spec for this chip, but Vpp can be as high as 13 V for some PICs.

3. No bypass cap accross Vdd and Vss.

4. Not all power and ground pins hooked up if this chip has multiple. Again, I didn't look up your specific PIC.

5. Too long a cable between the PicKit and the chip, which allows for crosstalk between PGC and PGD.

See my In-circuit Serial Programming paper for more detail and general demystification of the programming process.

On a separate topic, there are two flaws in your program. First you need to set RB1 as output since it wakes up as input. Second, you need to turn it off in the loop too if you want the LED to blink. Right now your program sets RB1 high and leaves it that way. If your chip has analog inputs, then you also have to make sure that RB1 is either not one of them or to explicitly switch it to a digital pin.

-

It's embedded stuff so wouldn't you typically use void main(void)?

Aside from that...TRISB needs to be set for which pins are output on PORTB. Better habit is also to write to LATB not PORTB...read from the port write to the latch.

PORTBbits.RB0=0x01 same as LATBbits.LATB0=0x01 but better method is via latch.

When you created your project with Project Wizard did you pick the correct chip number? That gets passed through to the assembler/linker part when you build and if you have the wrong PIC number listed it will mess with stuff when you try and program because it tries to write data to a memory map for that particular chip.

Check that out and see what you find.

-
Hmm! I am not sure if I understand what you mean. What do you mean by "TRISB needs to be set for which pins are output on PORTB."? I am not sure if I am asking too much but would please put this in a small code that would light up an LED? Thanks in advance – Nirupama May 6 '12 at 7:05
You should have TRISB = 0x00;, to make PORT B pins all outputs. Try reading the data sheet and user manual. – Leon Heller May 6 '12 at 8:16

Page 31 of the Datasheet for the PIC 16f59 talks all about your I/O ports and how to set them up.

Basically each port can be configured as either an input or output port. This is done via the TRIS reg (tristate reg) for each of the different ports. PORTA = TRISA / PORTB=TRISB and so on.

If you set bit 0 on TRISA to a 1, PORTA bit 0 (RA0) becomes input (1=input 0=Output).

So, providing to have the correct header file loaded in for our name definitions, you could make PORTB Bit 0 an Output by doing this...

void main(void)
{
TRISBbits.TRISB0 = 0x00;  // PORTB Bit 0 is now Output.
// To set ALL pins to output all at once TRISA = 0x00;
PORTBbits.RB0 = 0x01;     // You've just energized the pin which corresponds to RB0

while(1)                      // Loop forever
{

LATBbits.LATB0 = 0x01;    // is an alternative way of doing the same thing except you are
// writing to the Port buffer instead of directly to the Port
// which is a safer method of coding (so I'm told).

Delay(of time);           // Delay method of your choice

LATBbits.LATB0 = 0x00;  // De-energizes Bit 0

// or PORTBbits.RB0 = 0x00;

Delay(of time);

}
}


And there you have it...a short bit of code that will blink an LED, properly conntected, to the output pin of PORTB Bit 0. You make the delay loops and toss in the correct #includes and it should work for you.

However reading through the datasheet will help more. It gives you code samples to initialize ports and the such.

-
IMO, you should edit your other answer and merge them both. – PetPaulsen May 6 '12 at 8:36
Thanks a lot. I appreciated your help – Nirupama May 6 '12 at 10:51
I am sure there might be something wrong with my system. By running your code, I get a compiler error that says"main.c:14: error: undefined identifier "TRISBbits" What's wrong? I am missing any include header file. BTW, I am using the HI-Tech compiler. – Nirupama May 6 '12 at 12:06
Did you add your #include <htc.h> and any other includes needed? Go search the p16f59.h file and see how they defined the individual pins if you've already added the #include files. They list naming conventions there. Chances are they used the bit name (RA0 RA1 RA2 and TRISA0 TRISA1 etc).... quick way to get you up and running is set the whole port to output...TRISA=0x00; then write to the whole port as PORTA = 0b00000001 (where the binary bits in the 8bit number = your output pin #) Read your Full Datasheet too (not the short 16 page one) - 6.7 tells you what to do. – Chef Flambe May 6 '12 at 19:07
Your code was missing a curly bracket, and the indentation was messed up. I fixed it. – Connor Wolf Jun 5 '12 at 9:53