DIY记录之 USBasp

笔者在上网浏览时发现了这个项目[0]。刚好另一个DIY会需要对Attiny85进行烧写,并且感觉自己做一个USBasp来干这个事比较有趣,于是就买材料打板子准备DIY一个USBasp。这篇随笔是用来记录过程的,希望也能方便别的对此感兴趣的并且也想DIY的读者。

注意

笔者的电脑环境是Arch GNU/Linux,并且偏爱命令行,喜欢GUI或者在别的电脑环境下操作的读者请自行寻找资料进行对应操作。

本篇随笔的指令基本上都来自于该网址(https://www.fischl.de/usbasp/),仅供参考,具体请查看源代码中的Readme.txt文件。

板子

在官网上[0]往下翻会发现作者Thomas Fischl提供的其实是固件和Schematic。布局的话则可以继续往下翻,会看到一个列表,其中都是用户所设计的布局。笔者比较慵懒,所以就直接选择了一个个人比较喜欢的由yellobyte设计的用MIT协议发布[5]的布局而非自己设计布局。链接如下:

https://github.com/yellobyte/USB-Atmel-In-Circuit-Programmer

只要把Gerber文件[1]在打板工厂上上传并且下单就行了。

过几天就能收到板子:

材料

作者已经将BOM文件放在库中了[2]。我们只需要解压:

复制代码
unzip USBasp-BOM.zip

然后因为解压出的文件的格式是xlsx,在命令行中读起来不方便,所以笔者安装了csvkit:

复制代码
sudo pacman -S csvkit

然后把xlsx转换成csv格式:

复制代码
in2csv USBasp-BOM.xlsx > USBasp-BOM.csv

这样子就能直接用editor来查看了。

接下来照着BOM买材料就行了。

焊接

焊接这一块笔者就没什么发言权了。给不熟悉焊接的读者推荐这篇能用来入门焊接的漫画《焊接是容易的》。元器件对应的位置可以根据BOM内容和板子上的标识来确认,在yellowbyte的库中也有焊接完成后的照片[3]。下面有一张笔者焊接完后的照片。笔者焊错了USB口旁边的电阻,不过因为目前为止功能上还没什么问题所以就这样了,请以yellowbyte设计的为准。两个LED是因为BOM中的元件不方便买,笔者就直接用两个LED替代。那两个按钮的价格偏贵,有能力的读者可以尝试使用pin针去代替它们。

烧写程序

这个USBasp使用的芯片有两个选择,一个是ATMega88,另一个是ATMega8,笔者使用的是ATMega8A(功能跟ATMega8一致,用来替代ATMega8的型号[4])。这两个都算是Atmel AVR controllers。而USBasp的全称是USB programmer for Atmel AVR controllers,意味着它是用来给Atmel AVR controllers烧写程序的。为了解决这个鸡生蛋蛋生鸡的问题,我们需要一个已经能使用的烧录器来给USBasp的芯片烧写程序。笔者刚好有一个Arduino uno,所以就使用它来搞定。

将Arduino uno变成烧写器

安装arduino-cli

复制代码
sudo pacman -S  arduino-cli

将Arduino uno用USB线连上然后运行命令来确认代表它的设备文件是哪个:

复制代码
$ arduino-cli board list
Port         Protocol Type              Board Name  FQBN            Core
/dev/ttyACM0 serial   Serial Port (USB) Arduino Uno arduino:avr:uno arduino:avr

在这里设备文件是/dev/ttyACM0

把ArduinoISP的代码文件下载下来,编译然后上传的Arduino uno上。

复制代码
arduino-cli compile -b arduino:avr:uno ISP.ino
arduino-cli upload -b arduino:avr:uno -p /dev/ttyACM0 -v ISP.ino

烧写固件

像Arduino ISP源代码中的注释描述的那样,Arduino uno 上的 pin口 11, 12, 13 分别对应的是 MOSI,MISO,SCK。而 pin 10则是 RESET。在这个文件中能看到ISP的10pin接口对应的名字:

另一个文件中展示的pin对应。

那么就用杜邦线把对应的pin和pin口一一连接。

也要将PCB上旁边标有Self Progr的两个pin针用母对母杜邦线连接,告诉USBasp我们要对它上面的ATmega8芯片烧写程序。

接下来确保电脑上已安装avrdude,没有的话并且是Arch的话可以这样下载:

复制代码
sudo pacman -S avrdude

然后运行:

复制代码
avrdude -c arduino_as_isp -p m8 -P /dev/ttyACM0 -v -v

在这个命令中,-c avrdude代表我们使用的烧写器是Arduino,-p m8代表程序要被写到ATmega8型号的芯片中(可运行avrdude -p ?查看)。

出现下面的输出就代表Arduino ISP识别到了我们的ATmega8芯片。

plain 复制代码
...
Programmer type       : STK500
Description           : AVR as programmer with Arduino-as-ISP FW
HW Version            : 2
FW Version            : 1.18
Topcard               : Unknown
SCK period            : 0.0 us
XTAL frequency        : 7.372800 MHz

AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.02 s
Device signature = 1E 93 07 (ATmega8, ATmega8A)

Avrdude done.  Thank you.

接下来就去USBasp的官网,下载固件文件:

bash 复制代码
wget https://www.fischl.de/usbasp/usbasp.2011-05-28.tar.gz

解压后跳转到固件所在的文件夹:

复制代码
tar -xvf usbasp.2011-05-28.tar.gz
cd usbasp.2011-05-28/bin/firmware

运行下面的指令把固件刷进去:

复制代码
avrdude -c arduino_as_isp -p m8 -P /dev/ttyACM0 -U flash:w:usbasp.atmega8.2011-05-28.hex -v -v

出现以下输出就代表成功了:

plain 复制代码
...
AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.02 s
Device signature = 1E 93 07 (ATmega8, ATmega8A)
Auto-erasing chip as flash memory needs programming (-U flash:w:...)
specify the -D option to disable this feature
Erased chip
Reading 4700 bytes for flash from input file usbasp.atmega8.2011-05-28.hex
in 1 section [0, 0x125b]: 74 pages and 36 pad bytes
Writing 4700 bytes to flash
Writing | ################################################## | 100% 6.71 s
Reading | ################################################## | 100% 3.33 s
4700 bytes of flash verified

Avrdude done.  Thank you.

接下来再把fuse bits给修改了,这样子ATmega8就会使用我们为它准备的更加精确的12MHz外部晶振,而非芯片内部的振荡器。

复制代码
avrdude -c arduino_as_isp -p m8 -P /dev/ttyACM0 -U hfuse:w:0xC9:m -U lfuse:w:0xEF:m -v -v

出现以下输出就代表成功了。

plain 复制代码
...
AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.02 s
Device signature = 1E 93 07 (ATmega8, ATmega8A)

Processing -U hfuse:w:0xC9:m
Reading 1 byte for hfuse from input file 0xC9
in 1 section [0, 0]
Writing 1 byte (0xC9) to hfuse
Writing | ################################################## | 100% 0.03 s
Reading | ################################################## | 100% 0.01 s
1 byte of hfuse verified

Processing -U lfuse:w:0xEF:m
Reading 1 byte for lfuse from input file 0xEF
in 1 section [0, 0]
Writing 1 byte (0xEF) to lfuse
Writing | ################################################## | 100% 0.03 s
Reading | ################################################## | 100% 0.01 s
1 byte of lfuse verified

Avrdude done.  Thank you.

验证是否成功

如果PCB板上的JP1有杜邦线连接就把它拔掉。在命令行运行sudo dmesg -w。用USB连接电脑和USBasp,如果输出出现了以下信息,就代表成功了!

plain 复制代码
[40715.209403] usb 4-2: new low-speed USB device number 24 using xhci_hcd
[40715.357491] usb 4-2: New USB device found, idVendor=16c0, idProduct=05dc, bcdDevice= 1.04
[40715.357505] usb 4-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[40715.357512] usb 4-2: Product: USBasp
[40715.357518] usb 4-2: Manufacturer: www.fischl.de

正如官方Readme.txt所说的,要以非root权限使用USBasp,这也是比较正确的做法,我们需要把usbasp.2011-05-28/bin/linux-nonroot中的99-USBasp.rules文件复制到/etc/udev/rules.d/中。不过因为SYSFS已经被弃用了,从官网下载的包中的udev rules在笔者的电脑上不起作用,这个链接中的在笔者电脑上才有效果。设置完udev后插上USB运行avrdude -c usbasp,出现以下输出就说明搞定了:

复制代码
...
  64ea48     = AVR64EA48 (SPM, UPDI)
  8ea28      = AVR8EA28 (SPM, UPDI)
  8ea32      = AVR8EA32 (SPM, UPDI)
  lgt8f168p  = LGT8F168P (SPM, ISP, HVPP, debugWIRE)
  lgt8f328p  = LGT8F328P (SPM, ISP, HVPP, debugWIRE)
  lgt8f88p   = LGT8F88P (SPM, ISP, HVPP, debugWIRE)


Avrdude done.  Thank you.

如果想刷入别的程序

需要用杜邦线连接JP1,然后Arduino ISP中的这行源代码要改成#define SPI_CLOCK (12000000 / 6)。因为我们的ATmega8已经在使用12MHz的外部晶振了,而非1MHz的默认的内部振荡器。

试用一下

笔者有一个TV-B-GONE的DIY用的是ATtiny85,正好拿它来做个实验。

根据这个链接的CAD文件连接好MOSI,MISO,SCK,RST和GND。根据这个网页的描述,我们需要放一个100nF的电容连接ATtiny85的Vcc和GND,不过笔者最后是用了一个10uF的电容成功的。按下PCB上的S1(Low Speed)然后运行:

复制代码
avrdude -p attiny85 -c usbasp -B 1 -v -v

输出是:

plain 复制代码
...
Programmer type       : usbasp
Description           : USBasp ISP and TPI programmer
Try to set SCK period to 1e-06 s (= 1000000 Hz)
Connected USBasp is not cabable of 3 MHz SCK
Set SCK frequency to 750000 Hz

AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.02 s
Device signature = 1E 93 0B (ATtiny85)

Avrdude done.  Thank you.

就说明检测到了我们的ATtiny85。

下载一下代码TV-B-GONE的代码:

复制代码
git clone https://github.com/adafruit/TV-B-Gone-kit.git
cd firmware

然后开刷:

复制代码
avrdude -p attiny85 -c usbasp -B 1 -U flash:w:tvbgone.hex -v -v

等待一段时间然后看到这些就说明程序写好了:

plain 复制代码
...
Programmer type       : usbasp
Description           : USBasp ISP and TPI programmer
Try to set SCK period to 1e-06 s (= 1000000 Hz)
Connected USBasp is not cabable of 3 MHz SCK
Set SCK frequency to 750000 Hz

AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.02 s
Device signature = 1E 93 0B (ATtiny85)
Auto-erasing chip as flash memory needs programming (-U flash:w:...)
specify the -D option to disable this feature
Try to set SCK period to 1e-06 s (= 1000000 Hz)
Connected USBasp is not cabable of 3 MHz SCK
Set SCK frequency to 750000 Hz
Erased chip
Reading 7948 bytes for flash from input file tvbgone.hex
in 1 section [0, 0x1f0b]: 125 pages and 52 pad bytes
Writing 7948 bytes to flash
Writing | ################################################## | 100% 63.96 s
Reading | ################################################## | 100% 54.63 s
7948 bytes of flash verified

Avrdude done.  Thank you.

然后是把fuse bits给改了这样ATtiny85就会使用8MHz的外部晶振了:

复制代码
avrdude -p attiny85 -c usbasp -B 250 -U lfuse:w:0xfd:m -U hfuse:w:0xdf:m -v -v

输出:

plain 复制代码
...
AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.02 s
Device signature = 1E 93 0B (ATtiny85)

Processing -U lfuse:w:0xfd:m
Reading 1 byte for lfuse from input file 0xfd
in 1 section [0, 0]
Writing 1 byte (0xFD) to lfuse
Writing | ################################################## | 100% 0.03 s
Reading | ################################################## | 100% 0.01 s
1 byte of lfuse verified

Processing -U hfuse:w:0xdf:m
Reading 1 byte for hfuse from input file 0xdf
in 1 section [0, 0]
Writing 1 byte (0xDF) to hfuse
Writing | ################################################## | 100% 0.01 s
Reading | ################################################## | 100% 0.01 s
1 byte of hfuse verified

Avrdude done.  Thank you.

这样子就搞定了,放到PCB上也能正常运行。

总结

对笔者而言这是一个有趣又实用的DIY项目,也感谢USBasp的作者Thomas Fischl和本文使用的PCB的作者yellowbyte。认为这些设计对自己有帮助的读者可以考虑花些钱支持一下USBasp的作者。
https://www.fischl.de/usbasp/

本文链接:https://www.cnblogs.com/chenw1/p/18816830

发布协议

本文以GFDL1.3+协议发布

Copyright (C) 2025.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.