Forum: Compiler & IDEs Vorstellung und gleich eine Frage


von Christian W. (bandit83)


Angehängte Dateien:

Lesenswert?

Hallo,

zuerst einmal möchte ich mich vorstellen, meine Name ist Christian komme 
aus der Gegend um Bremen und schreibe gerade in den letzten Zügen meine 
Diplomarbeit.

Nach wochenlagem stillen mitlesen ist es aber jetzt doch soweit, dass 
ich bei meinem Problem so noch keine Lösung gefunden habe. Wie Paul 
Panzer es ausdrücken würde, "es jet sich um folgendes.."

Spaß beiseite - zu meinem Problem: Ich nutze in meiner Diplomarbeit 
einen ATMega32 Controler, der über eine selbstgeschrieben Software einen 
Servoverstärker mit Pulsen ansteuern soll. Dies funktioniert alles auch 
wunderbar, jedoch sollen/müssen jetzt angefahrene Punkte im Speicher 
dauerhaft abgelegt werden, sodass sie nach dem Reseten und/oder 
wiedereinschalten noch vorhanden sind. Dafür wollte ich das eeprom 
nutzen. Zum Programmieren nutze ich WinAvr 20090313 und die Sprache C++. 
Im Makefile habe ich den Controller ausgewählt und die Optimierung auf 
Stufe "s" gestellt.

Nun stoße ich jedoch an meine "Grenzen". Habe bereits sämtliche 
"Befehlsvarianten" versucht, aber irgendwie mag er entweder nichts ins 
eeprom schreiben, oder aber nicht auslesen. Im Anhang seht ihr einen 
Ausschnitt aus dem Programm (genauer gesagt die Teile die mir 
Kopfzerbrechen machen).

Hintergedanke bei dem Unterprogramm "teach" ist der, dass der Benutzer 
manuell einen Punkt anfahren kann und ihn dann mit hilfe der Tasten 1-8 
abspeichern kann. An sich läuft das Programm auch durch, er schreibt 
denke ich nur nichts ins eeprom. In dem Unterprogramm "manuell" möchte 
ich zu testzwecken die Punkte "anfahren" lassen. Da ich dies jedoch 
vorab virtuell machen möchte, soll er mir in dem Unterprogramm 
"verfahren" über eine Schleife für die Punkte die jeweiligen "tp" Werte 
ausgeben (tp1 = Punkt 1 etc.). Dies macht er auch wunderbar, jedoch für 
beide Punkte 256 mal. Eigentlich sollte er es ja nur so oft machen, wie 
ich ihm es vorher abgespeichert habe.

Ich hoffe ihr könnt mir helfen, bin schon bestimmt seit 6 Wochen oder 
mehr am suchen und verzweifeln. Bedanken möchte ich mich auch 
schoneinmal im vorfeld - sollte das ganze Programm von "nöten" sein, 
stelle ich es natürlich sofort online, nur irgendwie habe ich so das 
Gefühl, dass es nur ein kleines Problem mit großer Wirkung ist.

Beste Grüße und nochmals danke.
Christian

von Karl H. (kbuchegg)


Lesenswert?

Christian W. schrieb:

> Ich hoffe ihr könnt mir helfen, bin schon bestimmt seit 6 Wochen oder
> mehr am suchen und verzweifeln.

6 Wochen und du bist noch nicht ein einziges mal auf den Gedanken 
gekommen in die Doku des avr-gcc zu sehen um rauszufinden, dass es dort 
fertige funktionierende Funktionen zum EEPROM schreiben/lesen gibt, bzw. 
hier ins Tutorial zu schauen um rauszufinden wie man sie verwendet?

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#EEPROM

> aber irgendwie mag er entweder nichts ins
> eeprom schreiben, oder aber nicht auslesen

Wie könnte man wohl rausfinden, welches der beiden Szenarien zutrifft?


Du musst dringend an deiner Kompetenz arbeiten. Sonst sagt dir dein 
erster Arbeitgeber nach der Diplomarbeit: Sorry, aber so jemanden können 
wir nicht brauchen.

von Karl H. (kbuchegg)


Lesenswert?

1
        case CR : goto eins;      //bei Enter - zum abspeichern springen

und Konsorten.

