Forum: Mikrocontroller und Digitale Elektronik AVR/Arduino Eigenbau nimmt keine Programme mehr an (ATmega168)


von Stormxy (Gast)


Angehängte Dateien:

Lesenswert?

Hallo (hoffentlich) liebe Leute,
ich wende mich mal an euch, da ich mit meinem (zugegebener Maßen stark 
beschränktem) Latein am Ende bin :/

Folgendes:
Ich habe von einem Schülerwettbewerb hier noch ein Arduino kompatiblen 
Bausatz mit vier Stellen 7 Segment LED Display rumliegen gehabt und 
dachte mir die Tage der ließe sich doch als Digitaluhr verwenden.

Habe mir dafür die Timerinterrupts etwas näher angesehen und es dabei 
irgendwie geschafft durch ein Programmupload den Mikrocontroller 
unprogrammierbar zu machen. Er startet wohl noch (es blinken zufällige 
LED Segmente auf der Anzeige auf) und ist auch resetbar, aber nimmt 
keine Programme mehr über den Arduino Upload entgegen. Auf den seriellen 
Leitungen sind zwei LEDs verlötet die die Aktivität anzeigen, während 
des Uploads blinken diese normalerweise erst kurz und leuchten dann fast 
dauerhaft bis der Mikrocontroller wieder mit dem neuen Programm startet, 
nun jedoch blinken sie kurz, leuchten dann viel zu kurz dauerhaft und 
der Mikrocontroller zeigt wieder Unsinn auf der Anzeige an. Arduino gibt 
nach etwas Wartezeit dann auch eine entsprechende Fehlermeldung aus:
1
avrdude: stk500_paged_write(): (a) protocol error, expect=0x14, resp=0x64
2
avrdude: stk500_cmd(): programmer is out of sync

Das alles wäre sicherlich kein Problem, wenn ich über entsprechende 
Hardware und das zugehörige Wissen verfügen würde, aber naja…

Der „Mikrocontroller“ (also die Schaltung) ist ein Bausatz von der Intel 
Leibniz Challenge 2012 (mittlerweile leider eingestellter 
Schülerwettbewerb), die Einzelteile bekam man zugeschickt und wurden auf 
einem Steckbrett selbst (nach Anleitung) zusammengebaut. Im Kern werkelt 
ein ATmega168-20PU, der von einem externen 16MHz Quarz versorgt wird, 
Strom gibt’s von einem USB-TTL-Konverter, der wohl extra für den 
Wettbewerb hergestellt wurde, dementsprechend habe ich keine Ahnung, was 
der vielleicht noch alles beim Programmieren macht. Ein ähnliches 
Problem ergibt sich beim Mikrocontroller, wie ich mir mittlerweile 
denken kann, musste der ja mit einem Bootloader vorprogrammiert worden 
sein, ob überhaupt und wenn ja mit welchem weiß ich aber leider nicht. 
Jedenfalls ist die ganze Sache kompatibel mit dem Arduino Nano mit 
Atmega168. Ich häng mal das Schaltbild an.

Kommen wir also zur Software, programmiert habe ich das Teil mit 
Arduino. Ich bin mir ziemlich sicher, dass es irgendwie mit dem letzten 
Programmupload zusammenhing, den das Programm machte nicht was es soll, 
und sofort danach ging nichts mehr, an der Hardware hatte ich zudem 
nichts verändert. Das Programm war mehr oder weniger ein Testprogramm um 
ein wenig mit dem Timerinterrupt rumzuspielen. Es soll abwechselnd zwei 
unterschiedliche lange Zeiten bis zum nächsten Interrupt einstellen, 
damit ich dadurch später durch „Leerzyklen“ beim Multiplexen der Anzeige 
(also zwischenzeitlich immer alle Stellen ausschalten) die Helligkeit 
der Anzeige verringern kann.

