An Arduino-based programmer for the AT89C2051 chip

The Atmel AT89C2051 is a low cost microcontroller in a 20-pin DIL package.  It runs MCS-51 (commonly termed ‘8051’) code.  It works from 2.7V to 6V at anything from 0 Hz up to 24 MHz.  It has 2K bytes of Flash memory to hold the program and 128 bytes of RAM.  It has 15 I/O lines, a UART, an analogue comparator and two 16-bit timer/counters.

I came across the chip as it’s often used in cheap 7-segment clock kits such as this one from BangGood (only £2.71 at the time of writing).

I wanted to reprogram the chip so I could use the kit as a stopwatch/timer instead of a regular clock.  Of course I could have bought a programmer to do the job, but reading the chip’s data sheet it seemed straightforward to do the programming with an Arduino – and I thought it would be a fun project to do that.

The chip is programmed a byte at a time by setting up each byte on 8 of the chip’s I/O lines and then pulsing some of the other I/O lines to ‘burn’ the byte to flash memory and move on to the next byte to be programmed.  You can also read the existing program out of a chip (unless a read-protect bit has been set) and there are special ways of pulsing the I/O lines to erase the whole chip and so on.

The only tricky thing is that one pin has to be raised from the nominal operating voltage of five volts up to twelve volts during programming – the challenge was working out the easiest way to do this using an Arduino.

So I decided to use an Arduino Mega 2560 for this project.  A Uno doesn’t have quite enough I/O to do the job properly, and the Mega 2560’s double row of I/O pins makes routing the connections to the chip simple as the chip can sit directly over the double-row connector.

I decided to use a charge pump (voltage multiplier) running off the Arduino’s five volts to generate the programming voltage – that seemed cleaner than needing a separate twelve volt supply.  It just uses a few diodes and capacitors and relies on the Arduino pulsing some of its I/O lines to drive the voltage multiplier.  A couple of zener diodes clip the voltage down to exactly 5V or 12V and a couple of transistors, also switched by the Arduino, select between either of those voltages or 0V to drive the pin on the chip.

I designed a PCB using the free KiCad package.  Here’s a .pdf of the circuit diagram, and here is what KiCad produces as a picture of the design.  In the picture it looks like the chip to be programmed is soldered straight into the board, but of course in reality a ZIF socket is fitted in that position so that the chip(s) you are programming can be quickly swapped.

programmer3DThat picture wrongly shows the tracks on the top of the board – I design them that way for home production as the transfer process mirror-images the tracks so that they’re correct for the back of the board.  If you fancy making one of your own, it would be quite straightforward to  do it on strip board – like I say most of the pins of the chip just connect direct to the Arduino pins that the chip sits over.  If you want to etch your own PCB, here is a .pdf of the mask.

Here are a couple of snaps of the prototype board.  You can see I didn’t bother to crop back the board edges!


topbackAnd this is what it looks like when docked on top of the Arduino Mega 2560.

topDockedbackDockedSo that’s about it for the hardware.  I’ll make a separate post about the Arduino sketch that does the work of programming the chip, and the PC program that talks to the Arduino to send and receive hex files.

9 thoughts on “An Arduino-based programmer for the AT89C2051 chip”

    1. I used the demo version of the Keil C compiler to write the 8051 code, I use the Arduino IDE to write the Arduino code, and the free version of Microsoft Visual Studio to write the PC program (using the C# language).

      1. Thanks for the reply. So I’m using an arduino mega and a couple of relays to switch the reset pin to 12 5 or 0 volts but it’s not working. Could it be the relays are to slow or something else.

        1. Yeah, I think relays with their slow operation and contact bounce won’t work with my existing code. You could try extending the delays after the VPP::setVoltage() statements – instead of delayMicroseconds() alter them to delay() That uses milliseconds instead of microseconds so a thousand times slower. Even a small fast relay probably needs at least 20 milliseconds or so to switch, so I wouldn’t go below delay(20) anywhere. It might still not work if the contact bounce means that the voltage at the reset pin switches rapidly back and forth between say 5 and 12 volts every time the relay closes – but you might want to give it a try – I don’t think it will do any harm to the chip. For a practical and reliable solution you really need something that can switch faster and cleaner than a relay – which is why I used the transistors.

    1. I have the code and the clock somewhere, but I’ve not used it for many months. I will try to blog about it and post the code I wrote, but I can’t promise when I will be free to do it.

    1. Yes, it looks like the programming sequence is the same. Obviously the board layout would need changing to suit the chip and the programs modified a bit to suit the extra memory capacity of the chip.

Leave a Reply

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