Programming the at89lp family with an Arduino.



The at89lp is Atmel’s modern 8051 micro controller family. These mcu’s can fetch one instruction per clock cycle, where the classic 8051 needs 12 cycles. Execution takes 1 to 4 cycles, compared to 12 to 48 for the classic 8051. In the end this makes the new controller 6 to 12 times faster. Alternatively you can run the mcu in ’12 cycle per instruction fetch backwards compatibility’ mode. The choice is made by setting a fuse.

A controller more regularly asked about in the Arduino Microcontrollers forum is the older at89s52 mcu. Actually this is very bare bones micro controller: it has 32 gpio’s, 3 timers, an uart, support for isp and that is about it. It has 256 bytes ram and 8KB flash. Compared to this, the at89lp51ed2 has much more features: spi, i2c, a dac and pwm’s. Besides the 256 bytes internal ram, it has 2KB extended on chip ram and 64KB of flash.

This post is about a modified ArduinoISP version that can program the at89lp family (at least the two members I own: the at89lp4052 and the at89lp51ed2).

At89lp ISP is a bit different from avr ISP in that an extra signal is requiered: slave select (SS). The target is kept in reset as long as th etarget is in in programming mode but during each individual ISP transfer the SS signal has to be pulled down.

This is actually an old project that has been gathering dust in this old branch of my ArduinoISP git hub repo:
I recently picked it up again and back ported (or will do so) some ArduinoISP improvements (e.g. getting rid of the delay in hart beat).

Also I changed the wiring a bit, such that it is compatible with the ‘universal ArduinoISP shield’ described in earlier posts. This wiring should work on all Arduino’s. (Well, actually all avr based Arduino’s. I won’t backport the bitbang spi that allows to run on the arm boards).

Below are some pics:

First an Arduino Mega programming an at89lp51ed2 in a breadboard. Remark the ‘Universial ArduinoISP’ wiring: MISO, MOSI and SCK are obtained from the arduino’s ISP header.


Arduino mega programming an at89lp51ed2 in a breadboard.

Second, a more tidy setup: a Leonardo fitted with the ‘universal ArduinoISP shield’ programming an at89lp51ed2 sitting in a generic 8051 development board. (Ready to run the knight rider firmware). The extra yellow wire is the extra SS signal. (See also code in the ArduinoISP or at89lp_isp sketches.)


Arduino Leonardo fitted with the ‘universal ArduinoISP shield’ programming an at89lp51ed2 sitting in a generic 8051 development board.

This table lists the connections in a more clear way:

                  Arduino           at89lp
                  =======           ======
                     MOSI --------- MOSI' (P1.5) (1)
                     MISO --------- MISO' (P1.6)
                      SCK --------- SCK'  (P1.7)
                       10 --------- RESET
//--R--|<-LED_HB ------ 9 
//--R--|<-LED_ERR ----- 8 
//--R--|<-LED_PMODE --- 7 
                        6 --------- SS (p1.4) 
             IOREF(or 5V) --------- VDD ---||---// 
                      GND --------- GND 
                                    POL ------- VDD 
                                    P1.3 --LED->|--R--// (2) 

(1) MOSI', MISO' and SCK' are the 'remapped' SPI signals, they are on different pins than the run time SPI
(2) See examples for a remark on connecting the anode of the led to the mcu

The at89lp_isp sketch

I used this sketch to learn about the at89lp isp protocol. I find it still useful:

  • As a quick test: it can flash a led blink (on pin P1.3) into the target, read out signature…
  • To set the fuses of the at89lp51xx.

When you compile the sketch you can configure building for use with the at89lp4052 or the at89lp51xx chips.
For the latter, you need the #define AT89LP51. (for the at89lp4052 just put the define in comment).

Compile and upload the sketch to the Arduino and connect to the serial line at 115200 baud. Here is a sample session:
(Tested and compiled with ide 1.6.9.)

Send ‘x’: the sketch will report the target device signature, fuses and lock bits.
Send ‘a’: (at89lp51xx only): this programs suitable fuses.
Send ‘x’ again to read the new fuses.
Send ‘r’: the first 100 bytes from flash memory will be read. This will be all FF’s if it is a new chip.
Send ‘e’: erase chip. if you want to program the flash, this step is needed because you can only turn an ‘1’ into a ‘0’, not the other way round, so you must first set every bit to ‘1’.
Send ‘r’ again: now you definitely should see all FF’s
Press ‘w’: the blink program is now programmed
Press ‘r’ to see if the program is really there.
Press ‘p’ to leave programming mode (‘p’ toggles programming mode).
=> the led should now start blinking.

The ArduinoISP sketch

Compiles with ide 1.6.9.
Supports reading, erasing and writing flash. Reads out signature. For now use the at89lp_isp sketch to set the fuses.
You will need an avrdude.conf file that contains specifications for the at89lp. Get it from the repo: data/avrdude-at89lp.conf

An example command line (linux) that flashes the knight-rider.ihx file to the at89lp51xxx:

avrdude -C avrdude-at89lp.conf -P /dev/ttyACM0 -b 19200 -c stk500v1 -p lp51 -U flash:w:knight-rider.ihx