Wenn du dich bei mir bewerben solltest und ich schau mir deine 
Diplomarbeit an, bist du spätestens nach dieser Zeile automatisch vom 
Vorstellungsgespräch ausgeschlossen.

von Christian W. (bandit83)


Lesenswert?

Hallo,

an meiner Kompetenz liegt es nicht, habe mir das Tutorial und die Hilfe 
als erstes zu Herzen genommen nachdem ich ein wenig die Suche benutzt 
habe, jedoch brachte diese leider auch keinen Erfolg (bin zwar vom 
Rübenlaster gefallen, aber bin nicht auf dem Kopf gelandet!). Selbst 
mein Betreuer an der Uni weiß im Moment keine Lösung - soviel zum Thema 
Kompetenz.

Was das Bewerben bei einer Firma angeht (und meinen Programmierstil) - 
dies steht hier doch gar nicht zur Debatte und davon abgesehen bewerbe 
ich mich auch garantiert nie als Programmierer (bin Maschinenbauer und 
da beschäftigt man sich mit anderen Sachen als Programmieren von 
Controllern).

von Karl H. (kbuchegg)


Lesenswert?

Christian W. schrieb:

> Rübenlaster gefallen, aber bin nicht auf dem Kopf gelandet!). Selbst
> mein Betreuer an der Uni weiß im Moment keine Lösung - soviel zum Thema
> Kompetenz.

Spricht nicht gerade für deinen Betreuer.
Eigentlich hätte der sagen müssen:
schmeiss das meiste vom Code weg und fang nochmal von vorne an.
Aber achte diesmal an eine strukturierte Vorgehensweise und lies dir 
vorher nochmal durch, was du im Studium über Pointer gelernt hast.

> (bin Maschinenbauer und
> da beschäftigt man sich mit anderen Sachen als Programmieren von
> Controllern).

Es wird mir immer ein Rätsel bleiben, warum man sich für wichtige 
Prüfungen Themen sucht, bei denen man nur auf die Schnauze fallen kann. 
Wenn du Maschinenbauer bist, so ist das eine Sache. Aber dann nimm dir 
keine Diplomarbeit, bei der du programmieren musst, wenn du das vorher 
noch nie ausreichend gemacht hast.

Ehrlich gesagt: In deinem Code gibt es einige Problemkreise. Einer davon 
ist zb das ganze Drumherum, das um peep1 und peep2 kreist.

Nichtsdestotrotz: schmeiss deine eigenen EEPROM Sachen raus und ändere 
so um, wie du es im Tutorial siehst. Sowohl die Definition der 
'Variablen' die im EEPROM landen sollen als auch die Funktionen die die 
Werte dieser Variablen lesen und schreiben.

Dann bedienst du dein Programm so, dass etwas ins EEPROM geschrieben 
werden müsste und benutzt das AVR-Studio oder welches Programm du sonst 
zum Brennen deines Programms benutzt, um das EEPROM auszulesen (das weiß 
nämlich mit Sicherheit wie man das macht) und siehst als erstes nach, ob 
deine Werte im EEPROM gelandet sind oder nicht. Damit hast du zumindest 
schon mal abgeklärt ob das Problem beim Schreiben oder beim Lesen der 
Werte entsteht. Wie es dann weitergeht, hängt natürlich damit zusammen 
ob es ein Schreiben oder Lesen-Problem ist, aber die Lösung wird mit 
Sicherheit über den Weg führen, sich im Programm noch ein paar 
zusätzliche Ausgaben einzubauen, die dir als Beobachter mitteilen was 
das Programm gerade macht und mit welchen Werten es hantiert.

von Bernd (Gast)


Lesenswert?

Die EEPROM write und read Routine ist soweit ok, hast dumal versucht den 
Speicher zurückzulesen oder verlierst du den Inhalt nach dem ein / 
ausschalten ?

@ Karl Heinz, warum sollte man immer die GCC Lib verwenden ? ich seh 
dafür keinen Grund.

von Karl H. (kbuchegg)


Lesenswert?

Bernd schrieb:

> @ Karl Heinz, warum sollte man immer die GCC Lib verwenden ? ich seh
> dafür keinen Grund.

