Programmierung von ATmega8-16PU macht Probleme

OP #1769087
Lesenswert?

Hallo zusammen,

ich hab eine kleine Platine aufgebaut mit einem ATmega8-16PU. Ich kann 
diesen aber leider nicht programmieren, PonyProg sagt mir "Device 
missing or unknown Device (-24)". Ein Klick auf "Ignorieren" bringt auch 
nichts, nach einigen Sekunden heißt es "Write failed". Ich habe den 
Quellcode in C mit AVR Studio 4 erstellt und mit PonyProg dann die 
hex-Datei geöffnet, und versucht auf den IC zu schreiben.

Hier mal einige Informationen:

- Alle +5V Spannungsversorgen liegen an den Chip-Beinchen an (5V kommen 
von einem 7805)
- Alle Masseverbindungen des ICs sind beschaltet
- Ich verwende an den PINS 9 und 10 einen 4.0000 Mhz Quarz mit zwei 22pF 
Kondensatoren
- Der ATmega ist nagelneu
- Alle Kontakte auf dem IC-Sockel haben einwandfreie Verbindung
- Alle PINs von der Programmierbuchse (Wannenstecker) gehen zu den 
richtigen PINs am ATmega. Spannungsversorgung +5V am Programmierstecker 
liegt ebenfalls an.

Hat jemand eine Idee?

Mir fällt als Fehlerquelle folgendes ein:

- falscher serieller Adapter? Dieser hier: 
http://www.anvilex.de/Extern/Datasheets/DS_P009_10.pdf
- fehlende Kondensatoren direkt an den Spannungseingängen am IC (100nF)?
- Falscher Quarz? Ich verwende einen 4,0000 statt 3,6864?

Vielleicht ist es auch nur ein ganz einfacher Anfängerfehler, ich hab 
noch nie einen ATmega programmiert...

Danke
#1769097
Lesenswert?

Christian W. schrieb:
> - Der ATmega ist nagelneu

Das könnte das Problem sein. Hast Du schon Fuses setzen können? Neue 
ATmegas laufen mit internem 8 MHz Takt und Takteiler 8. Resultat sind 1 
MHz Taktfrequenz. Das ist beim Programmieren mittels ISP zu beachten, da 
die maximale Frequenz der ISP-Clock um einen gewissen Teiler kleiner 
sein muss. Leider habe ich den Teiler gerade nicht im Kopf (4?).

Christian W. schrieb:
> - Falscher Quarz? Ich verwende einen 4,0000 statt 3,6864?

Der Quarz geht einem nagelneuen ATmega am Boppes vorbei. ;) Der läuft - 
solange die Fuses diesbezüglich nicht gesetzt sind - mit 1 MHz (8 MHz 
interner Takt mit Taktteiler 8).

Christian W. schrieb:
> - fehlende Kondensatoren direkt an den Spannungseingängen am IC (100nF)?

Sollte nicht Ursache für Dein Problem sein, solche Kondensatoren sind 
aber sehr empfehlenswert.
#1769109
Lesenswert?

Hallo  Christian W. ,

>   Ein Klick auf "Ignorieren" bringt auch nichts

das haben auch schon viele Hasen gesagt, die dann im Schlund des Adlers 
endeten.

Leider konnten wir diese Hasen nicht mehr befragen!

 Gastino G. sagte schon was  dazu.

schritt 1:
einen kleinen Messpin an GND des Prozessors löten
schritt 2
Minuskabel des  Multimeters an diesen Messpin
schritt 3 :
Mit Multimetre dann messen an VCC und dann an RESET

beide müssen High sein
RESET fällt kurz auf LOW bei jedem versuch zu programmieren (kann man 
messen)

TIPP:
meistens sind MISO oder MOSI vertauscht

grussi klausi
OP #1769406
Lesenswert?

Hallo, danke für die Beiträge. Ich werd das alles mal testen. Fusebits 
kann ich leider nicht setzen, geschweige denn auslesen aus dem Chip, 
jedesmal kommt diese "Device missing..." Meldung.

Hab mal einen Schaltplan angehängt, wie die Platine momentan aussieht, 
vielleicht hat jemand Lust, mal kurz drüberzuschauen.

Danke

Christian
Angehängte Dateien:
Gast #1769414
Lesenswert?

