Jump to content
 
Orunmila

Why is everybody still using the PIC16F877 ?

Recommended Posts

I was wondering if any of you have some ideas why we still see so many people using the PIC16F877 and the PIC16F877a for their projects? I can imagine that many schools and universities have programs that were based on this very old device but surely these guys must be updating their material from time to time?

Today I would expect people to use something like the PIC16F18855 or something like that. The XPress evaluation board for that device is just $13 on Digikey ( link to Digikey ) and it does not even require a programmer to program the board (it has drag and drop programming via USB - the board shows up as a hard drive MSD device). Actually I think the PIC16F18875 is a better comparison as it has the same number of pins (40).

So is any of you using the PIC16F877 and if so why that device?

Just for the discussion here is how the devices stack up, with all the peripherals and extra RAM on the newer device I really cannot see how it makes sense to use the 877! What do you all think?

  PIC16F877 PIC16F18875
Digikey 1-off price $5.09 $1.67
Max Speed 20MHz 32MHz
Flash 8k x 14 8k x 14
RAM 368 x 8 1K x 8
Package 40 PIN DIP 40 PIN DIP
I/O Pins 33 36
Operating Range 4V-5.5V 1.8V-5.5V
EEPROM 256x8 256x8
Peripherals CCP(2), MSSP(1), USART (1), TIMERS 8/16(2/1), CMP (2), ADC 10b(8 channels) CCP(5), PWM(2), MSSP (2), USART (1), TIMERS 8/16 (3/4), SMT Timer(2), ADCC 10b(35 channels), CLC (4), DSM(1), NCO (1), ZCD (1), CRC (1), CWG (3), CMP (2), DAC (1), VREF, 
  • I Agree 1

Share this post


Link to post
Share on other sites

I think the main driver here is the sheer volume of old projects available online or floating around in schools.

New users don't understand the devices well enough to adapt the code from the old version to run in the new devices, even though the new devices are so much easier to work with.
It's going to take time for all this example code to evolve from "original mid-range" to "enhanced mid-range".

Some of my favourite features of the new PIC16F devices are:

  • Internal oscillator. No need to debug a crystal circuit just to get some instant gratification.
  • LATx registers. No need to work around RMW problems.
  • Three hardware breakpoints. Don't lose "step over" etc. functionality after setting one breakpoint.
  • Linear memory. Arrays larger than 80 bytes are now easy.
  • Dual FSR pointers, able to access RAM and ROM, with automatic 16 bit pre/post increment/decrement.
  • Hardware context save/restore for interrupt code.
  • Simple single instruction RAM banking.
  • Ability to access WREG the same as any other SFR.

 

  • Helpful 1

Share this post


Link to post
Share on other sites

I recently started using Software Breakpoints as well, very useful feature which not many people know about!

You can do that like this :

LATA = 0x00;

__builtin_software_breakpoint(); // This will add a swbp instruction which will stop on the following line
NOP();                           // I like using a NOP here, makes things simple, but it is not required

LATA = 0xFF;

 

Share this post


Link to post
Share on other sites
16 minutes ago, ric said:

The table here implies that PK3 cannot do software breakpoints.

http://ww1.microchip.com/downloads/en/DeviceDoc/HWToolDebugFeatures.pdf

I'm sure I've seen them offered when I was using a PK3, but can't check right now.

Ahhh yes, that is very misleading!

So this is what that means. When you are using MPLAB-X and you are setting breakpoints using the IDE then the PK3 is not able to use software breakpoints to fulfill these requests for having a breakpoint. 

On the other hand, if you use the __builtin_software_breakpoint() as I showed above this is not covered by that statement and even the PK3 will happily break when it hits the instruction. This is achieved by jumping into the breakpoint code of the debug executive on the device.

 

  • Like 1

Share this post


Link to post
Share on other sites

The linear memory features of the "enhanced" pic16 (all the F1 devices) actually makes the PIC16 as fast as the PIC18 for most memory applications despite the PIC18 having an 8x8 multiply.  Also in the PIC16F1 are two "trap" instructions that vector your code into test memory. One of these is used by the debug exec to create software breakpoints.  But the other one is also available for some creative use.  Perhaps somebody can make a UART boot loader that lives in test memory.

  • Wow 1

Share this post


Link to post
Share on other sites
18 minutes ago, N9WXU said:

The linear memory features of the "enhanced" pic16 (all the F1 devices) actually makes the PIC16 as fast as the PIC18 for most memory applications despite the PIC18 having an 8x8 multiply.  Also in the PIC16F1 are two "trap" instructions that vector your code into test memory. One of these is used by the debug exec to create software breakpoints.  But the other one is also available for some creative use.  Perhaps somebody can make a UART boot loader that lives in test memory.

If you use the __builtin_software_breakpoint() compiler built-in function and look at the list file generated by the compiler you will see that it translates the instruction (0x003) as "trap" - this instruction is not documented in the device instruction set or datasheet, but it easy enough to discover by looking at the lst file.

  1211                           
  1212                           ;main.c: 17:     __builtin_software_breakpoint();
  1213  07F1  0003               	trap
  1214                           
  1215                           ;main.c: 18:     __nop();
  1216  07F2  0000               	nop
  1217                           

 ...

  • Wow 1

Share this post


Link to post
Share on other sites
12 hours ago, N9WXU said:

...

One of these is used by the debug exec to create software breakpoints.  But the other one is also available for some creative use.  Perhaps somebody can make a UART boot loader that lives in test memory.

That would require some information about where this test memory is, and how the second trap instruction works to "leak".

  • I Agree 1

Share this post


Link to post
Share on other sites

Undocumented instructions.. Interesting! Please share details. 

About the original post, this is simple laziness. In universities, professors have other interests than updating their slides. Another reason may be the simple architecture, which restricts students. So they have to deal with RMW problems, take care of cycles per instructions etc etc. 

I remember a simple task given to students, they had to use a very old PIC12. They had to design a piece of assembler, which displays the numbers 1 to 6 on a seven segment display. After pushing a button, the program had to stop, displaying the last active number. 

They had to prove that all numbers have equal probability of being displayed. 

Bonus points for least complexity or fastest execution.. 

 

  • Like 1

Share this post


Link to post
Share on other sites

That is a nice exercise, especially trying to do random numbers in asm is harder than people think, pn-sequences are really by far the best way to do that.

Our first challenging excercise was building a bootloader, this was on a 8031 of course 🙂

I think universities fail if they do not update their material. I know the fundamentals are still the same, but learning on ancient tools takes away a lot from the value you can get. Experience with the tools is sometimes just as valuable as foundations, that is after all why you have labs and exercises in the first place is it not?

Share this post


Link to post
Share on other sites

You're right, this was my first time with microcontrollers. I felt very uncomfortable with such an inefficient controller. A few days later, I bought an STK500 and began to experiment with Atmega32. I really enjoyed having gcc, 4 times faster execution and many other conveniences the PIC didn't have. 

I started to dislike PICs then I had to program in CCS. This "compiler" wasn't even able to understand an include of a header file, I had to include the c file. I swore to never use any PIC again.

Time passed. I got in touch with PIC at my first professional work. Things got better with HITECH - compared to CCS!

Today, XC8 is on the right way, but they should have thrown away the HITECH foundation right from the start. 

In short words, such archaic examples may be convenient for teachers in the first place, but they really repel students from working with such controllers. If they try to build own ideas with it, frustration is almost guaranteed. 

Share this post


Link to post
Share on other sites
On 1/26/2019 at 10:26 PM, ric said:

Plus you have colleges still making their students use C18... 

I have to admit, that we used this compiler too in our labs untill maybe 2 years ago.
It worked, was installed on the computers and if you have a comprehensive script
it is quite some work to keep everything at a recent level.

Another reason to stay with C18 as long as possible was the output from the first free versions of XC8.
Found it really horrible and unusable for education. It is much better now 😉
https://www.microchip.com/forums/FindPost/668751

About the ancient PICs:
We started with PICDEM2 (2002 version) boards coming with 16F877 or 18F452.
Used 18f452 and ICD2 as programmer/debugger.
When the 4520 comes out with internal oscillator we assembled the boards with this one.
Later we took out the 4520 and replaced it with a 45K22 and the ICD2 got replaced with PICkit3.

~2013 we switched to our own board. Students can buy a construction kit and build them by themselves.
Looks like these http://www.hs-ulm.de/nocache/wir/Personal/PersonalSaSchr/vschilli/Mikrocontroller/uCQ/
Maybe the 2xK22 will be replaced by a 2xK42...

About the software breakpoints:
Jason Kajita posted this some years ago: https://www.microchip.com/forums/FindPost/434136

Share this post


Link to post
Share on other sites

Forgot to mention:

If there are people in Europe who really think they want to have outdated PICs.
I have a bunch of them
(~20 PIC16F877 or 877a; 10+ 18F452;  all DIP40 and about 1kg of 16F688 in SO14)

Come and get them for free 😉

Share this post


Link to post
Share on other sites

We're still selling products using PIC16F877A, more than 18 years after I designed the first version. 🙂

(In the QFN-44 package though)

Share this post


Link to post
Share on other sites

We're still selling products using an OTP PIC17C752 circa 2000.  Neither MPLAB X nor current XC8 compilers support this part.  Luckily, I haven't had to maintain it in years.

Share this post


Link to post
Share on other sites

Interesting, I remember doing a bunch of products using 16C74, I think those are also still in use :).

Which makes me think, we could easily half the price of the microcontroller on those designs by changing to a newer model, but it is just not worth the cost and especially not worth the risk ...

When selecting a microcontroller, how important is price to you guys? For me I look for the best match to my requirements first and then if I have more than one solution price is for sure the tie breaker, but I have not once selected a worse match on features to reduce the price (maybe I have just been lucky?).

I have to add that the BOM cost of most of these designs were significantly higher than just the microcontroller, at least one of them included a GSM module at $30, which makes the $0.50 for the micro fairly insignificant ...

What do you guys think?

  • Like 1

Share this post


Link to post
Share on other sites

In the ivory tower of the university price is not that important.
If you build less than 10 devices even a difference of 5$/€ for each would not be worth to waste 1h of work 😉

For he student board I linked above which is sold a few hundred times it is a little bit more important to keep the price for all the components in the range of 10€ to make it attractive for them to get and build their own. (let them handle and solder the different sized components is one additional intention)

A 18F2xK22 is is for sure not the cheapest uC you can get, but in 2013 it was one of the most feature rich in the  8-Bit PIC range that is relative easy to understand with all of its peripherals for beginners in mikrocontroller programming.

Of course the presence of lots of tools like PICkit3 and knowledge of the MPLAB IDE and PIC18 at the side of the tutors in the labs was influencing the choice. 😉

I think the tools are very important especially if you do it not solely work with them or if you want to use them for teaching.
At the moment there is another subject where Python will be used as a fist programming language for our students.
A small part of this subject should be about embedded programming too. So we play around with circuitPython and microPhyton to see if it is easy enough to get an insight in just two or three lessons. Therefore we bought some tiny boards with SAMD21 and ESP32 controllers. Maybe some day we will build our own circuit/micropython board as we did with the PIC one but for the beginning it es more easy to use such controllers with huge libraries already available  for them.

  • Like 1

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
Reply to this topic...

×   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 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 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 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'
    • By Orunmila
      I think this is probably the most common question we get from beginners. Everybody gets confused with LATx and PORTx and run into Read-Modify-Write issues, so how does this really work?
       
    • By Orunmila
      I have a fairly general question for you all. I keep on running into situations where I need to mix C and ASM. Sometimes this works out easily by just using some asm("") instructions in the middle of my function, but sometimes I really feel like I could benefit from writing a function in ASM and calling it from C.

      I think my best example of this is the implementation of cryptographic functions such as AES or SHA. For these I see sometimes a 2x or even 3x speed improvement over what the compiler produces and I need to use these from more than one place so I really need a C function I can call to do these but I reallly need to implement it in ASM.
      Whenever I ask about mixing C and ASM I am told just not to do it, but it still seems to me that there are a lot of situations where this really is the best way to go?
      I recall a converstation with @holdmybeer where he needed very precise timing and the optimizer would always change the timing depending how the banks ended up being laid out (adding or removing bank switches), where implementing a function in ASM also seemed to be the solution.

      So I would like to get some opinions on this, do you guys agree? Any thoughts on this?

      PS. We recently had a related discussion about calculating parity as another example.
       
×
×
  • Create New...