Sie ist da und sie funktioniert.
Umgekehrt wird ein Schuh daraus. Es gibt keinen Grund sie nicht zu 
verwenden :-) Vor allen Dingen dann nicht, wenn Programmieren nicht der 
Brotberuf des Programmierers ist.

von Bernd (Gast)


Lesenswert?

Das seh ich anders... z.B. wenn man den Compiler wechselt beginnt man 
von vorn aber das ist eher Geschmackssache. Jedenfalls hat er den EEPROM 
Code aus den Atmel notes und die Routine ist ebenfalls ok.

von Karl H. (kbuchegg)


Lesenswert?

Bernd schrieb:
> Das seh ich anders... z.B. wenn man den Compiler wechselt beginnt man
> von vorn aber das ist eher Geschmackssache. Jedenfalls hat er den EEPROM
> Code aus den Atmel notes und die Routine ist ebenfalls ok.

Das mag ja alles sein.
Aber wenn er sich ganz einfach an die gcc Routinen gehalten hätte und 
sie so verwendet hätte wie es im Tutorial beschrieben ist, dann würde er 
soetwas nicht machen
1
int *peep1=(int*)(12345);
2
int *peep2=(int*)(54321);
3
4
.....
5
  eeprom_write(*peep1, zsp);
6
.....
7
  eeprom_write(*peep2, zsp);

Fazit: Ein Fehler der nur dadurch entsteht, weil der Programmierer wider 
mal cleverer ist, als diejenigen die ihm die Library zusammengestellt 
haben.

von Peter D. (peda)


Lesenswert?

Ich sehe auch keinen Grund, wegen dem EEPROM gleich rumzugrollen.
Die Routine entspricht dem Datenblatt, also wirds daran nicht liegen.

Die EEPROM Lib-Funktionen sind außerdem nicht der Brüller, da sie 
erstmal nen indirekten Call basteln (unnötiger Code-, Stackverbrauch).

Der Fehler ist woanders.

Ich hab allerdings keine Lust erst ein Textfile runterladen zu müssen 
und in *.c umzubenennen, um es formatiert ansehen zu können.


Peter

von Karl H. (kbuchegg)


Lesenswert?

Peter Dannegger schrieb:
> Ich sehe auch keinen Grund, wegen dem EEPROM gleich rumzugrollen.
> Die Routine entspricht dem Datenblatt, also wirds daran nicht liegen.

Ich habe auch nicht behauptet, dass die Routinen fehlerhaft sind.
Aber die Verwendung!

> Der Fehler ist woanders.

Ja.
In der Art und Weise wie er Funktionen, die er nicht versteht, 
verwendet.
(Siehe oben)

von Ulrich (Gast)


Lesenswert?

Bernd schrieb:
>warum sollte man immer die GCC Lib verwenden ? ich seh
>dafür keinen Grund.

Warum sollte man mit dem Bus fahren, laufen tuts doch auch.
Sorry, aber diese "wir erfinden das Rad zum tausendsten Mal"-Leute
habe ich echt gefressen.

von Bernd (Gast)


Lesenswert?

Cool bleiben :-) ich habe übrigens auch keine Lust durch den Code zu 
stapfen aber ich seh es eher wie Peter. Die ganzen Liberfinder sind mir 
ein Greuel denn ich schreibe nicht nur Programme für AVR's und den 
Compiler kann ich mir zuweilen auch nicht aussuchen. Also verwende ich C 
konformen Code wo es geht und nicht irgendwelche gebastelten Lib 
Funktionen.

Das Ganze muß aber nicht zu einem Glaubenskrieg führen :-)

Verwende mal irgendwas davon auf dem IAR Compiler für die gleichen ATMEL 
Käfer... viel Spaß :-)

von Bernd (Gast)


Lesenswert?

Angenommen wir haben 3 verschiedene Variablen und wollen die mit deiner 
Routine Abspeichern. Dann sieht das so aus.
1
void SaveMyEEPRomData (void)
2
{
3
    uint8_t i;
4
5
    cli ();
6
    char *ptr = (char*) & ersteVariable;     // 4 Byte uint32_t
7
    for (i = 0; i < 4; i++) {
8
        EEPRomWrite (i, *ptr++);
9
    }
10
    EEPRomWrite (0x05, zweiteVariable);      // 1 Byte uint8_t
11
12
    EEPRomWrite (0x06, dritteVariable);      // 2 Byte uint16_t
13
    EEPRomWrite (0x07, dritteVariable >> 8);
14
    sei ();
15
}
Hoffe das bringt Licht in die Sache :-)

