Writing to a AT89S52 through a USBasp

Last post
41 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi guys, this is probably not the correct forum and Im sorry if this is well trodden territory. I have read our friend Jecksons attempts to try to make an USBasp program a At89S52 via AVRdude. As a matter of fact, im trying to do the exact same thing.

Im actually able to read and partially write to the AT82S52 through the USBasp and Avrdude 5.10 with a modified conf.

Here is how i did it.

0. WinXP system
1. Bought/soldered a usbasp
2. Knowing that the usbasp functions fully (tested to program atmega8s all day with it) i interconnected the MISO, MOSI, SCK, GND, RST, VCC and GND of the Atmega8 on the USBasp and the target µC AT89S52.
3. Hooked up a 4,096mhz Xtal and 33pf capacitor to the target µC.
4. Connected the entire setup to the usb
5. Edited the conf file of avrdude with the work of Joy Shukla:

#------------------------------------------------------------
# Below chips by added by me .. Joy Shukla(joy_shukla@yahoo.in)
# these chips can be programmed with my usbasp programmer(changed atmega8 program)
# after adding avrdude support in this file ..
#------------------------------------------------------------

#------------------------------------------------------------
# AT89S52
#------------------------------------------------------------
part
    id               = "8052";
    desc             = "AT89S52";
    signature        = 0x1E 0x52 0x06;
    chip_erase_delay = 20000;
    pgm_enable       = "1 0 1 0  1 1 0 0    0 1 0 1  0 0 1 1",
                       "x x x x  x x x x    x x x x  x x x x";

    chip_erase       = "1 0 1 0  1 1 0 0    1 0 0 x  x x x x",
                       "x x x x  x x x x    x x x x  x x x x";

    timeout      = 200;
    stabdelay      = 100;
    cmdexedelay      = 25;
    synchloops      = 32;
    bytedelay      = 0;
    pollindex      = 3;
    pollvalue      = 0x53;
    predelay      = 1;
    postdelay      = 1;
    pollmethod      = 0;

    memory "flash"
        size            = 8192;
        paged           = no;
        min_write_delay = 4000;
        max_write_delay = 9000;
        readback_p1     = 0xff;
        readback_p2     = 0xff;
        read            = "  0   0   1   0    0   0   0   0",
                          "  x   x   x a12  a11 a10  a9  a8",
                          " a7  a6  a5  a4   a3  a2  a1  a0",
                          "  o   o   o   o    o   o   o   o";

        write           = "  0   1   0   0    0   0   0   0",
                          "  x   x   x a12  a11 a10  a9  a8",
                          " a7  a6  a5  a4   a3  a2  a1  a0",
                          "  i   i   i   i    i   i   i   i";
   mode      = 0x21;
   delay      = 12;
      ;

    memory "signature"
        size            = 3;
        read            = "0  0  1  0   1  0  0  0   x  x  x  0   0  0 a1 a0",
                          "0  0  0  0   0  0  0  0   o  o  o  o   o  o  o  o";
      ;
  ; 

5. Copied my target hex "Loghman.hex" of 380 (threehundred and eighty bytes) of led-blinking-code to avrdude's location

6. Fired up avrdude with the following command:
avrdude -p 8052 -c usbasp -e -U flash:"blabla\loghman.hex" -vvvv

7. Got the following screen:

Conclusion:
A) AVRdude can write to the AT89S52 but only 110 bytes, and NOT the full 380 bytes. Avrdude can read the supposedly written 110 bytes and it looks like this (gibberish?):

oߟ¯¯¯¯¯¯¯¯¯Ï__ï/ÿï?ÿï?ÿï?ÿÏŸߟ/ŸÏïÿÿÿÿÏïŸÿÿïŸOÿïŸOÿïŸOÿ/ïÿßÿÿ

Discussion:
A) I know through previous searches that AVR and the AT89 chips are programmed in a different way but hoped that the .conf file modification might do the trick. Obviously it didnt or i have due to ignorance missed something. Would any of the more versed AVR experts care to comment on what i might have done wrong?

B) Also, im getting a warning message that avrdude cannot set sck period. Tried to hook pin 25 to GND to set the SCK to slow mode but get the exact same warning. Any suggestions would be appriciated.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just to note that the source of avrdude (and usbasp for that matter) is open so if there's really a demand to add 8051 programming to it then it's quite possible for someone to do this then contribute the work back to the project (under the "beerware" or "Free BSD" licence)

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

try this config, it works.
add this to the config file near the other defines

#define AT89START   0xE0
#define AT89S51	  0xE0
#define AT89S52	  0xE1

