December 3, 2021

PIC16F87x support in ZEPPP

Almost 3 years ago I developed and published ZEPPP, my Arduino-based, “Zero-External-Parts” PIC Programmer, and wrote about it here on my blog.

From time to time I hear from people using it, and, sometimes I would also get questions about whether specific PIC devices are supported.

Now, ZEPPP is pretty limited in scope, as it was made to target the 16F628A primarily, but when I wrote it I also added support for other mid-range 8-bit PICs that employed similar programming procedures, and were popular back in the day. Just to echo the list, from day one ZEPPP had support for:

  • 16F87, 16F88
  • 16F627A, 16F628A, 16F648A
  • 16F873A, 16F874A, 16F876A, 16F877A

The Question

One of the PIC families that ZEPPP has supported from the start, is the 16F87XA line of microcontrollers. That means the 16F873A, 16F874A, and so on. They are not particularly modern devices, mind you, but in a couple of occasions, I’ve been asked whether ZEPPP could support the “non-A” variants, which predate the “A” versions although were almost functionally the same.

A Picture of a PIC 16F871
A PIC16F871 I bought from a fellow PIC enthusiast.

This is not something I get all the time, in fact, I had not heard that request in probably a couple of years, until recently a user on my blog echoed the same question, and he was apparently knowledgeable and interested enough in this, that he was already looking into adding the support himself.

It’s worth noting that the 16F628A also has a “non-A” version, and it’s not compatible with ZEPPP because it does not support LVP, which is what ZEPPP uses to program the chips. So it wouldn’t be crazy to assume that the 87X line of microcontrollers were the same, with the “non-A” parts not supporting LVP…

Except they do. The non-A plain “87X” parts, do, in fact, support LVP. So maybe it was just a matter of treating them like the “A” parts? Maybe?


I didn’t have any “non-A” part to try, but Ken (the user who posted the question), had a bunch of 16F876 devices, and he was more than willing to test, so we started tinkering with it. I branched the code from the repository and added settings for the 87X parts that mirrored the 87XA settings, and then asked Ken to test.

He reported very thoroughly the behavior of ZEPPP, and unfortunately the non-A parts would refuse to be programmed the way the “A” parts did, so I spent the next afternoon comparing the programming specifications of both 87XA and 87X parts trying to find the differences.

After looking at them side by side I noticed that most of the timing and the memory reading commands were the same, but the “non-A” parts did not support block writes, and had completely different erase algorithms. Fortunately there was support in ZEPPP already for non-block writes (because the 16F628A also lacks support for them), so I configured ZEPPP to use that style of programming with the 87X parts and asked Ken to try again. This led to a version of ZEPPP that was able to write and read to 87X parts, but was unable to erase them.

The Hunt for non-A Parts

This was good enough for most uses, but I wanted to have full support for all operations, and that meant having a way of testing the code myself, as new low-level routines were needed in the firmware, and that was not as straightforward.

To do this, I ordered a handful of old 16F877 from eBay, but that was not something that would arrive anytime soon.

In the meantime I found a small shop nearby, that according to their online listing had stock of 16F871 PICs, an old part of which no “A” variant exists. This store was run by a guy who’s been developing custom PIC projects for different clients for a long time, and of course had several very ancient PICs ready to sell.

In a matter of days I got a few 16F871 PICs to play with, and after another night of work I finally managed to implement the erase procedures for all memory areas, and was able to confirm that they worked with my 16F871 PICs. I also asked Ken to test on his 16F876 ICs, and he also reported success.

Polish and Fixes

I was quite happy now with ZEPPP successfully programming the 87X devices, but I also took this opportunity to improve the code a bit. There were a few places where changes were needed; From the internal structure of the code, to error messages and the behavior of some commands. There were also some assumptions inside ZEPPP that I wasn’t quite happy with.

All the changes are now in the ZEPPP Git Repository. The project now also includes a Changelog where you can check what was added/changed in more detail.

I would like to thanks Ken again for his very generous help testing the support for 87X parts, and for starting this whole endeavor that resulted in a handful of improvements to ZEPPP, and the support for a new (old?) family of devices.

Leave a Reply

Your email address will not be published. Required fields are marked *