Help please: PIC12F675 Beginner - Page 1
Forum section: electronics / general

author: igendel
author_rank: Frequent Contributor
timestamp: May 02, 2014, 02:16:00 pm
content: Hello good people!I'm trying to wrap my head around this humble PIC MCU, but there are so many variants and variations on the webSome background: I started learning about MCUs about 2 years ago, with Arduino, then moved on to "independent" AVRs using Atmel Studio, and some forays into MSP430G2. Now I got hold of a PICkit 1 (hey, don't laugh!) and a couple of cheap PIC12F675s that are supported by it, so I installed MPLAB X w/ XC8, tried to write a Blink program and... nothing.The process of burning the generated "production" HEX file using the PICkit 1 and its old, dedicated software seems to be working just fine, but I get no response from the MCU itself no matter what code I try. The old programmer isn't recognized by the IDE so I can't debug that way, and I'm still not willing to spend $$ on a modern programmer just for a little experimenting.Obviously, I searched the web and these forums, but so far I only found code for other PICs, or for other compilers, or other IDEs... so, can someone please provide a working Blink code for my setup, with the correct register initializations? It doesn't even have to be commented, I can take it from there.Thank you very much in advance!

author: ElektroQuark
author_rank: Unknown
timestamp: May 02, 2014, 02:25:15 pm
content: Try MPLAB instead.

author: igendel
author_rank: Frequent Contributor
timestamp: May 02, 2014, 02:42:57 pm
content: Quote from: EdoNork on May 02, 2014, 02:25:15 pmWhat good reason is there to use less-than-the-latest? If I can make this work, I won't stay forever with just the 675 and the old programmer, so I want to start as up to date as possible.

author: ElektroQuark
author_rank: Unknown
timestamp: May 02, 2014, 02:45:35 pm
content: "The old programmer isn't recognized by the IDE so I can't debug"Maybe with MPLAB you can try finding the problem.

author: Sebastian
author_rank: Regular Contributor
timestamp: May 02, 2014, 02:48:18 pm
content: Could you post your code so we can see if that is the problem?I would not switch back to the old MPLAB, I think X has a much better UI and it works great for me.

author: igendel
author_rank: Frequent Contributor
timestamp: May 02, 2014, 02:54:43 pm
content: Quote from: EdoNork on May 02, 2014, 02:45:35 pmI see - still, assuming the chip itself is ok, starting from a working code will be faster and more efficient than trying to debug a dubious code I don't even understand yet...Quote from: Sebastian on May 02, 2014, 02:48:18 pmI tried and mixed many versions, it's all a big mess. I'd rather have a clean start. Like, should I use the GPIO register or, say, RA0? include pic12f675.h or something else?

author: AlfBaz
author_rank: Super Contributor
timestamp: May 02, 2014, 02:56:30 pm
content: Pickit 1 is not the only casualty, I believe the original ICD isn't supported either, at least for the pic32's

author: Sebastian
author_rank: Regular Contributor
timestamp: May 02, 2014, 03:06:10 pm
content: I never used pic 12fs only 16f, 18f, and 24f so I don't know if there is anything different.But in general with XC8 you have to include only xc.h because it automatically includes the standard libraries for the device.I don't know if your device has an ADC but if it does you have to deactivate it because it is on at reset. (ANSEL = 0x00; or something like that). There could be other stuff you have to deactivate as well, so have a look at the datasheet. Then you have to set the 3-state bit of the pin you are using to 0 and you should be good to go.