von Thomas (Gast)


Lesenswert?

Bernd schrieb:
>Verwende mal irgendwas davon auf dem IAR Compiler für die gleichen ATMEL
>Käfer... viel Spaß :-)

Warum sollte man das tun?
Wechselt ihr die Compiler so oft wie die Unterhosen? ;)
Wenn man einmal den für sich optimalen Compiler gefunden hat, dann 
bleibt man auch dabei. Und eine Portierung auf einen anderen Prozessor 
bedeutet so oder so fast immer ein Neuschreiben des Codes.

von Bernd (Gast)


Lesenswert?

>> Wechselt ihr die Compiler so oft wie die Unterhosen?

Ja.

von Dirk B. (sharandac)


Lesenswert?

Hallo,

für mich wäre als Frage noch offen, das wenn man davon ausgeht das die 
Routinen richtig geschrieben sind und funktionieren, wieso er dann die 
Daten nicht behält. Hast du mal versucht die Daten vor einem Reset 
wieder einzulesen? Wenn das geht wäre die Frage, hast du BOD aktiviert? 
Das ist besonders wichtig, da es sonst schnell geht das man sich das 
EEprom bei Spannungsabfall zerlegt. Zweite Frage wäre, hast du mal 
nachgesehen ob die beim neu beschreiben des Flashes nicht jedes mal auch 
das EEprom löschst ?

CA Dirk

von Bernd (Gast)


Lesenswert?

Den habe ich heute morgen gebraucht :-)

Beitrag "Was ist die aktuelle, STABILE WinAVR Version?"

Karl Heinz Buchegger schrieb:
>> Sie ist da und sie funktioniert.

:-)

von Karl H. (kbuchegg)


Lesenswert?

Bernd schrieb:
> Den habe ich heute morgen gebraucht :-)
>
> Beitrag "Was ist die aktuelle, STABILE WinAVR Version?"
>
> Karl Heinz Buchegger schrieb:
>>> Sie ist da und sie funktioniert.
>
> :-)

Da bin ich mit dir konform.
Ich hasse es ebenfalls, wenn neue Compiler oder Libraryversionen auf den 
Markt geschmissen werden, die Bugs beinhalten. Ist für mich immer noch 
kein Grund die in der Lib angebotenen Funktionen nicht zu benutzen :-)

Aber nochmal: Bei ihm sind nicht die Funktionen das Problem, sondern die 
Art wie er sie verwendet. Und im Zweifel benutze ich lieber Funktionen 
für die es im Tutorial Erklärungen gibt wie man sie benutzt als 
irgendwelches selbstgeschriebenes (in diesem Fall: selbst 
abgeschriebenes) Zeug, von dem nicht klar ist wie man es einsetzt. Vor 
allen Dingen und insbesondere dann, wenn ich in Programmieren nicht so 
fit bin wie es eigentlich sein sollte (und ich das auch weiß).

Du lässt ja auch den Compiler seine Arithmetikroutinen einsetzen und 
benutzt nicht eigene. Oder die str... Funktionen. Schreibst du die alle 
selbst? Könnte ja in der nächsten Version ein Bug drinn sein! Und wenn 
wir schon dabei sind: Ich trau dem Compiler auch nicht über den Weg, 
dass er for Schleifen richtig umsetzt. und und und.

Letztendes landen wir bei: Leg Compiler und Library beiseite und progge 
in Assembler. Und das kanns ja dann nicht sein.

Ich habe Verständnis dafür, dass jemand Funktionen aus der Library nicht 
kennt. Vor allen Dingen dann, wenn es keine Standardfunktionen sind. 
Aber wenn jemand 6 Wochen lang das Tutorial studiert und ihm nicht 
auffällt, dass er Funktionalität implementiert hat, die ihm die Lib 
schon zur Verfügung stellt und es ev. angebracht wäre auf diese Schiene 
zu wechseln damit man die Erklärungen im Tut 1:1 einfach anwenden kann 
und die Beispiele von dort einfach übernehmen kann, dann denke ich mir 
meinen Teil. Vor allen Dingen dann, wenn das praktisch kein Aufwand 
gewesen wäre.

