How-to: Program PICs Using Linux

Arguably, Microchip’s PIC microcontrollers do not get enough posts here. One of the drawbacks for some of us is that Linux support for PICs is not very well known. The information is out there, but no one has laid out the process of going from writing C code to programming a chip. Written for Linux users that are familiar with microcontrollers, basic circuits, the C programming language, and can read a datasheet, this how-to should get you up and programming a PIC quickly with Linux.

The Compiler:

The Small Device C Compiler, sdcc is what will be used to create the .hex file needed to program a PIC. Support for PICs is still growing, and still in beta, so be aware that things outside the code and chips of this article may need some debugging. However, like every other open source project out there, more contributing users will help the project. Best of all, it is free, with ports to Windows and MacOS X, this is a compiler that handles many architectures and devices without the program limit of free versions of for-pay compilers that are limited to Windows. Sdcc is available through various distributions’ package managers including Ubuntu and Fedora.

To install sdcc on Ubuntu:

sudo apt-get install sdcc

To install sdcc on Fedora:

sudo yum install sdcc

The Chips:

Three different PIC chips were used in the writing of this tutorial: the 40 pin PIC16F887, the 14 pin PIC16F688, and the 8 pin PIC12F675. You can follow along with any of these chips as well as other chips.

The Programmer:

We will be using two programmers, Olimex’s PICStart+ compatible PIC-MCP-USB programmer, and Microchip’s PICkit 2. Both programmers have been tested to work with the three chips used here.

The PICStart+ programmers use the picp program. Most any PICStart+ compatible programmer will work with picp. Easily installed in Ubuntu with:

<pre>sudo apt-get install picp

For Fedora and other distributions may have to download and install it from source. So, in an empty directory of your choosing:

wget http://home.pacbell.net/theposts/picmicro/picp-0.6.8.tar.gz
tar -xzf picp-0.6.8.tar.gz
cd picp-0.6.8
make
sudo make install

The source is on [Jeff Post]’s Development Tools for PIC programmers page along with other programming options.

If you will be using the PIC16F887 and picp, you will need to modify your /etc/picp/picdevrc file by adding the following lines:

[16F887]
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
PICSTART

[16F887:def]
20 00 3f ff 3f ff 00 7f
00 7f 3f ff 3f ff 00 ff
00 ff 00 00 00 00 00 00
0D 10 20 00 04 20 07 02
00 00 01 00 00 00 00 00
00 01 22 0f

[16F887:defx]
3f ff 07 00 00 00 00 00
00 00 00 00 00 00 00 00
3f ff 07 00 00 00 00 00
00 00 00 00 00 00 00 00

The above lines are  modified parameters for PIC16F886 found in a post by [Al Williams]. For chips not already in /etc/picp/picdevrc, additional parameters will need to be added to /etc/picp/picdevrc.

PICkit 2 programmers will work with another program called pk2cmd hosted by Microchip here. You will need to install pk2cmd from source. so in a directory of your choosing:

wget http://ww1.microchip.com/downloads/en/DeviceDoc/pk2cmdv1.20LinuxMacSource.tar.gz
tar -xzf pk2cmdv1.20LinuxMacSource.tar.gz
cd pk2cmdv1.20LinuxMacSource
make linux
sudo make install

Note that Microchip touts the PICkit 3 as a replacement for the PICkit 2. It is not a replacement for the PICkit 2 as there are no Linux drivers for the PICkit 3, so do not buy the PICkit 3 thinking it will work in Linux.

There is also another program that claims to work with a range of DIY PIC programmers: PICPgm. We have not tried this program or any of the DIY programmers at this point. We know there are other PIC programmers out there, both cheap and expensive, that have not been mentioned. Perhaps a PIC programmer roundup is in need of writing.

The Code:

The code for this how-to is a kind of hello world program using LEDs. The code for this is hosted on Github, you can follow along with the blink.c file for the PIC16F887, PIC16F688, or PIC12F675. Also included are working .hex files. Here is the PIC16F887 code as a reference as we walk through each major operation:

//Simple program to get started programming
//PIC microcontrollers in Linux.
//Written by Devlin Thyne.
//Released to the public domain.

