Hallo,
ich hab mir hier schon viele Infos aus dem Forum gesammelt und
erfolgreich umgesetzt. Jetzt wollte ich mal wieder anfangen (nach ein
paar Jahren) in C zu programmieren. Genaugenommen einem Atmega 16 ein
wenig Leben einzuhauchen.
Da stellt sich mir gleich folgendes Problem.
Ich habe ein kleines Programm geschrieben, wo ich einen Teil in einen
"Funktionsblock" auslagern wollte damit die main Funktion übersichtlich
bleibt.
Leider funkt. das nicht wie erhofft.
Ich habe folgendes gemacht:
1
voidmachwas(intms){
2
for(inti=0;i<8;i++){
3
....
4
}
5
intmain(void)
6
{
7
while(1){
8
machwas(100);
9
}
10
}
So weit so gut... leider wird "machwas" nicht ausgeführt. Im Debugger
sehe ich das er beim Aufruf von "machwas" in die Funktion springt, aber
direkt wieder raus...
Schreibe ich die Anweisungen aus "machwas" in die main Funktion geht
es...
Wo liegt mein Fehler?
Danke im Voraus... Tobias
Da steht ja Code drin... wegoptimieren kann er die nicht... ich hab nur
am Programmierrechner kein Internet, deswegen nur der Auszug...
Die Schleife mit ihrem Inhalt funkt. ja direkt im Main...
Schau mal in die h-Files Deines (uns unbekannten) Compilers.
Oftmals gibts da eine delay.h, die man dann nimmt.
Oder schau ins Manual.
Zeitvernichtungsfunktionen schreibt man nicht selber, das können die
Compilerbauer besser als Du.
Peter
Tobias Jenatschke schrieb:> Da steht ja Code drin... wegoptimieren kann er die nicht...
Woher weißt du das?
Comopilier das mal ohne Optimierung (-O0), das sollte helfen.
Oliver
Tobias Jenatschke schrieb:> ich hab nur> am Programmierrechner kein Internet, deswegen nur der Auszug...
Das ist ganz schlecht. Für Code, der "so so der so ähnlich" abgetippt
wurde, dazu mit "..." drin, wirst du keine Hilfe bekommen.
Oliver
Tobias Jenatschke schrieb:> void machwas(int ms) {> for(int i=0; i<8;i++){
^^^ das ist reinen ISO C nicht gestattet soweit ich weiß.
in reinen C muss i vor der Schleife deklariert sein.
> ....> }> int main(void)> {> while(1){> machwas(100);> }> }
Ansonsten sieht der Code Schnipsel gut aus, wenn du uns nicht mit mehr
Informationen versorgen kannst, welcher Compiler, welche Compile
Optionen, was wird in "...." gemacht. wird es schwer dir zu sagen wo
dein Fehler liegt.
Imon schrieb:> Tobias Jenatschke schrieb:>> void machwas(int ms) {>> for(int i=0; i<8;i++){> ^^^ das ist reinen ISO C nicht gestattet soweit ich weiß.> in reinen C muss i vor der Schleife deklariert sein.
Das geht in Ordnung ab ISO/IEC 9899:1999.
Danke erstmal...
Ich arbeite mit AVR-Studio + GCC
Habe leider nur Java und PHP gelernt, C basiert nur auf Selbststudium.
>Tobias Jenatschke schrieb:> Da steht ja Code drin... wegoptimieren kann er die nicht...>Woher weißt du das?>Comopilier das mal ohne Optimierung (-O0), das sollte helfen.
Ich vermute das nur, da es ja direkt im Main funktioniert....
Ich versuch heute abend mal den gesamten Code hier zu rein zu posten...
Vermutlich schreibst du dann nicht
_delay_ms(ms);
sondern
_delay_ms(50);
Letzteres ist die richtige Variante: Nur Konstanten sind bei _delay_ms
und _delay_us erlaubt. Steht auch so in der avr-libc Doku und 1001*mal
hier im Forum :-)
Du kannst ein variables _delay_ms so erreichen:
{
uint16_t i;
for (i=0; i<ms; i++)
_delay_ms(1);
}
Oh, sorry, Ich bin wirklich wie ein Schnitzel...(bekloppt von allen
Seiten)
Das hab ich echt überlesen!
Jetzt dachte ich mir, ich könnte mir eine Funktion basteln, ala...
void langes_warten(uint16_t ms)
Das ist ungewöhnlich.
Aber zu "funktioniert nicht" fällt mir leider nicht viel ein.
Eine buggy _delay_ms() kann man ausschliessen, weil die direkte Variante
ja schon funktioniert hat. Bei F_CPU und Optimierung hast du hoffentlich
auch nichts geändert.
Bleiben also die doofen Fragen:
1. Rufst du langes_warten() auch irgendwo auf?
Nicht an die Wand springen. Hat man schon gesehen!
2. Überträgst du das richtige HEX-File?
Das AVR Studio kann da beim ISP Programmieren etwas eigen sein.
3. Hast du den richtigen AVR eingestellt?
Wenn Unterprogramme insgesamt nicht funktionieren, kann ein
Initialisierungsproblem beim Stack vorliegen. Das kann ein Zeichen für
einen falschen µC (TARGET) sein. Auch die M103 Fuse beim Atmega128 fällt
in diese Kategorie (Übersetzt für Atmega128, Werkseinstellung des
Atmega128 ist aber Atmega103...).
_delay_ms() ist keine statische Funktion, sondern eine inline Funktion.
Da fällt ein Stackproblem nicht auf.
Nicht zu vergessen, dass _delay_ms im Simulator zu, na ja sagen wir mal,
längeren Wartezeiten führen kann, wenn man mit F10 drüberzusteppen
versucht. Selbst wenn man alles richtig gemacht hat.
Stefan B. schrieb:> Letzteres ist die richtige Variante: Nur Konstanten sind bei _delay_ms> und _delay_us erlaubt. Steht auch so in der avr-libc Doku und 1001*mal> hier im Forum :-)
Ich dachte, es wäre erlaubt, erzeugt aber sehr großen Code und sollte
deshalb vermieden werden?
ekke schrieb:> Stefan B. schrieb:>> Erlaubt im Sinn von funktioniert im Sinn von Verzögert die angegebene>> Anzahl Millisekunden.> Ja, das meinte ich... ;-)
Eben.
Mit einer Variablen stimmen die Zeiten ganz einfach nicht mehr.
_delay_ms ist davon abhängig, dass der Optimizer eine komplexe
Berechnung rausoptimiert. Das geht aber nur dann, wenn er die
Verzögerungszeit kennt.
Die kennt er wiederrum nur dann, wenn es eine Konstante ist.
Ich hab gestern abend erstmal hingeworfen. Manchmal sieht man einige
Stunden später den Fehler. Heute bin ich leider lange unterwegs. Werde
mich wohl morgen wieder damit befassen.
Es wird etwas einfaches sein... mal schauen.
Wenn ich den Fehler gefunden habe, melde ich mich natürlich wieder...
Danke für die viele Hilfe.
1
voidlanges_warten(uint16_tms){
2
uint16_ti;
3
for(i=0;i<ms;i++)
4
_delay_ms(1);
5
}
Bringt ja eh etwas Ungenauigkeit in die Pause, für meinen Zweck reicht
es jedoch.