von Frank aus Köln (Gast)


Lesenswert?

Um den Glaubenskrieg mal wieder etwas anzuheizen ;)
Ich finde es nicht schlimm, Libs nicht zu benutzen.
Libs machen in meinen Augen Sinn, wenn ich mich nicht um Codegrösse und 
Geschwindigkeit kümmern muss.
Spätestens wenn ich auf einem Kleinen µC ( RAM, Flash ) zeitkritische 
Dinge tun muss, komme ich um das selber schreiben nicht mehr drum rum.
Das sollte jedem der das mal versucht hat, auch schon aufgefallen sein. 
Versucht mal mit printf und floats auf einem ATTiny 25 rumzufingern.
Außerdem finde ich es sehr löblich, wenn sich ein Anfänger durch die 
Datenblätter durchwuselt, um selber eine Lösung für sein Problem zu 
finden.
Deshalb kann ich den harschen Ton auch nicht verstehen.
Ich finde Libs sind Komfort, den man nicht immer hat oder nutzen kann.
Libs sind UNIVERSELLE Werkzeuge, Spezialwerkzeuge muss man sich immer 
noch selber schreiben.

Gruß aus Köln
Frank

von P. S. (Gast)


Lesenswert?

Ulrich schrieb:

> Warum sollte man mit dem Bus fahren, laufen tuts doch auch.
> Sorry, aber diese "wir erfinden das Rad zum tausendsten Mal"-Leute
> habe ich echt gefressen.

Ah, da steht jemand auf Holzraeder.

Es spricht ueberhaupt nichts dagegen, das Rad neu zu erfinden, nur so 
wurde es ueber die Jahrtausende verbessert. Allerdings sollte man sich 
dafuer zuerst - aeh - Radkompetenz aneignen :-)

In diesem speziellen Fall ist das Hauptproblem wohl mal wieder, dass 
sich jemand an ein komplettes Auto wagt, statt erst mal die einzelnen 
Komponenten auf die Reihe zu bekommen.

Also der gleiche Tip wie immer beim Debuggen: Alles einzeln testen. In 
ein 5-Zeilen-Testprogramm schaut im Forum auch eher mal einer rein als 
in so einen Wust.

von Bernd (Gast)


Lesenswert?

Einen hab ich noch :-)

Ich will jetzt nicht den Thread mißbrauchen und ich weiß das du ein sehr 
guter Programmierer bist (Karl Heinz) Aaaaber :-)

Satndard C Funktionen wie printf etc. etc. verwende ich natürlich. Bei 
spezifischen Sachen halte ich es aber eben anders.

Beispiel: Die MC's haben alle nen Timer. Wenn ich also den Timer als 16 
BIT Zähler verwenden will warum nicht ne LIB Funktion schreiben ? wirds 
jetzt klar ?

von Karl H. (kbuchegg)


Lesenswert?

Bernd schrieb:

> Beispiel: Die MC's haben alle nen Timer. Wenn ich also den Timer als 16
> BIT Zähler verwenden will warum nicht ne LIB Funktion schreiben ? wirds
> jetzt klar ?

Ist ganz einfach:
Schreib eine Lib dafür. Sorge dafür, dass sie in die glibc aufgenommen 
wird (also allgemein verfügbar ist) und du hast in mir einen Herold, der 
(wenn die Lib gut genug ist) sie anpreist wie geschnittenes Brot :-). 
Ich ärgere mich swieso jedesmal, dass ich mir aus dem Datenblatt die 
Konfigurationsbits für einen bestimmten Vorteiler raussuchen muss und 
nicht einfach schreiben kann

   setTimer0Prescaler( TIMER0_PRESCALER_8 );

Nur leider wirst du feststellen, dass eine derartige Lib im Gegensatz zu 
ein paar popeligen EEprom Zugriffsfunktionen gar nicht so einfach ist. 
EEprom Zugriff ist m.W. bei allen AVR gleich aufgebaut. Timer leider 
nicht.

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.