#include "pic/pic16f887.h"

//Use these configuration words:
//0x2ff4 0x3fff

//Set the configuration words:
unsigned int at _CONFIG1 configWord1 = 0x2FF4;
unsigned int at _CONFIG2 configWord2 = 0x3fff;

//To compile:
//sdcc -mpic14 -p16f887 blink.c

//To program the chip using picp:
//Assuming /dev/ttyUSB0 is the serial port.

//Erase the chip:
//picp /dev/ttyUSB0 16f887 -ef

//Write the program:
//picp /dev/ttyUSB0 16f887 -wp blink.hex

//Write the configuration words (optional):
//picp /dev/ttyUSB0 16f887 -wc 0x2ff4 0x3fff

//Doing it all at once: erasing, programming, and reading back config words:
//picp /dev/ttyUSB0 16f887 -ef -wp blink.hex -rc

//To program the chip using pk2cmd:
//pk2cmd -M -PPIC16f887 -Fblink.hex

//Setup variables
unsigned char ucharCount = 0;
unsigned int uintDelayCount = 0;

void main(void)
{
	//Set PORTC to all outputs
	TRISC = 0x00;

	ucharCount = 0;
	uintDelayCount = 0;

	//Loop forever
	while ( 1 )
	{
		//Delay Loop
		while ( uintDelayCount < 10000 )
		{
			//Increment the loop counter
			uintDelayCount++;
		}

		//Reset delay loop counter
		uintDelayCount = 0;

		//Increment the count
		ucharCount++;

		//Display the count on the PORTC pins
		PORTC = ucharCount;

	}

}

The first line is the #include for the header file of the particular chip you will be using. It tells the compiler which registers are available and where they are located in memory. In most systems, the header files will be in /usr/share/sdcc/include.

Then we setup the configuration word or words fuses. They are only able to be written when the chip is programmed, but we can define them here so we don’t have to manually program them later. The PIC16F887 has the address for the configuration words defined in its header file as _CONFIG1 and _CONFIG2. The PIC16F688 and PIC12F675 do not have the configuration word address defined in their header (we said sdcc was in beta, didn’t we?), so we just use the address of the configuration word: 0x2007. The configuration words are specific to the chip model and application and are described in the chapter “Special Features of the CPU” in each of the respective chips’ datasheets. In the blink.c samples, the configuration word is just a 16bit hexadecimal word, but the word can be made more human readable by ANDing together the configuration options. Check out the chips’ header files for the names of the options.

Next, we setup some global variables, one for the value that will be output on the LEDs and the other for a delay counter.

In the void main(), we set the PORTC tristate register, TRISC to all outputs. The PIC12F675 has only one port, GPIO, and its tristate register is TRISIO. After setting the tristate register, we enter an infinite loop with while(1). Inside that loop is a delay loop so that we can see the LEDs changing. Following the delay loop, the display counter is incremented and then written to PORTC (or GPIO) for display on the LEDs.

Compiling the Code:

Now that we have reviewed the code, it is time to turn it into something a PIC can use. sdcc will take the blink.c file and make a bunch of files. One of these files will be blink.hex which will be what the PIC device programmer will be writing to the PIC. Here’s how:

For the PIC16F887:

sdcc -mpic14 -p16f887 blink.c

For the PIC16F688:

sdcc -mpic14 -p16f688 blink.c

For the PIC12F675:

sdcc -mpic14 -p12f675 blink.c

The -mpic14 option tells sdcc that it will be compiling for the 14-bit instructions of the PIC16 and PIC12 families. The second option is the specific chip that code will be compiled for. The last thing on the line is the file containing the C code that will be compiled.

Programming the Chip:

To program a chip you will take your device programmer and connect the chip you want to load with your program. Unless you are using a socket programmer like the PIC-MCP-USB, you will need to consult the datasheets of the programmer and the chip to be programmed for the proper connection. Once properly connected, you will need to run the program to run the programmer:

For a PICStart+ programmer on /dev/ttyUSB0 programming a PIC16F887 :

picp /dev/ttyUSB0 16f887 -ef -wp blink.hex -rc