Wie gesagt über großartige Hardware verfüge ich nicht (insbesondere 
nicht über einen separaten Programmer), vielleicht ließe sich höchstens 
noch was basteln (z.B. http://arduino.cc/en/Hacking/ParallelProgrammer 
wofür mir jedoch noch ein Parallelkabel fehlt).
Ursprünglich dachte ich ja wirklich das Programm sei Schuld, aber 
eigentlich sollte der Bootloader ja unabhängig vom Programm sein (und 
Arduino Idiotensicher), also muss ich es ja irgendwie geschafft haben 
den Bootloader zu beschädigen? Ich bin echt verwirrt :S
Also wenn ich das Teil wieder zum laufen bekommen könnte, wäre das echt 
super! Ich finde die Mikrocontroller Programmierung nämlich eigentlich 
ganz interessant, aber habe jetzt auch keine großen Projekte vor, dass 
es sich lohnt extra Hardware anzuschaffen.  Super wär‘s auch wenn ihr 
mir vielleicht auch helfen könntet zu verstehen, was wohl beim 
Programmieren auf dem Board passiert (früher dachte ich immer der 
USB-TTL-Konverter würde die Arbeit erledigen, aber das macht ja wohl 
doch der Bootloader des uC selbst oder doch nicht?).

Vielen Dank im Voraus und sorry für den Roman
Stormxy




PS: Hier mal mein letzte Code, der den uC abgeschossen hat:
1
//Die ordnet nur den IOxx den entsprechenden richtigen Pin zu
2
#include <IOpins.h>
3
4
#include <avr/io.h>
5
#include <avr/interrupt.h>
6
7
8
// 8 Segmente der Siebensegmentanzeige
9
//     ___        A: oben
10
//    | A |       F: oben links
11
//  F |___| B     B: oben rechts
12
//    | G |       G: mitte
13
//  E |___| C     E: unten links
14
//      D   . DP  C: unten rechts
15
//                D: unten
16
//                DP: Dezimalpunkt
17
byte IOSegmente [8] = {
18
IO23,  //   A: oben
19
IO24,  //   B: oben rechts
20
IO25,  //   C: unten rechts
21
IO26,  //   D: unten
22
IO6 ,  //   E: unten links
23
IO11,  //   F: oben links
24
IO12,  //   G: mitte
25
IO13,  //  DP: Dezimalpunkt
26
};
27
28
// Position der 4 Siebensegmentanzeigen
29
//     ___    ___    ___    ___
30
//    |   |  |   |  |   |  |   |
31
//    |___|  |___|  |___|  |___|
32
//    |   |  |   |  |   |  |   |
33
//    |___|. |___|. |___|. |___|.
34
//      1      2      3      4
35
byte IOAnzeigen [4] = {
36
IO19,  // Anzeige 1
37
IO18,  // Anzeige 2
38
IO17,  // Anzeige 3
39
IO14,  // Anzeige 4
40
};
41
42
PROGMEM prog_uchar disChars[64] = {//Hab ich zum Posten bischen gekürzt (...)
43
//ABCDEFGDP      0=AN 1=AUS
44
 B00000011, // 0
45
 B10011111, // 1
46
 B00100101, // 2
47
 B00001101, // 3
48
 B10011001, // 4
49
 B01001001, // 5
50
 B01000001, // 6
51
 B00011111, // 7
52
 B00000001, // 8
53
 B00001001, // 9
54
 
55
//...
56
 
57
 B11111111, //  keine Anzeige / Leerzeichen
58
};
59
60
byte disaktiveDisplay = 0;
61
byte cou=0;
62
int cou2=0;
63
boolean protectISR=true;
64
boolean state=true;
65
double onPercent=1;
66
67
ISR(TIMER1_COMPA_vect) {
68
  if (!protectISR) 
69
  sei();
70
  if (state) {
71
  cou2++;
72
  if (cou2==1000) {
73
    cou2=0;
74
    cou=(cou+1)%7;
75
  }
76
77
  //---Anzeigen
78
  for(byte i=0; i<4;i++) { // Deaktiviere alle nicht benoetigten Anzeigen
79
    digitalWrite(IOAnzeigen[i],HIGH);
80
  }
81
82
  for(byte i=0; i<7;i++) {   // Aktiviere Segmente
83
    digitalWrite(IOSegmente[i], pgm_read_byte_near(disChars+disaktiveDisplay+cou) & (128 >> i));
84
  }
85
86
  digitalWrite(IOAnzeigen[disaktiveDisplay],LOW); // Aktiviere eine Anzeige
87
88
  disaktiveDisplay=(disaktiveDisplay + 1) % 4;
89
  
90
  setInteruptTime(0.004*onPercent  ,!protectISR);
91
  } else {
92
    for(byte i=0; i<4;i++) { // Deaktiviere alle nicht benoetigten Anzeigen
93
      digitalWrite(IOAnzeigen[i],HIGH);
94
    }
95
    setInteruptTime(0.004*(1-onPercent)  ,!protectISR);
96
  }
97
  state=!state;
98
  if (protectISR)
99
  sei();
100
  //Serial.println(TCNT1)
101
}
102
103
104
void disSetup() {  
105
    cli();
106
      // initialize Timer1
107
    TCCR1A = 0;     // set entire TCCR1A register to 0
108
    TCCR1B = 0;     // same for TCCR1B
109
 
110
    // set compare match register to desired timer count:
111
    //16Mhz Clock
112
    double time=4; //4,194304 max!
113
    //OCR1A =int(time*16*1000/1024*1000-1); 
114
    OCR1A = (unsigned int) (time*15625-1); 
115
    // turn on CTC mode:
116
    TCCR1B |= (1 << WGM12);
117
    // Set CS10 and CS12 bits for 1024 prescaler:
118
    TCCR1B |= (1 << CS10);
119
    TCCR1B |= (1 << CS12);
120
    // enable timer compare interrupt:
121
    TIMSK1 |= (1 << OCIE1A);
122
    // enable global interrupts:
123
    sei();
124
  
125
  // -------------------------------------------
126
  // Konfigurieren der vier Anzeigen als Ausgaenge
127
  // -------------------------------------------
128
  for (byte a=0; a<4; a++) {
129
    pinMode(IOAnzeigen[a], OUTPUT);
130
  }
131
  // -------------------------------------------
132
  // Konfigurieren der 8 Segmente als Ausgaenge
133
  // -------------------------------------------
134
  for (byte a=0; a<8; a++) {
135
    pinMode(IOSegmente[a], OUTPUT);
136
  }
137
  digitalWrite(IOSegmente[7], HIGH);  //DP abschalten
138
}
139
140
141
void setup() {
142
disSetup();
143
Serial.begin(9600);
144
setInteruptTime(0.004);
145
}
146
147
148
void loop() {
149
}
150
151
void setInteruptTime(double time, boolean disableInterupts) {
152
  if (disableInterupts)
153
    cli();
154
  if (time > 0.000064) 
155
  OCR1A = (unsigned int) (time*15625-1); 
156
  else 
157
  OCR1A = 2; //Bin mir nicht mehr sicher ob hier beim letzen Upload nicht doch vielleicht 1 oder eine andere Zahl stand :S
158
159
  if(TCNT1 >= OCR1A) {
160
    TIMER1_COMPA_vect(); //ISR manuell Auslösen
161
    TCNT1 = 0; // Timer resten sodass er 
162
  }
163
  if (disableInterupts)
164
    sei();
165
}
166
167
void setInteruptTime(double time) {
168
  setInteruptTime(time, true) ;
169
}

von tomske (Gast)


Lesenswert?

Hi, versuch doch mal, nach der Fehlermeldung zu suchen... Ich habs mit 
dem Schnipsel "protocol error, expect=0x14, resp=0x64" und "arduino" 
probiert und bekomme einen ganzen Sack voller Möglichkeiten, die aber 
jeweils wieder Fragen an Dein Setup aufwerfen... (Version der IDE, Größe 
des Programms usw.) Vielleicht ist da ein Hinweis für Dich dabei.

von Ert (Gast)


Lesenswert?

Bei mir sind schon einige FTDI-Chip kaputt gegangen, evtl ist nur das 
die Fehlerquelle...

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Stormxy schrieb:
> //Die ordnet nur den IOxx den entsprechenden richtigen Pin zu
> #include <IOpins.h>
>
> #include <avr/io.h>
> #include <avr/interrupt.h>

M.E. solltest du erst die /avr/io.h einbinden und dann deine 
Pindefinitionen. Allerdings weiss ich ja nicht, wie du die Definitionen 
gemacht hast. Da kann schon mal was schief gehen.

: Bearbeitet durch User
von Stormxy (Gast)


Lesenswert?

Danke für die Antworten,
geht leider immer noch nicht :/

Ert schrieb:
> Bei mir sind schon einige FTDI-Chip kaputt gegangen, evtl ist nur das
> die Fehlerquelle...
Kann ich leider schlecht überprüfen, hab aber mal die Spannung, die er 
abgibt gemessen (waren ~4,8V sollte also passen) und RX und TX 
kurzgeschlossen (bekam im Terminal alles was ich dem Chip gesendet habe 
genauso zurück), also würde ich sagen der sollte es nicht sein, wäre 
auch ein etwas plötzliches ableben des Chips.

Matthias Sch. schrieb:
> M.E. solltest du erst die /avr/io.h einbinden und dann deine
> Pindefinitionen. Allerdings weiss ich ja nicht, wie du die Definitionen
> gemacht hast. Da kann schon mal was schief gehen.
Gut möglich. Die IOpins.h wurde beim Wettbewerb als Material gestellt 
und daher habe ich die immer noch eingebunden, definitionen sind ganz 
simpel, z.B.
1
#ifndef ___IOpins____
2
#define ___IOpins____
3
4
#define IO2  0     // Serial RX
5
#define IO3  1     // Serial TX
6
#define IO4  2     // Switch 3
7
.......
8
#define SWITCH_PRESSED 0
9
#define SWITCH_RELEASED 1
10
11
#endif
Jedenfalls hilft mir das beim Problem nicht viel, da ich nichtmal mehr
1
void setup() {}
2
void loop() {}
oder generell irgendwas hochgeladen bekomme :/

tomske schrieb:
> Hi, versuch doch mal, nach der Fehlermeldung zu suchen... Ich habs mit
> dem Schnipsel "protocol error, expect=0x14, resp=0x64" und "arduino"
> probiert und bekomme einen ganzen Sack voller Möglichkeiten, die aber
> jeweils wieder Fragen an Dein Setup aufwerfen... (Version der IDE, Größe
> des Programms usw.) Vielleicht ist da ein Hinweis für Dich dabei.
Danke, daran habe ich garnicht dran gedacht mal mit der konretten 
Meldung zu googlen (hab nur mit einer Beschreibung gegoogelt und war 
recht erfolglos), aber auch damit bisher wenig Erfolg...
Immerhin habe ich es dadurch jetzt geschaft mal eine LED an den ATmega 
Pin anzuschließen die der Arduino Bootloader verwendet, die 
leuchtet/blinkt jetzt beim Boardreset und Programmierversuchen, aber 
wirklich schlau werde ich auch nicht drauß.

Hoffe also weiter auf Ideen und Erklärungen!

von Jürgen (Gast)


Lesenswert?

Ich habe mal ein Arduino kompatibles Board weggeschmissen weil ich nicht 
mehr daran gedacht hatte, das DebugWire an war und ich es nicht 
ausgeschaltet hatte. Allerdinsg nutze ich die Boards nicht mit der 
Arduino IDE sondern mit AVR-Studio.
Bin schier daran verzweifelt in meiner unerfahrenheit. :D
Als dann die Müllabfuhr da war und den entsorgte kam der 
nachvollziehbare und getestete Geistesblitz.

von Stormxy (Gast)


Lesenswert?

Habe das Problem mittlerweile selbst in den Griff bekommen.
Nachdem es eigentlich nur am Bootloader liegen konnte, habe ich nun doch 
den Eigenbau Parallel Programmer gebastlelt und an meinen alten Rechner, 
der zum Glück noch über eine Parallel Schnittstelle verfügt, 
angeschlossen. Musste zwar in 4 unterschiedlichen PDFs wühlen um die 
Verkabelung auch sicher richtig hinzubekommen und noch paar andere 
Hindernisse überwinden, aber am Ende hat tatsächlich alles geklappt und 
Arduino konnte den Bootloader neu auf den Atmega schreiben, womit dieser 
nun wieder seine Arbeit verrichtet.

Wie ich es geschafft habe den Bootloader nur mittels Arduino überhaupt 
zu beschädigen, ist mir jedoch immer noch ein Rätsel :S

Naja wenigstens ist mir jetzt viel klarer wie der ganze 
Programmiervorgang eigentlich abläuft :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.