Hast du im Ponyprog-Einstellungsfenster "Siprog-API" ausgewählt?
Pullup an /Reset vorhanden? Falsche Reset-Polarität ausgewählt?
"Calibration"durchgeführt?
Manchmal hilft ein kleiner Kondensator in der SCK-Leitung, dann kommt 
der Clock "leicht verzögert" am Mega8 an. Eine Hausnummer wie groß der 
sein soll, hab ich jetzt leider nicht im Kopf, lief bei mir immer ohne.
Richtiger COM-Port ausgewählt?

\0
Gast #1769428
Lesenswert?

Ad Schaltplan: Du Hast die ∗Bezeichnungen∗ von MOSI und MISO vertauscht, 
und zwar sowohl am Header als auch am µC, die ∗Verdrahtung∗ dagegen 
passt laut Plan. Überprüf nochmal, ob die auch in der Schaltung so 
stimmt.
OP #1769443
Lesenswert?

Hallo,

danke für die schnellen Nachrichten.

Im PonyProg ist momentan der Siprog API gewählt, COM Schnittstelle 
stimmt auch. Ich hab auch schon andere Adapter im PonyProg getestet aber 
ohne Erfolg.

Ein Pullup-Widerstand am Reset-PIN ist nicht vorhanden, der PIN geht 
direkt an den Wannenstecker mit einem Draht.

Oszi hab ich keines...

Die MOSI MISO Belegungen stimmen auf der Platine 1:1.

Hab mal ein Digitalmultimeter angesteckt. Da ergibt sich folgendes:

- Platine ohne Stromversorgung und mit angesteckter serieller 
Schnittstelle: Reset PIN hat -0,35V

- Platine MIT Stromversorgung und mit angesteckter serieller 
Schnittstelle: Reset PIn hat + 4,73V

- Die 4,73 V ändern sich auch dann nicht, wenn ich versuche zu 
Programmieren oder etwas aus dem IC auszulesen.

Kann das tatsächlich sein, dass das Programmierinterface Schrott ist? 
Das hab ich mir fertig gekauft.

Kann ich während des Programmiervorgangs mit einer Krokoklemme den 
Reset-PIN auf Masse ziehen oder geht da was kaputt?

Danke

Christian
#1769447
Lesenswert?

Hallo Christian,

> Kann ich während des Programmiervorgangs mit einer Krokoklemme den
> Reset-PIN auf Masse ziehen oder geht da was kaputt?

Das kannst du und es geht nix kaputt...  leider nützt es aber auch nix.
Der Reset geht beim Proggen ja nur kurz auf Low um den Vorgang 
einzuleiten.
Dauerreset verhindert also das proggen.

Das du an die Fuses nicht herankommst ist unter diesen Umständen auch 
klar.
.. eigentlich benötigt man diese in deinem Stadium auch ersteinmal 
nicht.

.. anderen Prozessor versucht (wegen der Pferde vor der Apotheke)

gruss K.

p.s.
am Anfang sind es oft Einstellungen bezüglich des Programmers .. 
respektive
der PC Hardware, die , falls falsch, Probleme machen.

zudem solltest Du in diesem Stadium eher versuchen die Fuses auszulesen 
als irgendwas zu proggen.
OP #1769499
Lesenswert?

ok danke für die antworten.

ich werde bei der pc hardware ansetzen mit fehlersuchen, da mir der 
programmieradapter den ich verwende ziemlich komisch vorkommt. weil: im 
sub-d-steckergehäuse sitzt ein kleiner smd-ic, der da meiner meinung 
nach nicht hingehört und vielleicht den direkten datenaustausch zwischen 
pc und atmel verhindert. eigentlich müssten ja ein paar widerstände und 
ein transistor reichen?

kann ich diesen programmieradapter wie in der grafik angehängt 
verwenden? ich verwende PonyProg 2.07c Beta.

danke

christian
Angehängte Dateien:
OP #1769589
Lesenswert?

Hallo,

danke für die Nachricht.

Ich hab jetzt einen 10k Widerstand gegen VCC an Reset gehängt, zwar ist 
die Spannung am Reset PIN geringfügig auf 4,91 V gestiegen, aber auch 
beim Programmieren bleiben die 5 V und ändern sich nicht, auch nicht 
sehr kurz. (Wie lange wird der PIN auf Masse gezogen beim 
Programmiervorgang? Merkt man das mit einem Digitalmulti überhaupt?)