author: mariush
author_rank: Super Contributor
timestamp: May 02, 2014, 04:00:56 pm
content: pic12f675 is supported by XC8 v1.31 (you have the header files in xc8\v1.31\include, but it's enough to just say #include <xc.h> at the start of your main.c file and in "Project properties" in MPLAB X you have to select the chip you have so that the compiler will know what pic chip to use)However, MPLAB X may not be able to "communicate" with Pickit 1, you should try the old MPLAB. You can download it from here:http://www.microchip.com/pagehandler/en-us/devtools/dev-tools-parts.html(Scroll down to MPLAB IDE archives, and you have somewhere on the right side all the way down MPLAB 8.92).XC8 may not work right with MPLAB, or MPLAB may not recognize it as a compiler, in which case you can download from the same page Hi-Tech C compiler (scroll down more and you have there a ftp link).Hi-Tech C compiler is basically previous versions of XC8, Microchip bought Hi-Tech and just renamed it to XC8, so all you have to do is install hi-tech c, select it as compiler in MPLAB and then instead of #include <xc.h> you say #include <htc.h> , that's all there is to it. Everything else should work the same.Once you get everything working (mplab + hi-tech c/xc8 + pickit 1) you should write a simple program, that simply blink a led. Set internal oscillator, set it to default 4 mhz, disable analog input (ansel*) on that port, set the port to output (it should be by default output) then set that pin to 1 so that you can connect a led between that pin and ground and get it to light up. make sure you have a loop at the end to keep it running, otherwise i'm not sure if the compiler will add the loop code by itself.

author: dannyf
author_rank: Super Contributor
timestamp: May 02, 2014, 04:08:04 pm
content: QuoteTwo tricks for most PICs:1) set the fuse in the code;2) turn off any ancillary functions (like analog and comparators).If you still cannot get it work after this, I can write you one.

author: Sebastian
author_rank: Regular Contributor
timestamp: May 02, 2014, 05:23:11 pm
content: Oh, I forgot the configuration bits. Go to Window -> PIC memory view -> Configuration bits. Now a windows should open below where the code is. Set the configuration bits how you need them and click on generate. Copy the generated code into a new header file called config.h and include it in main. Now you are good to go.

author: igendel
author_rank: Frequent Contributor
timestamp: May 02, 2014, 05:38:52 pm
content: ... hours later ...I somehow got something to work. The code is this:Code:#include <xc.h>// Generated by the Configuration Bits wizard:#pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)#pragma config PWRTE = OFF // Power-Up Timer Enable bit (PWRT disabled)#pragma config MCLRE = ON // GP3/MCLR pin function select (GP3/MCLR pin function is MCLR)#pragma config BOREN = OFF // Brown-out Detect Enable bit (BOD disabled)#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)int main(int argc, char** argv) {ANSEL = 0;TRISIO = 0;GPIO = 0;while (1) {GPIO = 0;_delay(100000);GPIO = 1;_delay(100000);}return (0); // I know I don't need this, it was simply in the template}It blinks at ~4 times a second.When I wrote "GPIO = 1 - GPIO" it didn't work (was constantly on). Why?Edit: using an auxiliary variable for state, the "1 - state" does work:Code:while (1) {s = 1 - s; // s is unsigned charGPIO = s;_delay(1000000);}

author: Sebastian
author_rank: Regular Contributor
timestamp: May 02, 2014, 05:48:24 pm
content: What do you want to archive with "GPIO = 1 - GPIO"?Do you want to toggle one pin? GPIO is 8 bit wide and I think you only want to control one pin right? Use GPIObits.GPx where x is the number of the pin between 0 and 7, if your package actually features 8 I/O pins. To toggle GP0 use "GPIObits.GP0 = ~GPIObits.GP0"

author: igendel
author_rank: Frequent Contributor
timestamp: May 02, 2014, 05:50:58 pm
content: Quote from: Sebastian on May 02, 2014, 05:48:24 pmYes, I'm familiar with how such ports work and how to access them in a real application... I simply wanted something to blink for now, I don't care about the other pins.Still, why didn't it work?

author: Andy Watson
author_rank: Super Contributor
timestamp: May 02, 2014, 06:23:48 pm
content: What blinking thing have you connected, and more importantly how have you connected it?

author: igendel
author_rank: Frequent Contributor
timestamp: May 02, 2014, 06:40:59 pm
content: Quote from: Andy Watson on May 02, 2014, 06:23:48 pmA regular 5mm red LED, anode through a 330 Ohm resistor to pin, cathode to GND.It blinks happily now, the problem is, I think, how the compiler treats that statement.

author: Andy Watson
author_rank: Super Contributor
timestamp: May 02, 2014, 06:47:43 pm
content: I was considering the possibility that you had loaded the port down too much - a port read will always return the state of the pin, not the latch. But 330 into an LED should not be a problem. It does look like a compiler quirk! It would be interesting to pull out the assembly code and see what the compiler has done with the GPIO=1-GPIO;