For a PICkit 2 programmer programming a PIC16F887:

pk2cmd -M -PPIC16f887 -Fblink.hex

If you are programming another chip, or the PICStart+ programmer is on a port besides /dev/ttyUSB0, you will need to make corresponding changes to the commands.

Note: The code provided for the PIC16F887 disables low-voltage programming. Some of the programmers available but not directly mentioned only perform low-voltage programming. If you have one of these programmers, you will need to change the code so that the low-voltage programming bit in the configuration words allows for low-voltage programming. The low-voltage programming pin on the microcontroller will also need to be pulled low during normal operation.

Wire the Circuit:

The circuit for this project with the code provided is really simple to breadboard. Below are the schematics for the three chips:

Start out by connecting the Vdd pins to a positive voltage source between 4.5 volts and 6 volts and the Vss pin to ground. The 40 pin PIC16F887 and the 14 pin PIC16F688 will both need a pullup resistor on their master clear pin. To any one or all of the PORTC pins (or GPIO pins for the PIC12F675), connect LEDs with current-limiting resistors to ground. Note that pin 4 of the PIC12F675 is only an input and will not light an LED. The current out of any pin of the three chips used is limited to 20mA, so the current-limiting resistors are optional for most cheap jellybean LEDs. What you should see when you power up the circuit are blinking LEDs. The LEDs should be lighting to a binary count.

Your turn!

Now that we have given you a start with programming PICs using Linux, we hope to see more projects using these chips and the tools we have mentioned above. Though this article was written for Linux users, Windows and MacOS X users should be able to use sdcc for their PIC programming needs.

Image information: The Tux logo is by Larry Ewing, Simon Budig, and Anja Gerwinski, via Wikimedia Commons. The Microchip logo is a registered trademark of Microchip Technology Incorporated.