Tested with avrdude 6.3, but any reasonably recent version should do (say from 6.0.1).

A remark: as always with ArduinoISP you need to make sure auto reset is disabled. For the Leonardo there is noting to do but e.g. the Mega would need a cap between reset and ground to achieve this. In the picture above there is no such cap as I disable auto reset using a modified firmware in the mega’s 16u2 (that is what the blue jumper near the 16u2 is for).

Some 8051 examples…

See examples folder in the repo. They compile with sdcc. Just type ‘make’ to build all samples.

You can configure e.g. the frequency of the crystal you use in hw.h.
This is also the place to configure your target by including the appropriate header: at89lp4052.h or at89lp51x.h
(These headers contain the sfr’s specific for the processor at hand. sfr’s that are standard 8051 are in 8051.h provided by sdcc.)

Here is a quick tour.

Blink. – configurable io

Normally there is not much to say about a blink example. In this case there is. A classic 8051 has “quasi bidirectional io’s” that can be used as input or output without software configuration. The downside is that if you use them as input they are not terribly high impedance and if you use them as output they can’t source a lot of current. To the extent that if you connect a led with its anode side to the io pin and the cathode towards ground (like in the wiring diagram shown above), the io pin can’t source enough current to drive the led. Therefore to blink a led you have to connect the anode to vcc and the cathode towards the io pin, so the microcontroller sinks rather than sources the current.

The at89lp’s ports can be configured as bidirectional, high impedance input, push pull output or, open drain output.

By configuring them as push pull output you can drive a led from the anode side. This is what I did for the blue led in the pictures, using following non generic 8051 code snippet:

    /* at89lp specific: configure P1.3 as push pull output */
    P1M0 &= ~(1<<3);
    P1M1 |= (1<<3);

BTW the memory locations for P1M0 and P1M1 are different for the at89lp4052 and the at89lp51x. These addresses are defined in
at89lpx052.h and at89lp51x.h.

For more information on io port configuration, see data sheet.

Knight rider

Always nice. My favorite.
Does not configure the io port as output so led should point towards mcu.



Arduino melody sample playing on the at89lp51

This is actually the Arduino melody sample. It uses tone.c which implements the Arduino tone api.
It illustrates how to register interrupt service routines and the use of the timers.
It outputs a signal on P1.3 that is audible if you wire up some amplifier and speaker to that pin.

10 thoughts on “Programming the at89lp family with an Arduino.

    1. petervho Post author

      Thanks for letting me know!

      Just out of curiosity: are you actually building something or just studying/playing with this mcu?
      Why did you opt for this unusual mcu?

      1. Raw

        I have a bigger project or this type of MPU.
        i have a question, what is the crystal value you used with AT89LP4052? I have AT89LP2052 and i tried to program it but i failed(I read the instruction from atmel about some differences for ISP programming for AT89LP4052/AT89LP2052) So could you tell me about your experience with AT89LP4052 ?

      2. petervho Post author

        I used different crystals between 8MHz and 20MHz, all work, these devices are not picky about frequencies.

        This ArduinoISP sketch handles both ISP programming schemes (lpx052 and lp51x). But you need to tell it which mcu you have.
        For the lp4052 specify -p lp40 on the command line (instead of -lp51). For an lp2052, you’ll need to create an extra entry in the avrdude-at89lp.conf file.
        Copy paste it from the one for lp4052 and change the expected signature, memory size, stk500_devcode… ArduinoISP chooses programming modes
        based on the stk500_devcode: if it is 0xF1 it picks the lp51x scheme, so if you leave stk500_devcode to 0xF0, it should work.

        In the at89lp_isp sketch, th eprogramming mode is hard coded: it depends on having or lacking the

        #define AT89LP51
  1. Raw

    so first with at89lp_isp sketch, because i want to check the lp2052 working or not , is the quick code working with lp2052 or there is many changes in the code ?
    i will try to add lp2052 to avrdude conf file

  2. petervho Post author

    I expect yes. The isp interface of the at89lp3240 looks the same as the at89lp51x. So if you would copy paste the entry for part lp51 in avrdude-at89lp.conf and adapt it for the lp3240 (different signature, different nr of pages,…), it might just work. ArduinoISP is instructed to use the at89lp51 isp scheme (which is different from the at89lp40 scheme) by passing it device code 0xF1, so using 0xF1 as stk500_devcode in avrdude-at89lp.conf should work. At first sight you would not have to modify the fuses as the at89lp3240 does not have this bootloader jump bit. If you can make it work, would be interested to hear about it

  3. PeterT.

    Is there still a compiler/studio available? I have some AT89LP3240’s lying around, and want to get them a useful purpose… I was searching for the LP development studio on their site but apparently not longer available… 😦

    1. petervho Post author

      It is worth contacting microchip tech support. They probably still have it available somewhere. I contacted them once (when they were still atmel) and they were very helpful, providing an app note not available on their web site…
      O.t.o.h, you might consider using sdcc, it works quite well and is still actively developed.

      Edit: at89lpstudio uses an older unmodified sdcc version under the hood. Atmel just added header files for each at89lp device.
      So I think at89lpstudio would not bring you much over sdcc. Just try to grab the at89lp3240.h.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s