Fazit: Auch mit dem 10k Pullup lässt sich der Prozessor nicht 
programmieren. Als nächstes werd ich mal einen seriellen Adapter bauen 
und diesen dann statt des jetzigen Testen.

Christian
#1769593
Lesenswert?

Gregor schrieb:
> Hallo,
>
> ohne PulUp (10k gegen Vcc)auf dem RESET wird der Mega8 meines Wissens
> nicht laufen; und nicht programmierbar sein.

Genauso ist es. Der Kollektor des Transistors ist bei dem Programmer an 
Reset beschaltet  - ohne Pull-up kann das gar nicht funktionieren.

Edit: Zu spät. :)

@Spess: Ist der interne Pull-Up am Reset-Port von Anfang an aktiv? Im 
Datenblatt (ATmega48) steht bei der Beschreibung des Reset-Pins nichts 
dazu:

"RESET, Reset pin: When the RSTDISBL Fuse is programmed, this pin 
functions as a normal I/O
pin, and the part will have to rely on Power-on Reset and Brown-out 
Reset as its reset sources.
When the RSTDISBL Fuse is unprogrammed, the reset circuitry is connected 
to the pin, and the
pin can not be used as an I/O pin.
If PC6 is used as a reset pin, DDC6, PORTC6 and PINC6 will all read 0.
PCINT14: Pin Change Interrupt source 14. The PC6 pin can serve as an 
external interrupt
source."
Gast #1769605
Lesenswert?

Auch wenns öfters falsch beschrieben wird ändert sich doch nix daran: 
Der /RESET bleibt während des gesamten [1] (seriellen) 
Programmiervorgangs LOW [2]. D.h. man kann ihn durchaus per 
Krokoklemme/.. von Hand auf LOW ziehen.

Aaber: Das muss der Programmieradapter können. Wenn der das nicht 
schafft, dann ist irgendwo der Wurm drin. Entweder ein Kurzschluss am 
/RESET, ein defekter Programmieradapter, das Kabel ist falsch 
angeschlossen oder es hat keinen Durchgang.

Viel Erfolg!

[1] Ausnahme: Manch Software macht nach einem Chip-Erase nochmal einen 
'neuen' Reset.
[2] ..wo versteckt sich das Datenblatt zum m8? .. behelfsweise das vom 
m8A: http://atmel.com/dyn/resources/prod_documents/doc8159.pdf Kapitel 
24.8 'Serial downloading'.
OP #1769625
Lesenswert?

#include <avr/io.h> /* Standardregister */

// Hauptprogramm
int main(void)
{

  // Datenrichtung festlegen
  // DDRD = Gesamter B Port ist Ausgang
  DDRD = 0xff;

  // Alle LEDs an
  PORTD |= (1 << 0); /* PIN aktivieren */
  PORTD |= (1 << 1);
  PORTD |= (1 << 2);
  PORTD |= (1 << 3);
  PORTD |= (1 << 4);
  PORTD |= (1 << 5);
  PORTD |= (1 << 6);
  PORTD |= (1 << 7);

  return 0;
}

Christian
Gast #1769684
Lesenswert?

Christian W. schrieb:
> Wow geil ich habs grade geschafft.
>
> Hab alle Programme geschlossen, alles abgesteckt, neu gestartet,
>
> dann den Reset PIN auf Masse gelegt
>
> dann programmiert
>
> dann den Reset-Masse-PIN wieder von Masse genommen
>
> Alle LEDs leuchten!

Gratuliere.

Nun wissen wir, dass der Programmieradapter prinzipell funktioniert. 
Außer, dass der Reset Pin während des Programmierens nicht auf Low 
gezogen wird.

* Suche nochmal nach Unterbrechungen der Resetleitung vom Programmer zum 
AVR.
* Kurzschlüsse kann man ausschließen, denn sonst hätte dein manuelles 
auf Low ziehen nicht funktioniert (kurzschluss mit 5V) und andererseits 
hättest du nicht 4,9V im Betrieb messen können (bei Kurzschluss mit 
GND).