add this at the end of the config file

 #------------------------------------------------------------
  # AT89S51
  #------------------------------------------------------------
  part
      id               = "8052";
      desc             = "AT89S51";
      signature        = 0x1E 0x51 0x06;
      chip_erase_delay = 500000;
      pgm_enable       = "1 0 1 0  1 1 0 0    0 1 0 1  0 0 1 1",
                         "x x x x  x x x x    x x x x  x x x x";
  
      chip_erase       = "1 0 1 0  1 1 0 0    1 0 0 x  x x x x",
                         "x x x x  x x x x    x x x x  x x x x";
  
      timeout      = 200;
      stabdelay      = 100;
      cmdexedelay      = 25;
      synchloops      = 32;
      bytedelay      = 0;
      pollindex      = 3;
      pollvalue      = 0x53;
      predelay      = 1;
      postdelay      = 1;
      pollmethod      = 0;
  
      memory "flash"
          size            = 4096;
          paged           = no;
          min_write_delay = 4000;
          max_write_delay = 9000;
          readback_p1     = 0xff;
          readback_p2     = 0xff;
          read            = "  0   0   1   0    0   0   0   0",
                            "  x   x   x a12  a11 a10  a9  a8",
                            " a7  a6  a5  a4   a3  a2  a1  a0",
                            "  o   o   o   o    o   o   o   o";
  
          write           = "  0   1   0   0    0   0   0   0",
                            "  x   x   x a12  a11 a10  a9  a8",
                            " a7  a6  a5  a4   a3  a2  a1  a0",
                            "  i   i   i   i    i   i   i   i";
     mode      = 0x21;
     delay      = 12;
        ;
  
      memory "signature"
          size            = 3;
          read            = "0  0  1  0   1  0  0  0   x  x  x  0   0  0 a1 a0",
                            "0  0  0  0   0  0  0  0   o  o  o  o   o  o  o  o";
        ;
    ; 
#------------------------------------------------------------
# AT89S52
#------------------------------------------------------------
part
    id               = "8052";
    desc             = "AT89S52";
    signature        = 0x1E 0x52 0x06;
    chip_erase_delay = 500000;
    pgm_enable       = "1 0 1 0  1 1 0 0    0 1 0 1  0 0 1 1",
                       "x x x x  x x x x    x x x x  x x x x";

    chip_erase       = "1 0 1 0  1 1 0 0    1 0 0 x  x x x x",
                       "x x x x  x x x x    x x x x  x x x x";

    timeout      = 200;
    stabdelay      = 100;
    cmdexedelay      = 25;
    synchloops      = 32;
    bytedelay      = 0;
    pollindex      = 3;
    pollvalue      = 0x53;
    predelay      = 1;
    postdelay      = 1;
    pollmethod      = 0;

    memory "flash"
        size            = 8192;
        paged           = no;
        min_write_delay = 4000;
        max_write_delay = 9000;
        readback_p1     = 0xff;
        readback_p2     = 0xff;
        read            = "  0   0   1   0    0   0   0   0",
                          "  x   x   x a12  a11 a10  a9  a8",
                          " a7  a6  a5  a4   a3  a2  a1  a0",
                          "  o   o   o   o    o   o   o   o";

        write           = "  0   1   0   0    0   0   0   0",
                          "  x   x   x a12  a11 a10  a9  a8",
                          " a7  a6  a5  a4   a3  a2  a1  a0",
                          "  i   i   i   i    i   i   i   i";
   mode      = 0x21;
   delay      = 12;
      ;

    memory "signature"
        size            = 3;
        read            = "0  0  1  0   1  0  0  0   x  x  x  0   0  0 a1 a0",
                          "0  0  0  0   0  0  0  0   o  o  o  o   o  o  o  o";
      ;
  ; 
#------------------------------------------------------------ 
# AT89S8253 
#------------------------------------------------------------ 
part 
    id               = "8253"; 
    desc             = "AT89S8253"; 
    chip_erase_delay = 20000; 
    pgm_enable       = "1 0 1 0  1 1 0 0    0 1 0 1  0 0 1 1", 
                       "x x x x  x x x x    x x x x  x x x x"; 

    chip_erase       = "1 0 1 0  1 1 0 0    1 0 0 x  x x x x", 
                       "x x x x  x x x x    x x x x  x x x x"; 

    timeout      = 200; 
    stabdelay      = 100; 
    cmdexedelay      = 25; 
    synchloops      = 32; 
    bytedelay      = 0; 
    pollindex      = 3; 
    pollvalue      = 0x53; 
    predelay      = 1; 
    postdelay      = 1; 
    pollmethod      = 0; 

    memory "flash" 
        size            = 12288; 
        paged           = no; 
        min_write_delay = 4000; 
        max_write_delay = 9000; 
        readback_p1     = 0xff; 
        readback_p2     = 0xff; 
        read            = "  0   0   1   0    0   0   0   0", 
                          "  x   x a13 a12  a11 a10  a9  a8", 
                          " a7  a6  a5  a4   a3  a2  a1  a0", 
                          "  o   o   o   o    o   o   o   o"; 

        write           = "  0   1   0   0    0   0   0   0", 
                          "  x   x a13 a12  a11 a10  a9  a8", 
                          " a7  a6  a5  a4   a3  a2  a1  a0", 
                          "  i   i   i   i    i   i   i   i"; 
   mode      = 0x21; 
   delay      = 12; 
      ; 

    memory "signature" 
        size            = 2; 
        readback_p1     = 0x1E; 
        readback_p2     = 0x73; 
        read            = "0  0  1  0   1  0  0  0   x  x  x  x   x  x  x  x", 
                          "x  x  1  1   0  0  0 a0   o  o  o  o   o  o  o  o"; 
      ; 
  ; 

this is the bat file I use:

avrdude -c usbasp -p AT89S52 -C avrdude.conf -B 250 -e -U flash:w:file.hex

ensure you have the right code in the usbasp. If you are having trouble with avrdude, try progisp172 here:
http://www.zhifengsoft.com/download/progisp172.rar

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for your replies guys. Followed the instructions but still get the 348/110 problem, meaning my hexfile is detected by avrdude as Intel hex and of size 110 bytes although the size obviously is 348bytes large.

Does anyone know what might be the problem?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I get a different behaviour.

1. You get a 'warning' about not setting SCK frequency.
I can set SCK frequency or just leave as default.

2. You can erase successfully.
I get a 'target does not answer' after the erase.

3. You say that your file is 384 bytes. I am sure that avrdude can correctly count 110 bytes.
I can successfully program and verify providing that I use the -D flag. i.e. I need to erase in one session and program in a different session.

My other anomaly is with the SCK setting.

Usbasp starting from cold will happily communicate at SCK=750kHz.
However any subsequent 'run' needs to use SCK=32kHz.

Usbasp seems happy programming AVRs without issue.

Incidentally, I get the -e and -D behaviour with the STK500 too.

n.b. AT89 parts have an active-high RESET pin. If you do not use an inverter, you need to add a 'nRST' line to usbasp. i.e. it does the inverse of the regular /SS line.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Isn't the size confusion the classical "intelhex file size does not match binary size" problem?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

angrysurgeon wrote:
Thanks for your replies guys. Followed the instructions but still get the 348/110 problem, meaning my hexfile is detected by avrdude as Intel hex and of size 110 bytes although the size obviously is 348bytes large.

Does anyone know what might be the problem?

you do realize that the size of the hex, is not the size of the program writen to the part. The hex will be more than 2x the size of what is written due to the encoding scheme used in hex files.

Back-calculating from your 110 bytes, which requires 220 hex bytes. Encoding that at 16 hex bytes per line, plus 11 bytes of overhead per line, add a segment definition line [15], and the EOF marker [11], plus a CRLF [2] per line, I get 341 bytes for the hex file.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

you do realize that the size of the hex, is not the size of the program writen to the part. The hex will be more than 2x the size of what is written due to the encoding scheme used in hex files.

so in other words, im actually able to program the AT89S52, its just that my ledblinking code is not working?

So here is "my" code (actually the code i use from a AT89S52 tutorial):

#include 
#include 

unsigned long time, ON_time; //Global Variables

void main(){
    P1_3 = 1;     //Set up P1_3 as input pin
    ON_time = 100000;
    while(1){
         if (time < ON_time){
            time++;    // start or continue counting
            P1_0 = 0;     //Turn ON the LED
         }else{
            P1_0 = 1;    // Turn OFF the LED
        }
        if (P1_3 == 0){     // if the switch is pressed,
            time = 0;    // reset 'time' to 0
        }
    }
} 

Using Keil µvision 4.02, I get this compilation:

http://www.mediafire.com/?uba0td7qfxpb3br

To startup the At89S52 i use 2x 22pf a 11.0952Mhz crystal, connected (pin20), connected VCC 5.0V (pin 40) and to pin 1, i connect a red LED of 1.9V attached to the 5v via a 500ohm-1K resistor attached to 5V.

Unfortunately it does not work. With an oscilloscope, Ive tried to check if the oscillator swings correctly but all i get is gibberish, not the expected nice sine curve with the correct frequency that i get with Atmega8 (or any other microcontroller for that matter) when the power is turned on.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

David, i soldered the SCK to gnd on the usbasp that I use, but I was getting the exact same warningmessage before i did that "maneuver" so I just left it on since the AT89S52 manual mentions that the programming frequency must be 1/16th of that of the attached crystal.

And what do you mean with the following: " you need to add a nRST' line to usbasp", how would i go about doing that? That the RST of the AT89S52 must be 5V during programming?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did you try progisp172? This way you will know your hardware is working.

If you get the SCK warning in avrdude, you don't have the latest code in the usbasp.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

angrysurgeon wrote:
David, i soldered the SCK to gnd on the usbasp that I use, but I was getting the exact same warningmessage before i did that "maneuver" so I just left it on since the AT89S52 manual mentions that the programming frequency must be 1/16th of that of the attached crystal.

I presume that you are referring to the 'SCK_slow' i/p pin on the usbasp board. This is nothing to do with the SCK o/p pin on the ISP header.

Quote:
And what do you mean with the following: " you need to add a nRST' line to usbasp", how would i go about doing that? That the RST of the AT89S52 must be 5V during programming?

An AVR cpu and most civilised cpu's in all history have an active-low /RESET pin.
The MCS51 family have an active-high RESET pin. wek has written an excellent explanation of this 'feature'.

So any ISP programmer must be capable of sending the
correct polarity of signal to the /RESET or RESET pin.
I simply duplicated the usbasp code that affects the /RESET o/p. i.e. I selected another GPIO pin for nRST, and always set it to the inverse of the RST o/p pin.

I have also added a flag to allow SPI mode#1 for the AT89S8253. All AVRs and other AT89 parts use regular mode#0 SPI !
The ispEnterProgrammingMode() function now accepts byte#4 == 0x69 (what the AT89S52 replies) as well as the byte#3 == 0x53 (what AVRs and 8253 replies)

