# Programming and using a flash memory PIC

I'm learning how to program a PIC12F609 and I have what (I think) is a silly n00b question. As a test I'm trying to burn a program that simply turns all 5 IO pins to output and turns them all on, so that if I connect an LED in series with a resistor to any pin it will light up. My program is dead simple and builds fine and MPLAB says the PicKit3 has successfully programmed the device. But when I try to use the programmed chip it doesn't work.

My fear is that the program is expiring from the memory as soon as I disconnect the PicKit. My plan was to program the PIC, pull it out, drop it into the LED circuit and connect the power source (9V battery run through 5V regulator). In all my previous microcontroller experience, the program disappeared from RAM as soon as power stopped and only programs stored in EEPROM, which this tiny 8 pin Pic doesnt have, would boot when power was reconnected.

If this is the case, how do I get a program to "stick" on my chip? and if not, what else about my process seems wrong?

edit: I'm posting my code in hopes this will be helpful. I really appreciate the thoughtful answers that have already been given, hopefully this way someone can help me set my configuration switches.

#include <12F609.h>
#include <stdlib.h>

void main (){
// All five IO pins are on port A.
SET_TRIS_a(11111);
OUTPUT_a(11111);
while(1){
// endless loop, my attempt to make sure it didn't stop running
// I've also tried putting the OUTPUT and TRIS in here but no luck
}
}


my configuration bits are

FOSC - Oscillator Selection bits - RC oscillator
WDTE - Watchdog Timer Enable bit - WDT disabled
PWRTE - Power-up Timer Enable bit - PWRT enabled
MCLRE - MCLR Pin Function Select bit - MCLR pin function is MCLR
CP - Code Protection bit - CP is disabled
IOSCFS - Internal Oscillator Frequency Select - 8 MHz
BOREN - Brown-out Reset Selection bits - BOR enabled.

I think I understand what most all of those do, but I really don't know enough to select the right ones.

Your plan is fine as it stands - when you program the PIC it programs the flash memory. This program should be able to be retained for many tens, even hundreds of years.

The problem that most people (myself included) have with getting started with PICs is with the configuration fuses. These are settings which define how the PIC runs, including what oscillator to use to drive it.

It is most likely that you haven't set these fuses properly (they can be a real pain), so your program just isn't running.

• Thanks for the heads up. I've posted my code and am trying to figure out my configuration switches now. – NealJMD Aug 18 '11 at 21:45
• also added current configuration switches – NealJMD Aug 18 '11 at 22:08
• I see you have elected to use the RC oscillator. I assume you have the right resistor and capacitor attached to the OSC1 pin? – Majenko Aug 18 '11 at 22:50
• Nope, I don't have anything connected to the OSC1 pin. I tried changing that setting in Configure > Configuration bits, but when I try to program it, the configuration bits are all reverted. what would the program do if there's nothing connected to the CLKIN and CLKOUT pins? – NealJMD Aug 20 '11 at 2:09
• You are looking to use INTOSCIO (Internal Oscillator, with IO on the OSC pins). – Majenko Aug 20 '11 at 8:49

If you have a look at your part number, you will notice the 'F'. That means that the program will be stored in the flash memory (the RAM in this device is only 64 bytes (!), so storing program code there will not work). You might post your code here...

I am not familiar with the PIC12 series, but have used the PIC16, PIC18, PIC24 and PIC32 chips with MPLAB.

For each of these, a program can be compiled in either the debug or release mode. (There is a drop-menu for build configuration in the toolbar, with choices for Debug or Release.)

I believe the default setting is Debug. However if you program a device in debug mode and then disconnect the programmer, the program will not run stand-alone. You need to switch the configuration to Release and also select PICkit3 as your Programmer instead of Debugger.

Then re-compile (or reassemble) your program, and program the device. The program should then run without the programmer attached.

• I was hoping this would be it, but I went to Project > Build Configuration > (No build configurations). I checked the help documentation and that's where its apparently supposed to be set. is it possible there's no choice because I haven't set up a debugger of any sort? – NealJMD Aug 18 '11 at 21:49
• @NealJMD, what compiler are you using? Is it integrated into the MPLAB IDE? – tcrosley Aug 19 '11 at 0:07
• I'm using the CCS C Compiler – NealJMD Aug 19 '11 at 13:06

Your code looks good except for one line:

SET_TRIS_a(11111) ; set all 5 pins to 1=Input, using deprecated instruction.


I think you want something more like Example 5-1 on p. 43 of the datasheet:

banksel GPIO
movlw   b'00010101' ; 0=low, 1=high
movwf   GPIO
banksel ANSEL
clrf    ANSEL ; digital I/O, rather than ADC
banksel TRISIO
movlw   b'00000000' ; 0=output, 1=input
movwf   TRISIO


You might want to check out the datasheet for the PIC12F609. A tiny little footnote on p. 16 (out of 212) of the datasheet says "TRISIO3 always reads as '1' since GP3 is an input only pin.". On p. 43, the datasheet mentions "Setting a TRISIO bit (=1) will make the corresponding GPIO pin an input (i.e., disable the output driver). Clearing a TRISIO bit (=0) will make the corresponding GPIO pin an output (i.e., enables output driver and puts the contents of the output latch on the selected pin)."

(Yes, 1=input, 0=output is exactly the opposite of certain other popular chips).

(Further details: Massmind: TRIS; Massmind: PIC12F example code )

EDIT: Even though we think the 12f609 doesn't "need" to have ANSEL cleared, I would clear it anyway. I've heard that fixes at least one Problem with 12f609.

#include <12F609.h>
// ...
main(){
OUTPUT_A(0xFF); // all high: 0=low, 1=high
//  #BYTE ANSEL = 0x9F // defined in 12F609.h ?
ANSEL = 0;
SET_TRIS_A(0X00); // 0=output, 1=input
// ...
}

• thanks this is really helpful. I changed it from SET_TRIS_a(11111) to SET_TRIS_a(00000) cause I don't really want to get into assembly, but it's still not working. do you think I need to set the ANSEL value even though the chip doesn't have an ADC? – NealJMD Aug 20 '11 at 2:02
• turns out it was the configuration pins effing it up. thanks so much though! I would upvote this answer if I had the whuffie to do it. – NealJMD Aug 21 '11 at 23:49