Quick and dirty PIC16F72 programmer with the Pico
Accompanying Github repo: https://github.com/SyedTahmidMahbub/q-dpico_picprog72
Having come to Dhaka over winter break, I was able to scrounge through the 10+ year-old collection of electronics stuff my parents had in storage from when I would experiment with electronics during the initial days of this blog. Among the many parts, I stumbled upon a large number of PIC16F72 MCU's - the defacto 8-bit cheap MCU of choice for many (commercial) projects. However, I couldn't seem to find the corresponding PICKIT2/3 programmer from back then - or one of the clones I had made - within the storage cabinets. At the same time, I had been working on some projects with the Pi Pico (as mentioned in the blog previously: https://tahmidmc.blogspot.com/2023/08/2023-updates-phd-pi-pico.html). This seemed like the perfect use case for the Pico - a very quick and dirty programmer to flash the PIC16F72. With its 2MB onboard flash, a very easy-to-program Micropython interface and the PIC16F72's fairly timing insensitive ICSP protocol (http://ww1.microchip.com/downloads/en/devicedoc/39588a.pdf), I set out to build a programmer to flash some test code onto the PIC16F72. I made use of whatever parts I could scrounge from the parts bin to put the project together.
As expected, Micropython on the Pi Pico enabled a super-quick development time. To echo what I had previously quoted from the Raspberry Pi foundation:
Computing is just so cheap compared to what it has been historically. That then enables things that are maybe not super efficient, not super tight timing like Micropython but who cares at that point? A lot of people will come in and say things like 'in this benchmark, I found that MicroPython is 100x slower than C' but if your C code is 100x faster than you need, then it doesn't matter. You just write the code you need and you focus on the parts that add value to your project and then you move on to your next project.
And this is the perfect use case! It's not the highest performance result but it gets the job done and the project development was super quick!
The details for the PIC16F72 programming are covered in Microchip's documentation: http://ww1.microchip.com/downloads/en/devicedoc/39588a.pdf
A description of Microchip's HEX file format is provided here: https://microchipdeveloper.com/xwiki/bin/view/software-tools/ipe/sqtp-file-format-specification/intel-hex/
The hardware elements of the project have a few key aspects:
- A higher voltage power supply is required for programming. This is between 12.75V and 13.25V VPP. To achieve this, a boost converter is used to raise the 5V USB rail to about 13V. I didn't have any inductors on hand except one unmarked part I found, that measured around 1.8mH. The boost converter operates in discontinuous conduction mode with the minimal VPP required current. Because of the 3.3V IO level of the Pico, I used an NPN transistor instead of a logic level MOSFET I had on hand due to the MOSFET's relatively high threshold voltage.
- A VPP level shifter is required to drive the VPP pin up to 13V or hold it low. A PC817 optocoupler is used for this.
- Level shifters are not needed for the PGD and PGC programming lines since the 3.3V from the Pico is high enough (>2V) for the PIC to register, even though the PIC is powered off 5V.
- Configure the IOs for their corresponding functions.
- Configure PWM for the boost converter, running at 50kHz.
- Adjust the duty cycle until the output is near 13.2V.
- The output voltage is sensed by an ADC channel.
- Hold this duty cycle for the output voltage - at this point, the feedback loop is stopped.
- Detect the target PIC.
- If detected, issue a bulk erase and then check that the part is blank.
- Upon success, flash the words read from the HEX file.
- CODE_START_ADDR
- CODE_END_ADDR
- CONFIG_START_ADDR
- CONFIG_END_ADDR
- DEVID_PIC16F72
That's really so cool vaiya. Can we do it like PicKit2 or add support for commonly used PIC MCU in this python script?
ReplyDeleteThanks! It should be pretty easy to tweak the micropython code to add support for more PICs. For some of the smaller PIC16's, you'll probably only need to update the device ID and the ranges for the code and config memory spaces. For newer ones, especially the larger memory devices, the code will have to be tweaked to support extended memory addressing. And even newer parts might have a different programming spec. You can compare this to the programming guide of the PIC16F72 and see what the differences are.
DeleteWhat other common PIC MCUs are typically of interest?
I think these PIC MCU's are commonly used:
Delete12F675, 12F683, 16F676,
16F84/A, 16F628/A, 16F72, 16F73
It should not be too difficult to adapt the circuit and code for these specific parts. You can find the corresponding programming guides online. For example, here is the one for 12f675: https://ww1.microchip.com/downloads/en/DeviceDoc/41173c.pdf
DeleteAt quick glance, it seems that for the 12f675, you need to sequence VDD after VPP. So, you would add a transistor on the VDD line to do that with another GPIO, which you would do in the enter_prog function.
https://github.com/SyedTahmidMahbub/q-dpico_picprog72/blob/5a918e72d2a5b05f3c61767de552f66991e75294/prog72.py#L62C11-L62C11
Thank you for this! I want to program PIC16F886. This supports Low Voltage Mode, which is required if you want to program the chip with an Ardino as ISP. Can I use your method in order to program this microcontroller? Thank you very much. BTW, its datasheet is here: http://ww1.microchip.com/downloads/en/devicedoc/41291d.pdf
ReplyDeleteThe details for the programming spec are in this document: https://ww1.microchip.com/downloads/en/DeviceDoc/41287D.pdf
DeleteYou will need to update the corresponding sections in the code such as the code end region. You may also need to be able to control the VDD supply if using certain config options (VPP-first program/verify mode entry), see Section 3.0 and Fig 3-1 in the document.
So, you would add a transistor on the VDD line to do that with another GPIO, which you would do in the enter_prog function.
https://github.com/SyedTahmidMahbub/q-dpico_picprog72/blob/5a918e72d2a5b05f3c61767de552f66991e75294/prog72.py#L62C11-L62C11
can i use any other transistors like bc547 or 2n3904?
ReplyDeleteAs long as you are using a large enough inductance, yes.
Deleteits not working . that vpp voltage not gets generated. i will work with al same componenets as ur schematic. except that FB circuit 1.2k im using 1k. but thats not a problem. still the circuit cannot be able to generate 12v or 13v
ReplyDeletehelp me with it plz.
Do you see a PWM signal get generated? What inductance are you using? What voltage do you observe?
DeleteJust thinking about the opto-isolator. I can't see any down side of using a MOSFET or for that matter a BJT. Am I missing something important?
ReplyDeleteYou can use a MOSFET or BJT for level shifting - that should be ok. I just used the opto-isolator since I had that on hand.
DeleteNow im getting output about 13.25v. but still its not detecting the pic ic. Can u send me a circuit of connections on the pic side.
ReplyDeleteAnd also i edited the code to work with pic16f877a but it also not showing in programmer.
Im that anonymous chat earlier. Accidentally send as anonymous. But plz help.
ReplyDeleteI connected the pic16f72 with vcc and gnd and connected pgc and pgd accordingly and vpp also correctly generated and outputed in pic's vpp pin.but the code does not detects pic16f72. I have tried with 4 pic ics.
ReplyDeleteDoes it just fail in step 2 when trying to discover the PIC16F72? Do you have a scope to probe the VPP line? Can you see it go high and low if you toggle GP12? If you don't have a scope handy, you could try PWM'ing that pin and seeing if you get the right expected average voltage at VPP as you change the duty cycle.
DeleteHello, how are you? I made a fork of your project that removes the code that works with the boost converter circuit and added support for the PIC16F84A. I'm still trying to make another version for PIC16F877A but I can't get it to work.
ReplyDeleteThe device ID that the PIC16F877A gives me does not match what it should be and even if I bypass the check it only manages to program some of the information, but not all of it.
https://github.com/Kyuchumimo/q-dpico_picprogxxxx
Your device ID doesn't seem right. Note that the 16F877 and 16F877A have different device IDs. It sounds like you are trying to use the latter, in which case you should refer to this document: http://ww1.microchip.com/downloads/en/devicedoc/39589c.pdf
DeletePlease try again with that and confirm whether you do see the correct device ID as per that document.