* Was du noch versuchen könntest ist einen 100nF Kondensator zwischen 
Reset und GND anzuschließen. Den verwende ich jedenfalls in allen meinen 
Schaltungen grundsätzlich, und man sollte es prizipell auch so machen.

MfG Gregor
Gast #1769849
Lesenswert?

Christian W. schrieb:
> was mich noch interessiert ist, warum manchmal meine leds angehen, und
> manchmal nicht?

Das mit dem Basiswiderstand kann schon stimmen. Was ich jedoch vermute 
ist, dass der AVR einfach keinen gründlichen Reset bekommt. Fürs 
Programmieren dürfte es ja mit nur einem Widerstand am Reset 
funktionieren. Für den Normalbetrieb würde ich dir jedoch sehr raten 
eine Serienschaltung aus 10k Pullup gegen Versorgungsspannung und einem 
100nF Kondensator gegen Masse zu verwenden. Der Kondensator hält den AVR 
nach dem Einschalten so lange im Reset- Zustand bis sich alle Spannungen 
stabilisiert haben. Das kann sich je nach dem welche Spannungsversorgung 
du verwendest einige ms Dauern. Wenn die Spannungsversorgung nicht sehr 
Spannungssteif ist erzeugt das Einschalten einen Spannungseinbruch. Wenn 
der AVR aber schon vom ersten Moment an anfängt sein Programm 
abzuarbeiten, wenn aber noch keine stabilen Spannungsverhältnisse 
vorherrschen kann es auch zu unerklärlichen Fehlfunktionen kommen. Zumal 
hast du auch an den Versorgungspins auf jegliche Pufferkondensatoren 
(100nF) verzichtet, was man sowieso nicht sollte.

MfG Gregor
OP #1770735
Lesenswert?

Hallo zusammen,

ich hab jetzt mal alle Basiswiderstände durch 8k6 ersetzt und außerdem 
an der +5V Leitung direkt am IC Sockel einen 0,1uF Elko angebracht... Es 
ändert sich aber leider nichts an der Situation dass einige LEDs dunkel 
bleiben.

Was mir auffällt: Ich habe ein Programm geschrieben, dass alle LEDs 
nacheinander aufleuchten lässt. LED Nr. 6 an Ausgang PD5 geht zwar an, 
erlischt aber in dem Moment wenn die nächste LED Nr. 7 angeht. Sowas hab 
ich aber nicht programmiert. Sehr komisch... LED1 geht überhaupt nicht 
an, lässt sich aber einschalten, wenn man mit einer Hilfsspannung an der 
Basis den Transistor mit der Hand durchschaltet.

Kann mir jemand sagen, wie ich über die Fuse-Bits den 4 MHz Oszillator 
aktiviere? Momentan rennt der IC noch mit 1 MHz. Vielleicht liegts ja 
daran, dass der externe Quarz "reinpfuscht"...

Danke

Christian
Gast #1770763
Lesenswert?

Ad Programm: herzeigen (komplett).

Ad Quarz: Nein, der pfuscht Dir nicht rein, weil der nicht mal getrieben 
wird :-)

Ad Fuses: Zuallerserst(!) ins Datenblatt schauen, was ∗genau∗ Du willst, 
dann zusammenstöpseln, wie die Fuses wohl aussehen müssen, nochmals auf 
Plausibilität prüfen, ggf. mit [1] abgleichen, dann Programmieren :-)

Es gibt auch Rechner, die behilflich sind, z.B. [2], aber unter keinen 
Umständen blind nutzen ohne vorher das Datenblatt gelesen zu haben - da 
sperrt man sich nämlich ganz leicht selbst aus.

HTH

[1] http://www.mikrocontroller.net/articles/AVR_Fuses
[2] http://www.engbedded.com/fusecalc/
OP #1770826
Lesenswert?

Hier wäre mal mein C-Code
1
// 8-Kanal-Lauflicht
2

3
#include <avr/io.h> 
4
#define F_CPU 1000000UL // Takt
5
#include <util/delay.h> 
6

