# [Ubuntu]在ubuntu上编译、烧写AT80S52 (Working on Ubunutu: compiling, burining for AT80S52)

In this article, I will use sdcc to cross-compile source file of 8051, and burn its output(hex file) over usbasp with avrdude.

[cpp]
/* Filename: test.c
* Description: sample source for sdcc
* Author: Lesca FANG
* Date: Mar 7, 2011
*/

#include <8052.h>
typedef unsigned int size_t;

#define LED P0_0

void delay(size_t t)
{
while(t–);
}

void main()
{
while(1)
{
LED = 0;
delay(10000);
LED = 1;
delay(10000);
}
}

[/cpp]

If you haven’t install sdcc yet, run the following command:

$sudo apt-get install sdcc 如果已经成功安装，则运行下面的命令： If that’s done, run this command: $ sdcc -mmcs51 test.c

What we need here is .ihx(Intel hex) file.

avrdude is supposed to burn for AVR chips, so it’s not possible to burn directly to 8051 chips. But after some configuration, impossible is noting.

We have three different configration files for 8051 chips. They are respectively suit for some types. Check what you need and then copy them to /etc/avrdude.conf.

For AT89S51

#------------------------------------------------------------
# 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;
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";
;
;


For AT89S52

#------------------------------------------------------------
# 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;
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";
;
;


For AT89S8253

#------------------------------------------------------------
# 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;
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;
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";
;
;


After configuring, we can now burn the ROM. Still remember the output file that we need? Yes! It’s test.ihx :

$sudo avrdude -p 8052 -c usbasp -e -U flash:w:'./test.ihx' avrdude: warning: cannot set sck period. please check for usbasp firmware update. avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.02s avrdude: Device signature = 0x1e5206 avrdude: erasing chip avrdude: warning: cannot set sck period. please check for usbasp firmware update. avrdude: reading input file "./test.ihx" avrdude: input file ./test.ihx auto detected as Intel Hex avrdude: writing flash (140 bytes): Writing | ################################################## | 100% 2.07s avrdude: 140 bytes of flash written avrdude: verifying flash memory against ./test.ihx: avrdude: load data flash data from input file ./test.ihx: avrdude: input file ./test.ihx auto detected as Intel Hex avrdude: input file ./test.ihx contains 140 bytes avrdude: reading on-chip flash data: Reading | ################################################## | 100% 0.70s avrdude: verifying ... avrdude: 140 bytes of flash verified avrdude: safemode: Fuses OK avrdude done. Thank you.  选项说明(Options)： -p specifies the type of the MCU connected to the programmer. -c specifies the default programmer -e causes a chip erase to be executed. -U memtype:op:filename The op field specifies what operation to perform: r read device memory and write to the specified file w read data from the specified file and write to the device memory v read data from both the device and the specified file and perform a verify  我现在所能做的就是祝你好运，因为如果没有成功很有可能是以下原因造成的。 What I can do now is saying “Good luck” to you, ‘cos a failure can be caused by the following reasons. 错误排解 What’s wrong? • 你的下载线没有被系统正确识别 Your usbasp is not identified by your system • lsusb看看有没有这行，如果没有很有可能是你的usbasp有问题。 Check this line with lsusb. If no similar here, it may be your usbasp’s responsibility. $ lsusb
Bus 008 Device 002: ID 16c0:05dc VOTI USBasp AVR Programmer

• 系统发现了usbasp可是还是不行  System has found the usbasp device but it still won’t work
• 这很有可能是你的usbasp内部ROM不正确或者使用的不是标准usbasp协议造成的。建议购买商业版的usbasp下载线，比较稳定。
This is probobaly because of a incorrect usbasp ROM or non-standard usbasp protocal. You may use a commercial usbasp which can be more reliable.

Q&A

• 为什么avrdude如此之慢？ Why avrdude is so slow?
• 这主要是因为它每次只在USB包中放置一字节。我也试过使用页面模式，但是这不能适用于大文件的下载，而且每次读回校检都失败
This is because it only reads one byte for every USB packet. I have tried to change it to page mode, but it doesn’t work for big hex files and cannot read-back verifring.

• 为什么要root权限运行avrdude？ Why run avrdude as root?
• 在Ubuntu上，只有使用root权限才能打开usbasp所在的USB设备。
Only run as root can it open the USB device linked with usbasp on Ubuntu.

• 命令太长了？Too long command line?
• 试试这个，保存后要改为可执行。
Try this batch file, save it, change mode to executive.
[bash]
#! /bin/bash
mode=flash:w:PWD/1
#echo mode
sudo avrdude -p 8052 -c usbasp -e -U
mode
[/bash]
这个脚本只有一个参数——待下载文件名。