I discovered the reason for my strange clock speed behaviour. The usbasp was simply driving a naked chip on a breadboard. I had a pull-down resistor for the AT89's RESET. But I did not have a pull-up resistor for the SS pin of the usbasp. The AVR SPI peripheral must never have the SS pin as a floating i/p.

Incidentally, your 'at89.c' program works just fine. But of course it needs human intervention. A simple Blinky.c is easier to check.

n.b. the AT89S52 is a 5V part. You can read it at 3.3V. But erase or program needs to have a full 5V.
AVR parts are very tolerant of low voltage operation.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hmm, would it be possible to ask for a favor and requesting a working blinkey hex code working for a at89S52? It would be fantastic if someone could upload that for me. That way, i could operate with the absolute certainty that the software is of no fault and that my hardwareconfiguration is defective...As a matter of fact, i would be able to send anyone who does that 3 AT89S52s to any address in the world if that person posts the stuff here for all of humanity and pms me his address :D

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
:03000000020003F8
:03005C0002005F40
:05005F0012009E80FE6E
:0C006400D582FD1583E583B4FFF622224F
:04007000AA82AB8332
:090074008A048B051ABAFF011B76
:06007D00EC4D601C7C0A42
:0E0083008C051CED60EB90004CC002C003C069
:0C00910004120064D004D003D00280E60A
:01009D002240
:02009E007A00E6
:0E00A000C3EA6480948A50106390019000645B
:0A00AE00C002120070D0020A80E8C0
:0500B80063900280E1ED
:06003200E478FFF6D8FDA2
:080010007900E94400601B7A4D
:05001800009000C1781A
:03001D000075A0CB
:0A00200000E493F2A308B800020503
:08002A00A0D9F4DAF275A0FF81
:080038007800E84400600A7939
:030040000075A0A8
:0600430000E4F309D8FC03
:080049007800E84400600C7926
:0B00510000900000E4F0A3D8FCD9FAF6
:03000300758107FD
:0A0006001200BDE582600302005FF6
:0400BD007582002226
:00000001FF

This was compiled for an 18.432MHz crystal and should run on ANY mcs51 part. So you will be 3Hz for a 12MHz crystal. Put a stopwatch on the P1_1 o/p pin. Count 20 blinks and calculate your crystal frequency (should be 40.00 seconds for 18.432MHz).

#include "mcu.h"
#include "sleep.c"

void main(void)
{
	char i;
        while (1) {
		for (i = 0; i < 10; i++) {
			P1 ^= (1<<0);		// P1_0 blinks at 5Hz
			msleep(100);
		}
		P1 ^= (1<<1);			// P1_1 blinks at 0.5Hz
	}
}

Incidentally, avrdude + usbasp are incredibly slow with 8051 devices. This is because they only read one byte for every USB packet. So reading 8k flash takes 33 seconds!

With a simple modification to the usbasp firmware, this can be speeded up to something more reasonable.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It works...

IT WORKS! David and all the others, thank you! :D Feierabend! as the germans say! :D

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is the deal, here is how i got it to work for dummies like me:
0. connected the at89s52 to the usbasp as per above and modified the conf file.
1. copy pasted davids code into a new textfile and saved it (as pgm.hex)
1a. pgm.hex must be in the same folder as avrdude.exe
2. used this command to program the chip:
avrdude -p 8052 -c usbasp -e -U flash:w:Pgm.hex

(762bytes actual file size of pgm.hex
written after avrdude is done 194bytes)

3. hookup the now programmed at89s52 according to this schematic:

4. Enjoy.

Again, thank you all. Special thanks to David!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@angrysurgeon,

If you are seriously using the AT89Sxx or AT89S82xx parts, I have modified the usbasp firmware.

The reading and writing works at a sensible speed. And you can access all the memory areas, just by configuring the avrdude.conf

In fact, I am very impressed with the performance of usbasp. You can use all the AVR's ISP features, so AVRs program efficiently.

I do not use the page modes that are available on some of the AT89S parts. Even so, byte mode writing is reasonable. Byte mode reading is almost as fast as any page mode reading.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow! yes, i will be using at89s52 pretty extensively until the atmega prices of current models will come down (1-2 years from now?). Would you care to elaborate on what modifications you did with the usbasp in more detail? Are they hard to implement?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am a little confused as to how you got that command to work. Especially, how did you have the AT89S52 wired to the usbasp board.

Please can you post here / email me exactly what your hardware setup is. Do you have a commercial dev board?

8051's require pull-up resistors on the PORTS and fancy RESET circuits to operate. You cannot just put a naked 8051 on a breadboard.

Which usbasp kit did you build?
Did it come with a pre-programmed AVR?
Can you program that AVR with any other programmer?
Or do you need a pre-programmed chip?

By all means use your drawer full of AT89S52's. You will need the Keil evaluation compiler or the free sdcc compiler. The Keil tools are excellent for small beginner programs. (they are excellent for large programs too. just a LOT of money)

Some things work very differently at the hardware level on the 8051 compared to an AVR.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The usbasp:

No commercial dev board, all DIY (or almost). I didnt build the usbasp from a kit, i used the schematics from fischl.de and took it from there.

Result:

[{The above picture is large, right click on it and choose view picture and zoom in by left clicking on it (FIREFOX)}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I used the hexcode (2009 february) provided by fischl and programmed an atmega8 via a bought usbasp on a breadboard.

On the AT89S52 side of things:

1. put µC on a breadboard
2. connect pin 40 (VCC) of AT89S52 to usbasps 10pin input/output port pin 2

3. connect pin 20 (GND) of AT89S52 to usbasps "port-pin 10"

4. connect mosi of at89s52 to mosi of the atmega8 on the usbasp, miso to miso, sck to sck and RST to RST VIA the 10pin connector

5. attach 2x 20-30pf capacitors and an appropriate crystal to the AT89S52 (i used 4.33619mhz, tested also with 19mhz, 16mhz, all work fine for me, but using no crystal will NOT work {for me}). I also checked that the crystal swings fine with an oscilloscope.

6. Program by using a modified avrdude.conf using the provided command as per above.

I havnt tried with any other programmer, just the homemade usbasp. Havnt tried to program other chips other than atmega8, atmega88 and at89s52. If anything is unclear, contact me again and ill try to answer your questions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I still cannot understand how it worked.

The RST pin on the AT89S52 is active-high.
The RESET pin on an AVR is active-low.

You are connecting pin#5 (RST) on the ISP header to an AVR. Which is fine.
But the signal is the wrong way round for an AT89 part.

The other anomaly is that a AT89S52 echoes 0x69 on the 4th SPI of a ISP_ENABLE_PGM command. The original usbasp firmware looks for an 0x53 on the 3rd SPI of the ISP_ENABLE_PGM command.

Hey-ho. It worked for you. Since you have both an ATmeg88 and an ATmega8 chip, you can use the usbasp to load new firmware into the other chip. Then replace in the usbasp socket.

From your photo, you appear to have a 0R0 resistor between SS (pin#16) and your AVR RST (pin#1).

David.

p.s. buy some NON Pb-free solder. It is legal for hobbyists.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi again. Yes pin 16 is connected to 1 and yes, increadible. I was (am) so happy that this worked. By chance actually. Ive been on this since july really.

Enviroment, my friend. Have to think of the enviroment. Pb is also toxic. And i solder daily so...

Now if you really want to test this out for yourself i can send my setup to you (provided that you send it back after youre done).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

The other anomaly is that a AT89S52 echoes 0x69 on the 4th SPI of a ISP_ENABLE_PGM command. The original usbasp firmware looks for an 0x53 on the 3rd SPI of the ISP_ENABLE_PGM command.

You are WAY above me when it comes to understanding electronics. I unfortunately do not know what you mean with this.

Ill try to program the AT89S52 with the commercial usbasp, hang on and ill report back.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I doubt that the amount of Pb in that size of pcb is going to do you any harm. It may make better joints though!

I thought that you lived in France. It is simpler to email C code.

I still reckon you need to go over your pcb with a fine tooth comb. It should work perfectly when programming the external ATmega88.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Difference between a commercial vs a homemade usbasp.

Writing to the chip takes exactly 5 minutes with the commercial one. Reading takes the same amount though.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I still cannot understand how the commercial usbasp managed to communicate with the wrong level on the RST pin.

The read and write times can be improved to a few seconds for 8k. Your times should only be about 10 seconds to write 194 bytes even with your current firmware.

First off, please can you confirm that your home-made usbasp works flawlessly with your ATmega8(8).

Then I will email you a different firmware.

Incidentally, I reckon that the simplest way of coping with an AT89 RST, is to just use a PNP transistor across the RST capacitor. Then you will have an active-low RST signal, the same as an AVR.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Confirmed, works flawless while programming an atmega8.

David, do you have access to a nice, simple and easy c++-code + wiring to the At89S52 which can be used to run a 16x2 LCD? Have you come across such a website? (plenty of assembler sites out there but im an assembler illiterate) Been looking and experimenting all day but cannot get it to work.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As HD44780 compatible LCD support only involves a bit of wire-wiggling on an I/O port could you not simply port one of then many AVR based C solutions just replacing the lowest level bit access stuff?

Maybe start with Peter Fleury's code?

http://homepage.hispeed.ch/peterfleury/avr-lcd44780.html

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This originated with danni.
It looks the most straightforward LCD code to me.
At least you do not have complicated conditionals.
It is ideal for bit-addressable MCU's.

#include "lcd_drv.h"                    // prototypes
#include "mcu.h"                        // "AT89S52.h"
#include "delay.h"                      // delay macros

// you only need these three basic functions (put in lcd_drv.h ):
extern unsigned char lcd_data(unsigned char c);
extern unsigned char lcd_command(unsigned char c);
extern void init_lcd(void);

// define these appropriately for your hardware
// hard-wire RW pin to GND
#define LCD_RS	P1_2
#define LCD_E0	P1_3
#define LCD_D4	P1_4
#define LCD_D5	P1_5
#define LCD_D6	P1_6
#define LCD_D7	P1_7

static void lcd_nibble( unsigned char d )
{
  LCD_D4 = 0; if( d & (1<<4)) LCD_D4 = 1;
  LCD_D5 = 0; if( d & (1<<5)) LCD_D5 = 1;
  LCD_D6 = 0; if( d & (1<<6)) LCD_D6 = 1;
  LCD_D7 = 0; if( d & (1<<7)) LCD_D7 = 1;

  _delay_us( 1 );	// 1us
  LCD_E0 = 1;           // strobe the E line
  _delay_us( 1 );	// 1us
  LCD_E0 = 0;
}

unsigned char lcd_data(unsigned char c)
{
  LCD_RS = 1;
  lcd_nibble(c);	// move into bits 4..7
  lcd_nibble(c<<4);     // move the lower bits.
  _delay_us(37);        // enough time to complete
  return c;
}

unsigned char lcd_command(unsigned char c)
{
  LCD_RS = 0;
  lcd_nibble(c);	// move into bits 4..7
  lcd_nibble(c<<4);
  _delay_us(37);        // enough time to complete
  if (c <= 3)           // commands CLR, RTN take a long time
     _delay_ms(2);
  return c;
}

void init_lcd( void )
{
  // set DDR bits here for AVR's or PIC's etc.
  LCD_E0 = 0;
  LCD_RS = 0;				// send commands
  _delay_ms( 15 );			// wait 15ms

  lcd_nibble( 0x30 );
  _delay_ms( 5 );			// wait >4.1ms

  lcd_nibble( 0x30 );
  _delay_us( 100 );			// wait >100us

  lcd_nibble( 0x30 );			// 8 bit mode
  _delay_us( 100 );			// wait >100us

  lcd_nibble( 0x20 );			// 4 bit mode
  _delay_us( 100 );			// wait >100us

  lcd_command( 0x28 );			// 2 lines 5*7
  lcd_command( 0x08 );			// display off
  lcd_command( 0x01 );			// display clear
  lcd_command( 0x06 );                  // cursor increment
  lcd_command( 0x0C );			// on, no cursor, no blink
}

In fact you can use the same straightforward code with CodeVision AVR. Just add DDR initialisation to lcd_init()
Or if you use bitfield macros in the LCD_D4 defines, you can use any AVR compiler.

Note that a regular 8051 does not really need 1us delays. It does not run very fast.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi again David, thanks for the code. Do you happen to have the include files as well? Or do these have to be developed?

(Waiting for your firmware)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You put the lcd_xxx() prototypes into a "lcd_drv.h"
You put some simple delay macro / function in your file. If you are using a 4MHz crystal, I expect that you do not need any sub-100us delays at all.
SDCC uses for your AT89S52 micro.
KEIL may want

#include "AT89x52.h"

// simple macro that is good enough for 18MHz.
// you really need a F_CPU dependent ASM macro.
#define _delay_us(n)	{volatile int t = 1 + (n)/6;  while (t--) ;}

void _delay_ms(int ms)
{
   while (ms--) _delay_us(1000);
}

A "test_lcd_8051.c"

#include 
#include "lcd_drv.h"

extern void _delay_ms(int ms);

void lcd_puts(char *s)
{
    while (*s) lcd_data(*s++);
}

void main(void)
{
    init_lcd();
    lcd_puts("Hello World");
    while (1) {
        _delay_ms(1000);
        lcd_data('X');
    }
}     

Are you happy with C programming? I can give you a 'ready to run' ZIP if you say what board and compiler you are using. I do not know whether your LCD has pull-up resistors. 8051's need pull-ups, they cannot drive an o/p high.

It may be better to continue via private email. Uncle Bob will start getting twitchy.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Right, have some spare time to report back on some "progress". Here is how you reliably make a AT89S52 work with an LCD. Courtesy of Rickey's World.

Hardwiring:

LCD.h

 
/*
 * Filename : lcd.h
 * Hardware : Controller  -> P89V51RD2
 *            XTAL        -> 18.432 MHz
 *            Mode        -> 6 Clock/MC
 * I/O      : RS          -> P2.5
 *            Enable      -> P2.4
 *            Data4567    -> P2.0,P2.1,P2.2,P2.3
 * Compiler : SDCC            
 * Author   : sci-3d@hotmail.com
 * Date		: 01/08/06
 */

 #define LCD_en P2_4
 #define LCD_rs P2_5 
 #define LCD_DELAY 1535 /* Delay for 1 ms */
 #define LCD_clear() LCD_command(0x1)	/* Clear display LCD */
 #define LCD_origin() LCD_command(0x2)	/* Set to origin LCD */
 #define LCD_row1() LCD_command(0x80)	/* Begin at Line 1 */
 #define LCD_row2() LCD_command(0xC0)   /* Begin at Line 2 */
 
/***************************************************
 * Prototype(s)                                    *
 ***************************************************/
void LCD_delay(unsigned char ms);
void LCD_enable();
void LCD_command(unsigned char command);
void LCD_putc(unsigned char ascii);
void LCD_puts(unsigned char *lcd_string);
void LCD_init();

/***************************************************
 * Sources                                         *
 ***************************************************/
void LCD_delay(unsigned char ms)
{
	unsigned char n;
	unsigned int i;
	for (n=0; n>4) & 0x0F);
    LCD_enable();
    P2 = (P2 & 0xF0)|(command & 0x0F);
    LCD_enable();
    LCD_delay(1);
}

void LCD_putc(unsigned char ascii)
{
    LCD_rs = 1; /* Set bit P2.5 */
    P2 = (P2 & 0xF0)|((ascii>>4) & 0x0F);
    LCD_enable();
    P2 = (P2 & 0xF0)|(ascii & 0x0F);
    LCD_enable();
    LCD_delay(1);
}

void LCD_puts(unsigned char *lcd_string)
{
	while (*lcd_string) 
	{
		LCD_putc(*lcd_string++);
	}
}

void LCD_init()
{
    LCD_en = 1; /* Set bit P2.4 */
    LCD_rs = 0; /* Clear bit P2.5 */   
    LCD_command(0x33);
    LCD_command(0x32);
    LCD_command(0x28);
    LCD_command(0x0C);
    LCD_command(0x06);
    LCD_command(0x01); /* Clear */
    LCD_delay(256);
}

Test.c

#include 
#include 
#include 
#include "lcd.h"

delay(unsigned int y){
    unsigned int i;
    for(i=0;i");
    while (1)
	{
		P1_0 = 0;
		delay(20000);
		P1_0 = 1; 
		delay(20000);
	}
}

hex code

:1000BF0048656C6C6F204C4344003C204C696E6566
:0900CF0020323A204F4B203E0084
:1000A600E4FEEEC39F5011E4FDFC0DBD00010CBC47
:0800B60005F8BDFFF50E80EA1C
:0100BE00221F
:10008200EBC4540FFFE5A054F04FF5A012009CEB17
:0A009200540FFFE5A054F04FF5A055
:0A009C00C2A47F011200A6D2A42224
:0C010600AB07C2A51200827F010200A618
:0C011200AB07D2A51200827F010200A6FC
:10005D008B088A09890AAB08AA09A90A1200D86077
:10006D0013050AE50A7002050914F91200D8FF12EA
:05007D00011280E222E7
:10003600D2A4C2A57F331201067F321201067F28A1
:100046001201067F0C1201067F061201067F0112BD
:070056000106E4FF0200A611
:1000F100E4FDFCC3ED9FEC9E50070DBD00010C809B
:04010100F2E4FEFF27
:0101050022D7
:100003001200367F801201067BFF7A0079BF12004F
:100013005D7FC01201067BFF7A0079C912005DC2C1
:10002300907F207E4E1200F1D2907F207E4E1200F0
:03003300F180EC6D
:0300000002011EDC
:0C011E00787FE4F6D8FD75810A0200032A
:1000D800BB010689828A83E0225002E722BBFE0226
:0900E800E32289828A83E4932259
:00000001FF

Works fantastically!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Since AT89S52s do not come with analog to digital convertes, were going to work on them next. Will report back on progress. If someone has info on how to do this cheaply and reliably, please do contribute. Ill be looking at IKAlogics ingenious voltagedivider ADC.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There are many extenal ADC chips. Choose any one that you like.

You might also choose to look at the above schematic.
You can accomplish your multiplexed display directly with an AVR or a PIC.
Other chips do not need a crystal.
Other chips can run on a wide voltage range.
Some other chips may have a DAC on board. Or you may choose PWM and a low-pass filter.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

angrysurgeon wrote:
Since AT89S52s do not come with analog to digital convertes, were going to work on them next. Will report back on progress. If someone has info on how to do this cheaply and reliably, please do contribute.
Buy an atmega, really. Because, ...
Quote:
Ill be looking at IKAlogics ingenious voltagedivider ADC.
... the additional effort with the OpAmp and 22 resistor's isn't worth it.

And there are a number of worrying issues with that DIY ADC. The two MSBs aren't on the same port then the remaining eight bits, so they aren't switched at the same time. A 10 bit DAC with an R-2R ladder requires 0.1% or better resistors. Using an OpAmp as a comparator isn't the best idea. Ingenious is something else.

Stealing Proteus doesn't make you an engineer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Arnold, youre probably right, but in this case and my opinion, its nice to have "been there, done that" with the AT89S52. Thanks for the tip that the ladder resistors have to be within a 0.1% tolerance.

David, ADCs are pretty pricey. I bought my 100 At89s for 80c each. Resistors are dirt cheap! Have you found any 8bit ADCs that are cheap, meaning 20-30c each at 100 pcs?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would agree that most microcontrollers only have 10-bit ADC subsystems. But they are adequate for most jobs. Using a single chip that does everything is very cost effective. You also get increased reliability. And the assembly / production costs are cheaper.

Note that you can buy ARM chips for less than 80c. For your money, you will get several hundred increase in processing power. And all the peripherals you could ever want.

Now, it is quite satisfying to complete a project with a geriatric 8051. Some particular jobs just suit the 8051.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I wish the conversation here had STAYED on the topic of programming 89s5x (series) with the AVR USBasp programmer using AVRDUDE.

here is my SIMILAR tale:

I have been working on AVRs happily, but my teacher wants me to learn 89s5x as well, so I buy a few AT89s51/2 controllers.

I have successfully burned a BLINKY hex on my AT89s52 via AVR USBasp using AVRDUDE Command line, but unlike "angrysurgeon"'s mine didn't work.

I had to put an INVERTER on the REST line, as the 89s are ACTIVE-HIGH RESET.

Anyways, the problem is that it is sometimes working and sometimes giving error of connection/incorrect-signature

I have not tested with a BIG HEX file, I was wondering if I can test writing a random generated hex file on it and then verify it to check the working of the programmer. [will that work...???]

MR. david.prentice, can you please send me that REVISED HEX file that you have mentioned up there... also, if possible can you tell me what changes you made in the CODE...

THANKS to ALL and especially angrysurgeon, david.prentice, the conf files up there have been of BIG HELP.. :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The basic avrdude only supports AVR type chips.
Likewise, the original usbasp only supports AVR type chips with active-low reset.

Quite honestly, it is cheaper to buy a Chinese usbasp for $3.99 than to make one yourself.

And use the Chinese GUI software that will program your AT89S52 (with active-high reset)
Chinese GUI
Download the "progisp 1.72" about half-way down the page.

If you prefer using avrdude with an inverter on the RESET line, here is an avrdude.conf entry.

# page size = 256 and we use cmd = 0x50 to write the page
part
    id               = "s52";
    desc             = "AT89S52";
    stk500_devcode      = 0xE1;
#    avr910_devcode      = 0x68;
    signature        = 0x1E 0x52 0x06;
    chip_erase_delay = 500000;
    pgm_enable       = "1 0 1 0  1 1 0 0    0 1 0 1  0 0 1 1",
                       "x x x x  x x x x    x x x x  x x x x";

    chip_erase       = "1 0 1 0  1 1 0 0    1 0 0 x  x x x x",
                       "x x x x  x x x x    x x x x  x x x x";
    
    retry_pulse  = reset;
    
    timeout      = 200;
    stabdelay      = 100;
    cmdexedelay      = 25;
    synchloops      = 32;
    bytedelay      = 0;
    pollindex      = 4;
    pollvalue      = 0x69;
    predelay      = 1;
    postdelay      = 1;
    pollmethod      = 0;

    memory "flash"
        size            = 8192;
        paged           = no;
        page_size	= 256;
        num_pages       = 32;
        min_write_delay = 400;
        max_write_delay = 900;
        readback_p1     = 0x00;
        readback_p2     = 0x00;

        read            = "  0   0   1   0    0   0   0   0",
                          "  x   x   x a12  a11 a10  a9  a8",
                          " a7  a6  a5  a4   a3  a2  a1  a0",
                          "  o   o   o   o    o   o   o   o";

        write           = "  0   1   0   0    0   0   0   0",
                          "  x   x   x a12  a11 a10  a9  a8",
                          " a7  a6  a5  a4   a3  a2  a1  a0",
                          "  i   i   i   i    i   i   i   i";
        loadpage_lo     = "  0   1   0   1      0   0   0   1",
                          "  0   0   x   x      x   x   x   x",
                          "  a7 a6  a5  a4     a3  a2  a1  a0",
                          "  i   i   i   i      i   i   i   i";

        writepage       = "  0   1   0   1      0   0   0   0",
                          "  x   x   x a12    a11 a10  a9  a8",
                          "  0   0   0   0      0   0   0   0",
                          "  x   x   x   x      x   x   x   x";
   mode      = 0x21;
   delay      = 12;
      ;

    memory "signature"
        size            = 3;
        read            = "0  0  1  0   1  0  0  0   x  x  x  0   0  0 a1 a0",
                          "0  0  0  0   0  0  0  0   o  o  o  o   o  o  o  o";
      ;
    memory "atmelsig"
        size            = 32;
        read            = "0  0  1  0   1  0  0  0   x  x  x a4  a3 a2 a1 a0",
                          "0  0  0  0   0  0  0  0   o  o  o  o   o  o  o  o";
      ;
    memory "lock"
        size            = 1;
        read            = "0  0  1  0   0  1  0  0   0  0  0  0   0  0  0  0",
                          "x  x  x  x   x  x  x  x   x  x  x  o   o  o  x  x";
        write           = "1  0  1  0   1  1  0  0   1  1  1  0   0  0  i  i",
                          "x  x  x  x   x  x  x  x   x  x  x  x   x  x  x  x";
      ;
  ;

You can test anything you like if you design a suitable 'test-suite'. But it is just as simple to write a regular C program, write it, verify it.

I cannot understand why anyone would choose an AT89S52. It is a very bog-standard 8051. It has no SPI, eeprom, compare-unit, ADC, I2C, ...

In fact it is pretty feature-free.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My HOMEMADE Programmer works but not program 89s51 see this video and please help me.
http://www.youtube.com/watch?v=_6iSPmjxs0s

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hello, I am starting with atmel microcontrollers, especially with this one (at89s52), I got the comunication of the programator (USBASP) with the program (PROGISP), I can load the programs with no problema(aparently), but the microcontroller just maintains the P1.1 on, I am using Keil, because I have used it with ARM., is there any step I am not doing?, I am using the vcc supply from the programator, and I just conected it with the circuit that angrysurgeon posted above
neither the hex program nor any other .hex example seems to work :(
any advice is well recieved