7
int main(void) 
8
{ 
9
  // als Ausgang festlegen
10
    DDRD = 0xff; 
11

12
  // Warten vor dem Start
13
  _delay_ms(1000);
14

15
  // Pause zwischen den LEDs
16
  int zeit = 100;
17

18
  // Alles nacheinander einschalten
19
    PORTD |= (1 << PD1); _delay_ms(zeit);
20
    PORTD |= (1 << PD2); _delay_ms(zeit);
21
    PORTD |= (1 << PD3); _delay_ms(zeit);
22
    PORTD |= (1 << PD4); _delay_ms(zeit);
23
    PORTD |= (1 << PD5); _delay_ms(zeit);
24
    PORTD |= (1 << PD6); _delay_ms(zeit);
25
    PORTD |= (1 << PD7); _delay_ms(zeit);  
26
  
27
  // Warten
28
  _delay_ms(1000);
29

30
  // Alles ausschalten 
31
  PORTD &= ~(1 << PD1); 
32
    PORTD &= ~(1 << PD2); 
33
    PORTD &= ~(1 << PD3); 
34
    PORTD &= ~(1 << PD4);  
35
    PORTD &= ~(1 << PD5); 
36
    PORTD &= ~(1 << PD6);  
37
    PORTD &= ~(1 << PD7); 
38

39
    // Warten
40
  _delay_ms(500);
41

42
  // Pause zwischen den LEDs 
43
  int pause = 100;
44

45
    // Programmschleife
46
    while(1) 
47
      { 
48

49
        PORTD |= (1 << PD0); //  aktivieren 
50
            _delay_ms(pause); 
51
            PORTD &= ~(1 << PD0); //  deaktivieren 
52

53
            PORTD |= (1 << PD1); //  aktivieren 
54
            _delay_ms(pause); 
55
            PORTD &= ~(1 << PD1); //  deaktivieren 
56
    
57
            PORTD |= (1 << PD2); //  aktivieren 
58
            _delay_ms(pause); 
59
            PORTD &= ~(1 << PD2); //  deaktivieren 
60

61
            PORTD |= (1 << PD3); //  aktivieren 
62
            _delay_ms(pause); 
63
            PORTD &= ~(1 << PD3); //  deaktivieren 
64

65
            PORTD |= (1 << PD4); //  aktivieren 
66
            _delay_ms(pause); 
67
            PORTD &= ~(1 << PD4); //  deaktivieren 
68

69
            PORTD |= (1 << PD5); //  aktivieren 
70
            _delay_ms(pause); 
71
            PORTD &= ~(1 << PD5); //  deaktivieren 
72

73
            PORTD |= (1 << PD6); //  aktivieren 
74
            _delay_ms(pause); 
75
            PORTD &= ~(1 << PD6); //  deaktivieren 
76

77
            PORTD |= (1 << PD7); //  aktivieren 
78
            _delay_ms(pause); 
79
            PORTD &= ~(1 << PD7); //  deaktivieren 
80

81
            PORTD |= (1 << PD6); //  aktivieren 
82
            _delay_ms(pause); 
83
            PORTD &= ~(1 << PD6); //  deaktivieren 
84

85
            PORTD |= (1 << PD5); //  aktivieren 
86
            _delay_ms(pause); 
87
            PORTD &= ~(1 << PD5); //  deaktivieren 
88

89
            PORTD |= (1 << PD4); //  aktivieren 
90
            _delay_ms(pause); 
91
            PORTD &= ~(1 << PD4); //  deaktivieren 
92

93
            PORTD |= (1 << PD3); //  aktivieren 
94
            _delay_ms(pause); 
95
            PORTD &= ~(1 << PD3); //  deaktivieren 
96

97
            PORTD |= (1 << PD2); //  aktivieren 
98
            _delay_ms(pause); 
99
            PORTD &= ~(1 << PD2); //  deaktivieren 
100

101
            PORTD |= (1 << PD1); //  aktivieren 
102
            _delay_ms(pause); 
103
            PORTD &= ~(1 << PD1); //  deaktivieren 
104
              
105
    } // Ende while
106

107
    return 0;
108

109
} // Ende main
#1771029
Lesenswert?

So auf die Schnelle:

Alles aus- bzw. einschalten könntest Du natürlich auch einfacher mittels
1
//aus
2
PORTD = 0x00;
3
//ein
4
PORTD = 0xff;

Die Delay-Funktionen erwarten ein Double als Argument (wenn ich mich 
recht erinnere).
Hast Du beim Kompilieren eine Optimierungsstufe eingestellt?