94 thoughts on “How-to: Program PICs Using Linux

  1. The main advantage of PICS is also that all the datasheets and support are great.
    MPLAB sucked anyway, but that seems to be partially solved now as well. Thanks for that tip guys. Only reason why I still had windows on my PC. Thanks for the short pic tutorial.

  2. The religious followers of any MCU always make me giggle…

    I have used PIC, MSP430, AVR, and very briefly played with the Cypress PSOC and STM32. I prefer the MSP430 for low power apps and the PIC for most things else but thats just due to the amount of time I have worked with them!

    AVR fans always say PIC’s are slow, but they only compare AVR’s against 16F devices. The 18F devices are not that bad (not that good, but they do the jobs I have expected of them) and the PIC32 on my benchmark code (floating point digital filter) was slightly in the lead over the STM32.

    Lets argue less over MCU’s and get some more projects done with whatever MCU brand we feel comfortable with using :)

  3. @therian

    You’re just as fanatic (and annoying) with your anti-Mac, anti-Arduino, anti-hacker attitude.

    Real hackers and engineers use all of these. Once more, Mac is a great UNIX with an excellent GUI on top of it. It will always be much easier and more powerful to build and use tools on *nix systems than it will ever be on windows sytems, which you would know if you were a real engineer or hacker.

  4. I am an engineer/researcher – most engineers use Linux & Windows in industry. I have only met 2 people using Mac’s in industry, they do exist but they are a lot rarer than people using Linux/Win dual boot setups. Sometimes you unfortunately need windows in some shape or form for some FPGA dev tools – either no Linux distribution is offered or if they are (ISE 12) some tools are broken.

    All engineers do hack so to speak and as an engineer I love the idea of the Arduino – it’s getting a lot of people into embedded systems and building things – that can’t be bad!

  5. After reading the PIC24F getting started posts, ordering a couple PIC24FJ64GA002s and trying to find out a way to program them, it turned out it takes all kinds of expensive programmers.. Then a while later, piratepicprog becomes available, but it turns out there isn’t really a proper development thing like avr-gcc for the AVRs.
    Then I see this post, and I think that I’ll finally be able to program them.. Nope.
    Hackaday showed us how great and awesome the PIC24F’s are in the webserver on a businesscard posts, and now they’re back to the other PICs!

    –Nathan

  6. Hi Guys.
    I program PIC’s using assembler.
    Other than actually having to think in binary, Assembler is a magnitude order of simplicity over C, which is pretty restricted if you think you can specify 2+ dimensional arrays.

    Assembler usually works out much smaller than the equivalent compiled C AND it runs faster as a result.
    PIC’s usually mean low current and having to run at 4 megs to get the speed when you can program in assembler and run at 32 kHz and watch the current consumption drop through the floor.
    30uA vs 1mA for a PIC16LC711 i.e.

    Great site. Well done.

  7. Wow, when I mentioned PICs a while back I didn’t realise I would start a war!.

    The comments about expensive programmers is erroneous. It isn’t really that bad.

    If you want a really GOOD programmer, then PICSTART PLUS is a good programmer I have used for years and it is still connected to my PC.
    It will program all the DIP packages.
    IF you want to program the Surface mount devices, Picstart is a tad useless so, I suggest IF you are programming surface mounted devices, these are traditionally programmed IN Circuit, that is soldered in place, so you are EITHER reprogramming a part on a board you have acquired OR you are making your own boards (like I do for a professional living. I am a PROTEL99SE man).

    Look to ICD3 as this is a programmer AND a rather find debugging tool that works with old and the more modern chips that allow for all sorts of clever stuff like reading internal registers.

    There are other programmers like one made by MELABS but cheaper usually means so oddity in operation.
    The PICSTART programmer you plug the chip in with pin one at the top.
    With MELABS, the chip might need to be slid down the 40 pin sicket or even fitted the ‘wrong way round’ as MELABS are not as sophisticated at the PICSTART

    Maybe a bit off topic so I apologise.

    The way to learn PICs is usually (like I did) with a simple project and a general purpose chip like say the PIC16F818 as this is not ‘too much’ for the newbie.

    The beauty of PICs and I am certain that the same can be said for AVR chips, is that porting code from one chip to another is not that hard.
    You might need the data sheets as things like the Analogue to Digital converter on the ‘818 need to be handled ever so slightly different to say the F73 or the F77 device which have serial ports.

    programing a PIC from a blan page is a nightmare and I admit I stole my header files that i have modified extensively now, from the web and Microchip.

    IF you want to program PIC’s I would always suggest ASSEMBLER as a first important stage as knowing what the code looks like allows you to locate the foul mess that C can make of it.

    Starter kits like PICDEM 1 and 2 are wonderful.
    Once you have one, you will eventually start to make your own boards for your own projects.

    As an aside… The Microchip ICD3 programmer uses an AVR chip.
    You guys sound really smart. Smarter than me because C and Linux go over my head and I am paid a LOT of money to pull what I do out of a hat.

    Whilst I use the latest MPLAB, I STILL have a 16 bit V5.7 as I like the interface better than V8.xx.
    They are both free.
    Thanks for reading.

  8. @Rich T Kirk: “either no Linux distribution is offered or if they are (ISE 12) some tools are broken.”

    I’m running ISE12.3 on Ubuntu but admittedly I’m not targeting the latest devices. What’s broken?

  9. Heads up for anyone having trouble compiling pk2usb. If you’re getting an error like this:

    pk2usb.h:49:26: error: usb.h: No such file or directory
    pk2usbcommon.cpp: In member function ‘void CUsbhidioc::CloseReport()’:
    pk2usbcommon.cpp:648: error: ‘usb_release_interface’ was not declared in this scope
    make[1]: *** [pk2usbcommon.o] Error 1
    make[1]: Leaving directory `/home/jason/Programs/pk2cmdv1.20LinuxMacSource'
    make: *** [linux] Error 2

    You need to install libusb-dev (for Debian)

  10. I’m a PIC fan myself. Not for any religious reasons or other forms of fundamentalism, but simply because they are extraordinarily cheap, get the job done, are hard to burn, and are powerful. They come in a wide range of varieties, and, contrary to what has been written here, compatibility is very very good across families 8especially 10, 12, and 16, maybe not so much for 18 and 24 but for our benefit).

    I remember the first time I ever tried a PIC it worked right away, as advertised. It was the PIC16F84, becuase there were a lot of free programmers one could build around the parallel port of the PC.

    I subsequently moved on to the much cheaper and powerful PIC16F628A, since it had its internal clock you just power the thing and it runs.

    These chips still exist. And you can buy them for ridiculously low prices.

    Why no AVR or something else? No need, the PIC is as powerful for less money and less hassle. The assembly is pretty straightforward. The datasheets are easy to read and understand. So my reasons for keep using have always been pratical ones, not that I have anything agains other solutions.

    I currently moved on to PIC24F, and the assembly is incredibly powerful, and the $1.60 chip delivers 16MIPS and has enough RAM and FLASH for my most ambitious project (to date) where I was able to fit a ZigBee radio module stack, a mesh networking protocol, an over-the-air firmware update (with automatic recovery), a proprietary decryption algorithm, software configurable TRIAC controllers, LED controllers, IR decoders and synthesizers, software serial ports, generic control of I/O, and many more peripheral modules, and for each you can remotely configure how many of each you will use, on what pins, with what bitrates, all independent. And I still have 5% left on the flash and about 25% free RAM. The network addresses and passwords are all managed by the software and stored in EEPROM, and are selectively replaced during firmware updates.

    When I look at all this inside a PIC that costs under $2 and uses up less than 4mA of current I cannot avoid being amazed. It shows how powerful its assembly is, and it truly speaks to its clever design. Before starting this project I looked at all other solutions (using estimates of code size) and I could not find any other alternative for under $5. And even if I could spend $5 no other solution had such low power consumption.

    On the other end of the spectrum I used a PIC10 to control a power transistor to do a switched power supply to convert 240VAC to 5VDC. It needed to be small to fit inside wall sockets, for domotics. I found nothing cheaper, nothing smaller, and nothing more powerful, and with less current consumption, all at the same time. Price: $0.40. Size: sot-23. Speed: 1 MIPS (capable of generating 1us pulses to the power transistor). Current: 0.6mA.

    Of course price, size, speed, and power consumption, are possibly not the only decisive factors when selecting a platform, but for me these are usually the most important and that’s why I like PIC over other platforms.

    For all of you out there that don’t know where to start, here is a list of what I think of some models:

    PIC10 – Ultra small (6 pins, 4 I/O), ultra simple to use, ultra cheap ($0.40 to $0.60 or so). No debug, but MPLAB has a very good simulator, so I never had any surprises: after the simulator (which includes logic analyzers!) shows good results just program and it will work. Some PIC10 have ADC, and I used one of those for the cheap ultra-compact switched mains power supply I mentioned above.

    PIC12 – Still small (8 pins, 6 I/O), still simple, cheap (about $1). Some have EEPROM. No debug (needs special headers, so for me that is the same as having no debug capabilities). Good for production where you need an EEPROM to store configurations. If you don’t need an EEPROM a PIC10 may be able to do the job. If you need more RAM or FLASH (or pins) then a PIC16 will do the job better.

    PIC16 – An extremely large family, with all kinds of peripherals. The sizes and prices vary a lot, as well as its features. PIC16F628A is a good entry point, although I can’t remember now which programmers can this chip debug in circuit. Although I used this chip for a long time in all my PDIP designs, I currently use only PIC10, PIC12, and PIC24F (mainly all SMD). The PIC16 sits somewhere in a mid-range that I ended up not using anymore, although they also exist in SMD packages. Still, a nice family.

    PIC24F – Cheap ($1.8 to $3 or so), simple to use, and available in PDIP. The assembly is a delight, extremely powerful with instructions like mov [w6++],[w13–], or repeat #57 clr [–w0]. It reminds me of the Motorola 680X0 assembly power, but even more so! There are no banks, so programming is very linear. The stack is in RAM, so you can do preemptive multitasking, for example. The core is 16-bit, and there is a hardware multiplier of 16×16 (16 million multiplications per second) and hardware support for a 32/16 or 16/16 division. So FIR’s or IIR’s become a breeze. Carry operations optimized so that 32-bit additions can take as few as 2 instructions, and 64 bits 4 instructions. Its a little harder to setup the “hello world” but it is definitely worth it.

    All the families have a ton of peripherals, but I usually don’t use them (most functions are not hard to implement in software). Typically I use only the “hard ones”, like ADC, EEPROM, CRC, etc., and not the “easy ones” like serial ports or I2C.

    So my sugestion for someone who doesn’t know where to start is:

    a) Select a chip (PIC12F675 and PIC16F628A are good places to start). You can check the Microchip website, in the 8-bit family section. List all the PIC’s and then look for the items that interest you more (I2C, CAN, UART, lots of RAM, …) and click it to see a simple description.

    b) Get its datasheet from the Microchip site and read it (they are simple, complete, and thorough… well, maybe not as much for the PIC24, but you can get all the parts for all the different modules).

    c) Try a hello world in the MPLAB simulator using assembly until it looks good.

    d) Program the chip. Depending on the programmer and the chip you use you may be able to debug in circuit or not. The programmers to consider are the Pikit2, Pikit3, and ICD3. The first 2 are much cheaper, but they don’t debug as efficiently (no arbitrary breakpoints, for example, and support less chips). Check the combination of programmer and PIC you selected for debug (that information is available in Microchip’s website). As far as I remember most programmers program most chips (almost all do all), but not all programmers debug all chips. If debugging is not important (as it was not for me) the selection becomes much simpler.

    e) Try out other features of the chip you selected until you feel you are starting to understand the thing as a whole.

    f) When you feel comfortable select another chip from another family. If you selected a PIC12 then try a PIC16, if you’ve selected a PIC16 then try a PIC12.

    g) Read its datasheet. Try to find the differences and change your code to adapt to them. Try macros and defines to make the same code compile on both families.

    h) Feeling good? Try out a PIC24F. Get ALL the datasheets, but read only the main one and the additional ones (for peripherals) you think you will be needing (just dedicate a quick overview to the other ones).

    i) Find the assembler differences. Try to make the same code as you did for families 12 and 16 in the 24. Read the instruction set summary to see how many instructions you have. Carefully check the Wb,Ws,Wd,… notation to understand that you can do mov w3,[w10+237] or bclr [w1++],#12. Also try out the byte operations.

    j) Still feeling good? Need more challanges? Do macros that translate code you did for PIC12 and PIC16 for the native PIC24F. I did it, it was awesome! For example, movlw 35 can be automatically translated to the native mov #35,w0, and movwf DEST can be automatically converted to mov.b w0,[w10+DEST] (why w10+DEST and not just DEST? …if you try it you will know!)

    k) Now find some real world project that you need to solve and power to you!

    Too much work? .. not much more than for other platforms… in fact, considering that by step d) you will already have a fully functioning chip I think you can’t beet the simplicity with other platforms.

  11. Real men program in assembler. Really crazy men program in a hex editor.

    You know you’ve been around for a little while when the first computer you ever used had to have the bootloader clocked into memory by hand using 16 DPDT switches and one momentary and the default output interface was a bunch of LEDs showing raw register data.

    Keep the articles coming and don’t let the trolls get you down.

  12. whether its pics or avr or 80c51 does not matter
    what newbies like me need is for clever hackers to
    package the toolsuites(ide,compiler,simulator,drivers for different programmers etc)so that we can move over to ubuntu(available easily in africa).with well explained howtos so that we can migrate successfully
    and automated installers like you have on windows .lets be totally honest a graphical install is less intimidating.all i want is to drive the car not tweak a dozen things to make it drive.i am told i am expecting too much out of something free(linux).all the linux people i come across on the net are so clued up and brilliant i just cant see why they cant work together .its a shame
    UBUNTU for human beings

  13. Who other than noobs and complete useless would waste a single minute with pic’s and their insane arch.?

    Most of all whe he or she can use proper mcu’s such like avr’s which are fully and properly supported on unix systems?

  14. You can also integrate it in the eclipse or other IDE much lighter like geany, by using a make file, where make write is for write on pickit 2.

    here is a sample:

    # Makefile SDCC
    #
    # 24-08-2010

    PRJ=main
    OBJS=$(PRJ).o
    #Objects:
    #OBJSINC=adc.o usart2.o eeprom_pic.o timer.o spi.o spi_eeprom.o spi_rtc.o
    #OBJSINC= config3.o
    PLATFORM=18f2520
    LIB=-I /usr/share/gputils/lkr -I /usr/share/sdcc/lib/pic16 -I /inc
    LIBINC=-I "../inc"

    #compile with all objects
    #all: adc usart2 eeprom_pic timer spi spi_eeprom spi_rtc $(PRJ).hex
    #all: config3 $(PRJ).hex
    all: $(PRJ).hex

    $(PRJ).hex: $(OBJS)

    gplink \
    -I"/usr/bin/../share/sdcc/lib/pic16" -I"/usr/share/sdcc/lib/pic16" -I"/usr/bin/../share/sdcc/lib" -I"/usr/share/sdcc/lib" -I"/inc" \
    -w -r -o $(PRJ) $(PRJ).o crt0i.o $(OBJSINC)\
    libdev$(PLATFORM).lib libsdcc.lib libc18f.lib libio$(PLATFORM).lib

    $(OBJS): $(PRJ).asm
    gpasm -c $<

    $(PRJ).asm: $(PRJ).c

    sdcc -S -mpic16 $(LIBINC) -p$(PLATFORM) \
    --optimize-cmp --optimize-df --obanksel=2 --opt-code-size --fommit-frame-pointer --denable-peeps --stack-auto --main-return $< \

    ##
    #
    # Compile header files to objects
    #

    #~ config3:
    #~
    #~ sdcc -V -mpic16 $(LIBINC) -p$(PLATFORM) \
    #~ --optimize-cmp --optimize-df --obanksel=2 --opt-code-size --fommit-frame-pointer --denable-peeps --stack-auto\
    #~ -c ./inc/config3.c -o config3.o

    #adc:
    #
    # sdcc -V -mpic16 $(LIBINC) -p$(PLATFORM) \
    # --optimize-cmp --optimize-df --obanksel=2 --opt-code-size --fommit-frame-pointer --denable-peeps --stack-auto\
    # -c ./inc/adc.c -o adc.o
    #
    #usart2:
    #
    # sdcc -V -mpic16 $(LIBINC) -p$(PLATFORM) \
    # --optimize-cmp --optimize-df --obanksel=2 --opt-code-size --fommit-frame-pointer --denable-peeps --stack-auto\
    # -c ./inc/usart2.c -o usart2.o
    #
    #eeprom_pic:
    #
    # sdcc -V -mpic16 $(LIBINC) -p$(PLATFORM) \
    # --optimize-cmp --optimize-df --obanksel=2 --opt-code-size --fommit-frame-pointer --denable-peeps --stack-auto\
    # -c ./inc/eeprom_pic.c -o eeprom_pic.o
    #
    #timer:
    #
    # sdcc -V -mpic16 $(LIBINC) -p$(PLATFORM) \
    # --optimize-cmp --optimize-df --obanksel=2 --opt-code-size --fommit-frame-pointer --denable-peeps --stack-auto\
    # -c ./inc/timer.c -o timer.o
    #
    #spi:
    #
    # sdcc -V -mpic16 $(LIBINC) -p$(PLATFORM) \
    # --optimize-cmp --optimize-df --obanksel=2 --opt-code-size --fommit-frame-pointer --denable-peeps --stack-auto\
    # -c ./inc/spi.c -o spi.o
    #
    #spi_eeprom:
    #
    # sdcc -V -mpic16 $(LIBINC) -p$(PLATFORM) \
    # --optimize-cmp --optimize-df --obanksel=2 --opt-code-size --fommit-frame-pointer --denable-peeps --stack-auto\
    # -c ./inc/spi_eeprom.c -o spi_eeprom.o
    #
    #spi_rtc:
    #
    # sdcc -V -mpic16 $(LIBINC) -p$(PLATFORM) \
    # --optimize-cmp --optimize-df --obanksel=2 --opt-code-size --fommit-frame-pointer --denable-peeps --stack-auto\
    # -c ./inc/spi_rtc.c -o spi_rtc.o

    # Escrever e verificar PIC, presenvando os dados da eeprom. Usa Vpp externo
    write:

    pk2cmd -W -Z -E -MPIC -YPIC -R -PPIC$(PLATFORM) -F$(PRJ).hex
    #pk2cmd -Z -E -MPIC -YPIC -R -PPIC$(PLATFORM) -F$(PRJ).hex

    # Desligar Vdd da PIC
    hold:

    pk2cmd -PPIC$(PLATFORM) -T

    # Ligar Vdd e Reset da PIC
    release:

    pk2cmd -PPIC$(PLATFORM) -W -R

    erase:

    pk2cmd -E -W -PPIC$(PLATFORM)

    reset:

    pk2cmd -I -W -P -R

    clean:
    rm $(OBJS)
    rm $(OBJSINC)
    rm $(PRJ).cod
    rm $(PRJ).hex
    rm $(PRJ).asm

    1. I don’t feel qualified to answer this as my answer seems too simple?

      You should have a few lines that look SIMILAR to this…
      LIST P=18F4620 ; directive to define processor
      #include “P18F4620.INC” ; processor specific variable definitions
      ERRORLEVEL 0, -302, -303, -306, -305
      ;—
      MPLAB looks in it’s own install directory for the include files by default in MY case…
      C:\Program Files (x86)\Microchip\MPASM Suite
      I have in the past copied relevant include files in my source directory and then ADDED the .inc to the project forcing MPLAB to use THAT file (I used to tweak the .inc files)

      I note YOUR file name is “pic12f675.h”
      The 16 bit MPLAB used .h files, the later MPLAB uses .INC
      Check that the filename is correct as it MIGHT be “p12f675.h” or “p12f675.inc”and not “pic12f675.h”.

      As an aside, I use CAPITALS for SYSTEM names and Variables, such as “TMR0” and use Camel Case for MY variables, like “TMR0InitVal”.. just to differentiate between my types input and names as used in the #Include files, such as SPBRG, etc.

      That’s all I can offer.
      This not a hard one to solve because of MPLAB can’t find the file, it’s probably mis-named, missing completely., or somewhere else.
      Hope my humble offering is at least in the right direction.

  15. I am getting an error when I try to install pk2cmd. I copied and pasted the commands in one at a time. Am I the only one getting this error? Missing parts of installation
    .
    cp: cannot stat ‘pk2cmd’: No such file or directory
    make: *** [install] Error 1

    .

  16. got stuck on sdcc compiling . So running sdcc -p16f887 blink.c
    got

    blink.c:6:27: error: pic/pic16f887.h: No such file or directory
    blink.c:12: warning 197: keyword ‘at’ is deprecated, use ‘__at’ instead
    blink.c:12: error 20: Undefined identifier ‘_CONFIG1’
    blink.c:12: error 2: Initializer element is not constant
    blink.c:13: warning 197: keyword ‘at’ is deprecated, use ‘__at’ instead
    blink.c:13: error 20: Undefined identifier ‘_CONFIG2’
    blink.c:13: error 2: Initializer element is not constant
    blink.c:43: error 20: Undefined identifier ‘TRISC’
    blink.c:65: error 20: Undefined identifier ‘PORTC’

  17. i tried to compile .asm source file using sdcc ,but it gives error
    “at 1: warning 119: don’t know what to do with file ‘a.asm’. file extension unsupported

  18. Hi there
    This nice web page that come up almost first in every Google search, is obsolete and some of the links are broken. This I found out after trying out SDCC for the PIC to solve a related ‘issue’. This was for ‘lubuntu’ and programming ‘old code’ into a 12F series. So I can recommend the following:-

    SDCC (first)
    http://sdcc.sourceforge.net/
    For the download
    https://sourceforge.net/projects/sdcc/files/
    I downloaded the ‘latest version’.
    Also downloaded ‘gputils’ for PIC utilites and extra support. From here:-
    https://gputils.sourceforge.io/

    Then I looked for sample programs for SDCC and downloaded them from here:-
    https://github.com/diegoherranz/sdcc-examples
    He says you should install these in (l)ubuntu :-
    sudo apt-get install bison flex g++ libboost-dev texinfo
    You can also sudo apt install gputils… not compile from source.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.