Viele Leute kennen den ATmega von den Arduino-Projekten. Dort sind die Prozessoren bereits mit einem sog. ‘Bootloader’ versehen, man kann sie also über deren serielle Schnittstelle programmieren.
Was aber, wenn man einen “rohen” ATmega hat, frisch vom Elektronikladen? Und außerdem kein AVR-Programmiergerät? Dann nimmt man eben des Raspberry zum Programmieren!
In der Zeitschrift “Funkamateur 2/2016” ist ein ähnlicher Artikel
enthalten. Aber der dort getriebene Aufwand ist wesentlich höher.
Beispielsweise wird ein Darlington-Array ULN2803
gebraucht, und die
Programmierung erfolgt auch nicht (auf Raspberry-Seite) über SPI und
einem Standardprogramm, sondern über GPIOs und einem Python-Programm.
Schaltung
Die Grundschaltung eines ATmega328 ist einfach:
VCC
(Pin 7) mit 3.3V verbinden. Theoretisch sollte man nochAVCC
(Pin 20) mit 3.3V verbinden, zum Programmieren brauchte ich das aber nicht.GND
(Pin 8) mit Masse verbinden. Theoretisch sollte man auch noch das andereGND
(Pin 22) mit Masse verbinden. Bei mir war das aber zum Programmieren nicht nötig.- ein Kondensator
C1
mit 100nF als Abblockkondensator nahe an Pins 7 und 8. - 16 MHz-Quarz an Pins 9 und 10
- von jedem Quarz-Pin ein 22pF Kondensator nach Masse führen
nRESET
über einen Pull-Up-Widerstand von 10 kOhm nachVCC
. Später merkte ich, das noch nicht mal der Pull-Up-Widerstand wirklich nötig ist …
Obige Grundschaltung findet man immer und immer wieder.
Nun wollen wir den ATmega jedoch programmieren, also müssen wir einige Bahnen vom Raspberry zum ATmega ziehen:
- gelb:
GPIO25
nachnRESET
- cyan:
GPIO10
/SPI0_MOSI
nachD11
/MOSI
- lila:
GPIO9
/SPI0_MISO
nachD12
/MISO
- grün:
GPIO11
/SPI_CLK
nachD13
/SCK
Die erste (gelbe) Leitung ist zum Resetten des ATmega.
Die anderen drei Leitungen sind SPI-Leitungen, mit denen der Raspberry den AVR programmieren kann.
Software
AVRdude installieren
Auf dem Raspberry brauchen wir die Software avrdude
:
pi@raspberrypi:~ $ sudo su
root@raspberrypi:/home/pi# apt-get install avrdude
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
libftdi1
Suggested packages:
avrdude-doc
The following NEW packages will be installed:
avrdude libftdi1
0 upgraded, 2 newly installed, 0 to remove and 12 not upgraded.
Need to get 260 kB of archives.
After this operation, 1,021 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://archive.raspberrypi.org/debian/ jessie/main avrdude armhf 6.1-2+rpi1 [244 kB]
Get:2 http://mirrordirector.raspbian.org/raspbian/ jessie/main libftdi1 armhf 0.20-2 [16.7 kB]
Fetched 260 kB in 1s (182 kB/s)
Selecting previously unselected package libftdi1:armhf.
(Reading database ... 126952 files and directories currently installed.)
Preparing to unpack .../libftdi1_0.20-2_armhf.deb ...
Unpacking libftdi1:armhf (0.20-2) ...
Selecting previously unselected package avrdude.
Preparing to unpack .../avrdude_6.1-2+rpi1_armhf.deb ...
Unpacking avrdude (6.1-2+rpi1) ...
Processing triggers for man-db (2.7.0.2-5) ...
Setting up libftdi1:armhf (0.20-2) ...
Setting up avrdude (6.1-2+rpi1) ...
Processing triggers for libc-bin (2.19-18+deb8u3) ...
Ältere Tutorials reden davon, das man den AVRdude selbst compilieren solle. Das ist aber mittlerweile nicht mehr nötig. Mein Raspberry läuft Raspian 8.0, also basierend auf Debian Jessie. Und die avrdude-Version 6.1 funktioniert einwandfrei.
Chip erkennen
Hat man alles richtig verdrahtet, sollte der Chip erkannt werden:
root@raspberrypi:~# avrdude -c linuxspi -p m328p -P /dev/spidev0.0
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e950f
avrdude: safemode: Fuses OK (E:07, H:D9, L:62)
avrdude done. Thank you.
Die Device-Signatur 0x1e950f steht für den ATmega328P, also exakt für den Chip, den ich mir gekauft hatte.
Sollte kein /dev/spidev0.0
vorhanden sein, muss raspi-config
starten und unter “Advanced Options” SPI aktivieren.
Takt senken
Bei mir ging es danach aber dennoch noch nicht. Erst als ich den SPI-Takt von 400 kHz auf 200 kHz gesenkt hatte, lief es. Das ist zwar deutlich langsamer als vorher, aber immer noch schneller als mit GPIO-“Bitbanging”.
Dazu in /etc/avrdude.conf
den Eintrag linuxspi
so ändern:
programmer
id = "linuxspi";
desc = "Use Linux SPI device in /dev/spidev*";
type = "linuxspi";
reset = 25;
baudrate=200000;
;
Nun hat’s funktioniert. Ich vermute, das meine Kabel vom Raspberry zum Breadboard mit dem ATmega zu lang waren.