author: dannyf
author_rank: Super Contributor
timestamp: May 02, 2014, 07:22:38 pm
content: QuoteLook beyond that statement.I outlined the solution for you earlier.

author: igendel
author_rank: Frequent Contributor
timestamp: May 02, 2014, 10:15:45 pm
content: Quote from: dannyf on May 02, 2014, 07:22:38 pmSorry, I don't follow you on this one. What did I miss?

author: Andy Watson
author_rank: Super Contributor
timestamp: May 02, 2014, 10:28:42 pm
content: Can you extract the assembly code? I don't have access to a C compiler for the PIC and I am intrigued to know why that statement didn't work.

author: igendel
author_rank: Frequent Contributor
timestamp: May 02, 2014, 10:55:13 pm
content: Quote from: Andy Watson on May 02, 2014, 10:28:42 pmGood question... where can I find it? I'm not too familiar with the toolchain, so far I can only see the raw HEX "program memory".

author: mariush
author_rank: Super Contributor
timestamp: May 02, 2014, 11:11:05 pm
content: In MPLAB X , from menu .. Window > Output > Dissasembly Listing Fileor window > pic memory views > program memory, then select code in the combo box.. but the above option is nicer

author: igendel
author_rank: Frequent Contributor
timestamp: May 02, 2014, 11:26:10 pm
content: Quote from: mariush on May 02, 2014, 11:11:05 pmWow, that IS convenient!Here's what I get for the mysterious code line:Code:22: GPIO = 1 - GPIO;03EA 1283 BCF STATUS, 0x503EB 0305 DECF GPIO, W03EC 3AFF XORLW 0xFF03ED 3E01 ADDLW 0x103EE 0085 MOVWF GPIOAnd here's for the working alternative:Code:20: s = 1 - s;03E6 1283 BCF STATUS, 0x503E7 0323 DECF s, W03E8 3AFF XORLW 0xFF03E9 3E01 ADDLW 0x103EA 00A0 MOVWF __pcstackBANK003EB 0820 MOVF __pcstackBANK0, W03EC 00A3 MOVWF s21: GPIO = s;03ED 0823 MOVF s, W03EE 0085 MOVWF GPIO

author: igendel
author_rank: Frequent Contributor
timestamp: May 02, 2014, 11:39:43 pm
content: Quote from: dannyf on May 02, 2014, 07:22:38 pmOhhhhh.... I added these two initializations:Code:CMCON = 7;ADCON0 = 0;And it DOES blink with "GPIO = 1 - GPIO". However, I still have no ideawhyit works. Explanations or datasheet references are welcome...

author: Andy Watson
author_rank: Super Contributor
timestamp: May 03, 2014, 12:11:56 am
content: Quote from: igendel on May 02, 2014, 11:39:43 pmAh! Must have misunderstood the sequence of events as posted (DOH!) Putting the ADCON=0, disables the ADC inputs. The default, from reset, is to have the ADC inputs enabled. When the inputs are enabled as ADC inputs they read, digitally, as zero.http://ww1.microchip.com/downloads/en/DeviceDoc/41190G.pdfpage 21 onwards.

author: igendel
author_rank: Frequent Contributor
timestamp: May 03, 2014, 12:33:17 am
content: Quote from: Andy Watson on May 03, 2014, 12:11:56 amObviously, because setting ANSEL to 0 doesn't hint at all that I'm not going to use the ADC... [clarification edit: on any IO pin]I guess all MCUs are funny like that, each in its own way. Just need to get used to it.Thanks Andy and everyone!

author: westfw
author_rank: Super Contributor
timestamp: May 07, 2014, 08:39:21 am
content: QuoteDisables the analog comparator, which is separate from the A-D (although both are analog functions.) There's a note in the datasheet:"The ANSEL (9Fh) and CMCON (19h) registers (9Fh) must be initialized to configure an analog channel as a digital input. Pins configured as analog inputs will read ‘0’. The ANSEL register is defined for the PIC12F675."(drove me crazy till I figured it out. I knew about ANSEL, but not CMCON...)