In der while-Schleife gehen natürlich die jeweiligen LEDs aus, wenn Du 
die nächste einschaltest.

Wie sind die LEDs verschaltet? Kann man an Deinem Schaltplan oben ja 
nicht sehen.
OP #1771049
Lesenswert?

Hallo, das Wort Optimierungsstufe glaub ich klingt schon mal sehr gut 
für mein Problem, ich weiß aber nicht was da eingestellt ist, ich hab 
alles auf den Einstellungen wie bei der Programm-Installation belassen. 
Kann man auch ohne Optimierung den Code Hexen? Würd ich nämlich gerne 
mal testen und sehen was dabei rauskommt.

Das was konkret nicht passt, ist folgendes:

Ich programmiere:
1
// Alles nacheinander einschalten
2
    PORTD |= (1 << PD1); _delay_ms(zeit);
3
    PORTD |= (1 << PD2); _delay_ms(zeit);
4
    PORTD |= (1 << PD3); _delay_ms(zeit);
5
    PORTD |= (1 << PD4); _delay_ms(zeit);
6
    PORTD |= (1 << PD5); _delay_ms(zeit);
7
    PORTD |= (1 << PD6); _delay_ms(zeit);
8
    PORTD |= (1 << PD7); _delay_ms(zeit);

Und der Controller macht das hier mit den 8 LEDs:

AUS-EIN-EIN-EIN-EIN-AUS-EIN-EIN

Wie gesagt, wenn die while-Schleife durchläuft, funktionieren alle 8 
LEDs ohne Probleme.

Anbei noch eine Grafik, wie meine LEDs am Controller hängen.

Christian
Angehängte Dateien:
#1771097
Lesenswert?

Christian W. schrieb:
> Und der Controller macht das hier mit den 8 LEDs:
>
> AUS-EIN-EIN-EIN-EIN-AUS-EIN-EIN
>
> Wie gesagt, wenn die while-Schleife durchläuft, funktionieren alle 8
> LEDs ohne Probleme.

PD0 programmierst Du ja nicht, insofern ist das erste AUS erklärbar. Das 
andere ist durch den Code nicht wirklich erklärbar, prüfe daher nochmal 
die Verschaltung an dem Pin.

Die Optimierungsstufe des Compilers schaltet man in den 
Compiler-Optionen ein (ergibt dann beim Aufruf des gcc -O0, -O1, -O2 
oder -O3). Ohne Optimierung kann der Compiler die Delay-Zyklen nicht 
bestimmen.
OP #1777246
Lesenswert?

Hallo zusammen,

hab alles im Griff. Die Led Nr. 6 leuchtete deswegen nicht mehr wenn Nr. 
7 anging, weil hinten auf der Platine ein Lötfehler war. Von der einen 
Led war der Plus mit dem Minus der benachbarten Led verbunden. Das 
erklärt auch, warum Led Nr. 6 zwar alleine leuchtete, aber dann ausging, 
wenn alle anderen auch leuchteten, am Minuspol war plötzlich 
Plus-Potential und durch die Led floss kein Strom mehr.

Von der Programmierung her klappt jetzt alles einwandfrei. Hab heute den 
originalen AVR USB Programmieradapter bekommen. Der billige serielle 
Adapter den ich zu erst verwendet habe ist nicht zu gebrauchen. Da muss 
man immer per Hand den Reset Pin auf Null ziehen, das ist Sch**ße...

Vielen Dank für alle Tipps. War sehr hilfreich.

Viele Grüße

Christian
Gast #1786812
Lesenswert?

Hallo zusammen,

Bei seriellem Programmieradapter wird Reset-Pin mit Hilfe einer 
Transistor zu GND gezogen. d.H. auf dem Traget sollte ein Pull-up 
Widerstand vorhanden sein. Die grösse sollte im Bereich 3k3..10k liegen. 
Falls Target ist so konzipiert, dass nach dem Programmieren RESET-Pin 
als Ausgang verwendet wird - ein serieller Widerstand zwischen 
ISP-Stecker und Reset-Pin ist ein pflicht. Sonst wird Transistor beim 
Programmieradapter zerstört (Gleiches passiert, wenn Reset-Pin extern zu 
VCC Verbunden ist/wird).

MfG Konstantin

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren