Jump to content
 
  • 0
KM1

PIC16f1x vs PIC18f

Question

Hello,

This forum is very refreshing - good content and respectful users!

I have a good amount of experience with PIC products, but not full-time day in and day out. My question is regarding the pros and cons of using the advanced versions of the PIC16f family vs the 18f family. I really like the analog peripherals amongst other features and I wonder what others think for new project development?

For example, I am looking at a redesign of a product that currently has been using the PIC16f887 for the last 5 years. I am looking at the PIC16f18877 as a replacement unit and have spent some time wading through the 600+(!) page data sheet looking for opportunities to simplify the original circuit design and take advantage of some of these features. I am not looking for a way to avoid reading the data sheet, just some other points of view.

Keith

  • Like 1

Share this post


Link to post
Share on other sites

6 answers to this question

Recommended Posts

  • 0

Hi Keith,

Welcome to our forum! We aim to please ūüôā

Short answer is that I think the pic16F18877 is an excellent choice to replace the 16F887. It can pretty much do everything the 887 can do better since it can go 50% faster, and has a lot more to offer like CLC’s, PPS on the pins and a host of other features.

Perhaps you can give us a little more detail on what you are aiming to do and how. Will you be using XC8 and using C for this and what are you looking for in terms of analog?

There are also a lot of interesting goto parts in the PIC18 family, in particular look at the 18FxxK42, it has interesting additional features like DMA and vectored interrupts which are not on the PIC16F1 parts. They also have more flash and RAM if that is what you need.

 

 

  • Like 1
  • Helpful 1

Share this post


Link to post
Share on other sites
  • 0

In general any PIC16Fxxx device such as the PIC16F887 can effectively be migrated into a PIC16F1xxxx design (such as the PIC16F18877) as that was a key objective of the F1 redesign.  Immediate advantages that you will see are more FLASH, more RAM and more peripherals.  Other advantages are very important but can be a little subtle unless you are an assembly programmer.  In C, these additional advantages tend to reveal themselves in code that is as fast and a little smaller than the same code on a PIC18.  These other advantages are a flat memory map across FLASH & RAM (at least for pointers), 2 FSR's (pointers) and more efficient banking.

The PIC16F1's have 31 banks to solve the problem of a 512byte RAM/SFR limit.  The new limit is 4K and there are a number of PIC16F1's that make that available.

The PIC18 also has a 4K RAM limit but its FLASH limit is 2MB.  There are no PIC18's with 2MB but there are many with more than 56KB (The PIC16F1 limit). The new PIC18FxxK42 family has lots of new features and more RAM but there are not very many of the new PIC18 CPU available yet.

Welcome aboard and we are very interested in what you are doing with your project.

  • Helpful 1

Share this post


Link to post
Share on other sites
  • 0

My main goals with this project:

  • replace the original asm code with maintainable C - I am using MPlab X and the v2 c compiler. I have the asm source code and will be working with it, but it is the product of many years of tweaking by an (older and very smart) engineer now retired.
  • simplify the current board circuitry - one example is to eliminate an external AD converter and use the built in. I believe there is no need for special features provided by the existing converter (Texas Instruments TLC1543, 10-bit, serial output), I believe the converter has been in the design since before on-board AD was commonly available (mid to late 90's)? I think I can reduce my overall BOM cost by approximately 15-20%
  • The PIC's main job is to read 5 channels of AD, perform some relatively simple math, provide data to the user via LEDs and 7 segment displays, and store some data for calculations. There is a serial interface to an optional device, calibration data stored in EEPROM, and a simple user interface.

Longer term, I hope to add wireless connectivity, an improved UI, and possibly combine the optional device with this one to market a combination unit which may have appeal.

I have looked at the 18fxxk42 family and will be getting some to try in addition to the 18877s I have just received.

Keith

Share this post


Link to post
Share on other sites
  • 0

Everything in your list of requirements looked pretty reasonable for the PIC16 until you said wireless.  For wireless, a lot depends upon the details.  Bluetooth, WiFi, Subgig, LoRa, etc will all require some kind of RF module.  Each RF module generally comes with a co-processor that handles the heavy lifting for the wireless protocol, however... Each wireless module will still have demands upon the host processor.  For example, the WINC1500 wifi driver on an ATMEGA4808 took around 10k.  After reviewing the driver, it would be possible to shrink the code quite a lot but it would be at the expense of supporting the code for the duration.

That is not to suggest that wirelesss is not appropriate for a PIC16, it is just that wireless often comes with additional expectations that are not immediately apparent.  Here are a few:

1) Security, most wireless applications require a secure and authenticated connection to the host.

2) phone interface, many wireless applications seem to be tied to iOS and Android.  This generally implies BLE4.2 but could mean wifi.

3) IoT.  Obviously wireless existed before the internet, most of the wireless customer discussions ended up being Internet of Things discussions.  This drove the security requirements.

4) Over the air update.  because security and wireless standards are moving fast, most customers end up requiring the ability to update the software to adapt with the times.  

When you start going through these requirements you can quickly find yourself in a 128k MCU and that will be a PIC18 or AVR in 8-bit land.  A reasonable rule of thumb with these kinds of applications is the PIC16/18 will require 2x the FLASH as an AVR for the same application.  The details on why this is true would be a future technical post.

  • I Agree 1
  • Helpful 1

Share this post


Link to post
Share on other sites
  • 0

I think you will be pretty happy with the PIC16F1xxxx for that kind of project. 

The main advantage of the K42 would be the additional RAM and FLASH. I totally agree with @N9WXU there - when you are adding wifi and communication protocols that counts for a lot and you may end up constrained if you are trying to do it all on the smaller PIC16. If that is the next step you may find yourself porting the code right after writing it, which is never a good timeline.

The K42 has up to 128KB of FLASH and 8KB of RAM while the PIC16 is capped at 56KB of FLASH and 4KB of RAM. Although it should be fairly straightforward to port the PIC16F18877 code to any K42 if it is written in C and if you use something like MCC to generate the hardware code for you. If you need help with that part please do give us a shout, we can definitely lend a hand with that part!

  • I Agree 1
  • Helpful 1

Share this post


Link to post
Share on other sites
  • 0

Thank you Orunmila and N9WXU. I appreciate you taking the time to answer my questions.

Keith

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


 


  • Popular Contributors

    Nobody has received reputation this week.

  • Similar Content

    • By KM1
      Hello,
      I have run into a strange (for me) issue with the rtcounter module as provided by MCC and shown by the example program in the blog area of this site. I am using MPLabX and XC8, both up-to-date versions and I am trying the example on a pic18F47k40 xpress board. The issue is I set an output (RA4) in main after initializing the pic and then enter the while(1) loop where the rtcount_callNextCallback(); is called. The output now is turning on and off. The off duration is typically ~60u seconds, and on time can be varied with changes to the timer interrupt settings (I use a 1mS timer0 in 16 bit mode) and the number sent to the callback. Approximately every 3mS, the off time increases such that that cycle (only) is approx 50% duty cycle.
      Turning the output on or off in the callback routine has no effect - I initially wanted to toggle on and off at a speed visible to the eye. Commenting out the callback in the main loop stops the output from going low.
      I have checked errata and used the data sheet to confirm register settings, I tried moving the current-limited LED from RA4 to RA2, and I have studied the example program looking for obvious differences that may cause this behaviour.
      I would appreciate thoughts and/or suggestions.
      Keith
         
    • By burkart
      Hello All,
      I am working on a project (in MPLAB v5.10) with a PIC18F27K40 (PIC18 library v1.77.0) and I'm using the MCC (v3.85.1) generated I2C drivers, I2CSIMPLE from the Foundation Services. I can read from and write successfully to devices on the I2C bus. The problem comes when I try to communicate with a device that's not on the bus, the micro goes into an endless loop waiting for i2c_status to not be busy. My knowledge of programming in C is about 6 on a scale of 10, and for programming for embedded purposes, about 5 out of 10. I would like to have it so that I can check if a specific device is present on the I2C bus, and also be able to recover from errors on the bus without it going into a loop indefinitely.

      This I2C driver is pretty complex, and I am having difficulties wrapping my head around it. How would I make it so that the driver just returns an error or something I can check for status, rather than loop endlessly until the operation completes, which it never will?

      I have not edited any of the MCC generated code. This includes leaving the IRQ enable line commented in the i2c_master.c file, so instead it polls instead of using an interrupt to check if the i2c operation has completed.
      // uncomment the IRQ enable for an interrupt driven driver. // mssp1_enableIRQ(); Following is an example of how I am calling the i2c driver.
      i2c_write1ByteRegister(address, 0x0D, 0x07); // GPPUB pull-ups on pins 0-2 I am attempting to initialize a port extender, MCP23018, specifically enabling some pull-up resistors. I would like to issue this command, and if the extender is not present, then the micro will perform some tasks differently. With the port extender present the write operation works as expected and everything is fine. Of course the problem is when the extender is NOT on the bus to acknowledge.
      I have another question as well. This driver seems to operate a little slow. When watching the bus with a logic analyzer I noticed a rather long pause between bytes. I went looking through the i2c driver and in i2c1_driver.c I found the following code which I suspect is the cause.
      inline void mssp1_waitForEvent(uint16_t *timeout) { // uint16_t to = (timeout!=NULL)?*timeout:100; // to <<= 8; if(PIR3bits.SSP1IF == 0) { while(1)// to--) { if(PIR3bits.SSP1IF) break; __delay_us(100); } } } What is the purpose of the 100 us delay in the while loop? Reducing or eliminating the delay results in reducing or removing the pause between byte transactions, but I don't know enough to know how else this edit will effect the driver. Also, what is the commented out code at the top of the function used for? Is this part of the infinite loop problem I mentioned above?

       
      --
      James Burkart
    • By Orunmila
      error: variable has incomplete type 'void'
      If you are getting this error message trying to compile code that used to work or from some example code you found somewhere it is very likely because of the changes in the XC8 interrupt syntax introduced with V2.0 of XC8.
      Specifically I am getting this today for my interrupt service routine definition. I used to use the age-old way of doing this in XC8 as follows:
      // Old way to do this void interrupt myISR(void) { // Old way Interrupt code here } After the changes to the XC8 compiler which were mostly motivated to get better C standard compliance, particularly with C99, the syntax for that function should now use the commonly adopted concept of function declaration-specifier attributes, which traditionally start with 2 underscores and contains either a list of parameters in brackets or have empty brackets if no parameters are present. 
      // New and improved and C99 compliant way to specify an interrupt service routine in XC8 void __interrupt() myISR(void) { // New and improved interrupt code here } This syntax is now also consistent between XC8, XC16 and XC32
      Please see this post for more information on how to either work around this or change to the new syntax.
      https://www.microforum.cc/topic/5-i-used-to-use-to-locate-variables-but-since-xc8-20-this-is-no-longer-working/
    • By Orunmila
      I just downloaded XC32 V2.15, I was using V2.10 before. I find that some of my projects no longer compile. On my first check I noticed that the problems seem to occur when inline functions are used and the same header where the inline implementation is done is included in more than one compilation unit?
      Has any of you seen similar issues?
      I will investigate further and post here if I arrive at an answer.
       
      UPDATE: Ok, I managed to make a small test project to replicate the problem. I am attaching it here. 
      TestInlineXC32_2.15.zip
       
      Next I am going to test this on some other compilers to see what the deal is. I have confirmed that with that project when you switch it to V2.10 or older it all compiles just fine, but if you use V2.15 it failes to link with the following error:
      "/Applications/microchip/xc32/v2.15/bin/xc32-gcc"   -mprocessor=32MZ2048EFM100  -o dist/default/production/TestInlineXC32_2.15.X.production.elf build/default/production/main.o build/default/production/otherFile.o          -DXPRJ_default=default  -legacy-libc    -Wl,--defsym=__MPLAB_BUILD=1,--no-code-in-dinit,--no-dinit-in-serial-mem,-Map="dist/default/production/TestInlineXC32_2.15.X.production.map",--memorysummary,dist/default/production/memoryfile.xml
      nbproject/Makefile-default.mk:151: recipe for target 'dist/default/production/TestInlineXC32_2.15.X.production.hex' failed
      make[2]: Leaving directory '/Users/ejacobus/MPLABXProjects/TestInlineXC32_2.15.X'
      nbproject/Makefile-default.mk:90: recipe for target '.build-conf' failed
      make[1]: Leaving directory '/Users/ejacobus/MPLABXProjects/TestInlineXC32_2.15.X'
      nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
      build/default/production/otherFile.o: In function `myInlineFunction':
      /Users/ejacobus/MPLABXProjects/TestInlineXC32_2.15.X/inlinedheader.h:6: multiple definition of `myInlineFunction'
      build/default/production/main.o:/Users/ejacobus/MPLABXProjects/TestInlineXC32_2.15.X/inlinedheader.h:6: first defined here
      /Applications/microchip/xc32/v2.15/bin/bin/gcc/pic32mx/4.8.3/../../../../bin/pic32m-ld: Link terminated due to previous error(s).
      collect2: error: ld returned 255 exit status
      make[2]: *** [dist/default/production/TestInlineXC32_2.15.X.production.hex] Error 255
      make[1]: *** [.build-conf] Error 2
      make: *** [.build-impl] Error 2
      BUILD FAILED (exit value 2, total time: 680ms)
       
       
       
    • By Orunmila
      If you have purchased a "MPLAB(R) Xpress PIC18F47K40 Evaluation Board" from Microchip (part number DM182027) and you are running into difficulty because the board is behaving strangely it is most likely caused by a silicon errata on this device!
      The errata can be downloaded here: http://ww1.microchip.com/downloads/en/DeviceDoc/PIC18F27-47K40-Silicon-Errata-and-Data-Sheet-Clarification-80000713E.pdf
      The relevant section of the Errata is shown at the end.
      What is happening is that the compiler is using a TBLRD instruction somewhere and this instruction is not behaving as expected due to a silicon bug in REV A2 of the PIC18F47K40, causing the read to fail and the program to malfunction. Typically this happens as part of the C initialization code generated by the XC8 compiler, and since the compiler is optimizing, changing the code may cause the problem to temporarily disappear because you have few enough global variables that a table read is no longer the fastest way to initialize the memory segment for variables with static linkage.
      The XC8 compiler can avoid generating the sequence which will cause the failure if you tell it in the linker settings to implement the workaround for this Errata. This is done by adding +NVMREG to the setting as follows. Note that this is under the section "XC8 Linker" and the Option Category "Additional Options".
       

       
      This is the relevant section of the Errata.

       
       
    • By Orunmila
      I have a bunch of old projects using the @ method to hard locate variables at a specific location in data memory, but since I upgraded to XC8 2.0 none of these are working any more!
      How do I do this with the latest compiler? I am using XC8 v2.xx.
      I also saw this error at my interrupt service routine and I suspect that this is the same problem.
      My interrupt code looks like this 
      void interrupt my_isr(void) { ... my code here } error: variable has incomplete type 'void'
×
×
  • Create New...