Since the beginning Microchip has been great at having stock of all processors, even very old ones. That has changed over the last year as many of you have found out. If you are reading this then you probably are a CCS C compiler user. The good news is with most programs it is very easy to change from one chip to another.
For example if it is hard to buy the popular PIC16F887 part, you may be able to find the PIC16F747 and that might work for your application.
In many cases the only change you need to make is changing:
Then recompile and start up the production line.
Another bonus is the newer parts seem to have more features and they are a lower cost. For example a popular 8 pin part for many classic designs uses the PIC12F675 part. The newer PIC16F18313 part is 33% lower cost with double the memory.
If you have the IDE compiler there is an easy way to find parts that might work as an alternative. Use TOOLS > DEVICE EDITOR > SELECTION TOOL
Then on the right side select the families (14 bit shown here) and the pin count range (30-47 shown here) along with anything else you want to filter by. The table shows the essential characteristics including the modules (like UART) included in the part.
This works so well because of the compiler built in functions that are customized on the fly for the chip that is being compiled. For example the built in function to read the Analog to Digital converter, read_adc().
For the 12F675 you get:
For the 16F18313 you get this with the same C code:
If you write directly to a register then you have have more trouble converting the code. For example on a PIC12F675 you might have a line like this:
#byte PORT_A = 0x05
Then you might do this in your code:
data = PORT_A;
For a PIC16F18313 the port A address is 0x0C so you could do this:
#byte PORT_A = 0x0C
Or better yet, to make the same code work on both chips:
#byte PORT_A = getenv("SFR:PORTA")
This only works if the SFR names are the same in both chips. You should also consider switching to built-ins by removing the #byte all together and in your code doing this:
data = input_a();
You can do a similar thing for bit names like this:
#bit TIMER_INT_FLAG = getenv("BIT:T1IF")
Be aware sometimes the bits, even with the same name, function differently on different chips. Taking some extra time to use built in functions can save you time in the long run.
Chips with the more advanced peripheral modules may have different options for the built in functions. It is usually easy to figure out the changes by looking at the device header in the section for the peripheral. The comparator is one module that changes a lot between chips. For example:
PIC12F675: setup_comparator( A0_A1 );
PIC16F18313: setup_comparator( CP1_A1_A0 );
Newer chips generally have new fuse settings. In general the compiler default fuses are good. You may want to review the fuses (VIEW > CONFIGURATION BITS) for the new part to make sure they are good.
If you use oscillator fuse settings we strongly recommend you remove them and use the #use delay() instead. That directive sets all the fuses and registers for the oscillator. These settings are very different between chips so using the #use delay() will make the code more portable. For example:
#use delay( crystal=8mhz, clock=32mhz )
Like us on Facebook. Follow us on Twitter.
CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.
PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.