Hallo, mitteinander, ich habe da ein Problem mit der Kombination AVR-Studio/GCC. Und zwar habe ich ein Programm, das zyklisch AD-Werte einlesen soll (via Interrupt). Nehme ich die normale "Sammelroutine" geht alles (siehe Anhang). Ersetze ich aber die Zeile in der ISR, die den ADC ausliest, durch folgendes: ADCBuffer[TempChannel] = ((ADCBuffer[TempChannel]*4)+ADCH)/5; (soll eigentlich nur eine Mittelwertbildung des Signales bewirken...) wird in einem vollkommen anderen Modul (der UART-Routine) irgendetwas zerbomt, da kommt dann nicht mehr der formatierte String raus, sondern nur noch Datenmüll. Die Module selbst sind aber vollkommen gekapselt, da dürfe sich also gar nichts beeinflussen...!!?!? Wewiß da jemand Rat. Danke Gruß Kai
Sieht so aus, als würdest du irgendwo einen Puffer überschreiben. Hat ADCBuffer denn genügend Platz?
Hallo, Jörg, doch, müsste eigentlich gehen, ich hab' gerade 60% RAM verbraten und extra alles "static" deklariert..... oder doch lieber volatile nehmen??? 73 de Kai DL1GJJ
ich hab's mal extra jetzt gegeneinander ausprobiert: ADCBuffer[TempChannel] = ADCH; //ADCBuffer[TempChannel] = ((ADCBuffer[TempChannel]*4)+ADCH)/5; Das sind die beiden Zeilen, um ie es geht. So wie es jetzt steht, geht es, wenn ich die Kommentare in umändere in die andere Zeile, geht nix mehr.....
Ersetze mal spaßeshalber die 4 in der Formel durch eine 4u. Ich hab' da so eine Vermutung...
Hallo, Jörg, Dein Vorschlag hatte leider auch nix gebracht. Habe aber den Fehler mittlerweile entdeckt: ADCBuffer[TempChannel] = (unsigned char)(((unsigned int)ADCBuffer[TempChannel]*4)+(unsigned int)ADCH)/5; Cast's lassen grüßen..... Damit geht's! Trotzdem Danke 73 de Kai DL1GJJ
Ja, irgendsowas hatte ich vermutet, mir ist nur nicht ganz klar, welche der impliziten Typumwandlungen hier auf die Füße gefallen ist.
Hrmpf Auch wenn es jetzt tut, würde mich doch mal interessieren, wie sich 2 vollkommen unterschiedliche Module auf die Art und Weise beeinflussen können. Das Wissen darüber könnte ggf in der Zukunft seltsame Effekte verhindern helfen.... Gruß Kai
Hi, Kai, "Auch wenn es jetzt tut, würde mich doch mal interessieren, wie sich 2 vollkommen unterschiedliche Module auf die Art und Weise beeinflussen können." Mit der Fragestellung kommst Du schwer drauf. Denn das, was wir "Module" nennen, das beeinflußt sich nie gegenseitig. Aber irgendwo wurde im Modul A eine Variable X deklariert, die vermutlich von einem Zeiger in Modul B ungewollt beschrieben wird. Ciao Wolfgang
Du solltest auf jeden Fall das hier ISR (ADC_vect) { static unsigned char TempChannel; ersetzen durch ISR (ADC_vect) { static unsigned char TempChannel = 0; TempChannel kommt nicht mit einem Defaultwert von 0 ins Leben. Wo der anschliessende Schreibvorgang in den Buffer tatsächlich hinschreibt weiss nur Gott und der Compiler alleine. Und beide sagen nichts.
Mit dem Begriff "Modul" wäre ich auch etwas vorsichtig. Am Ende gibt es nur ein Stück Software, welches sich in einem Flash und vor allem in einem Ram mit einem Stack austobt. Da gibt es keine Grenzen :-) Selbst eine "Weltfirma" wie Mikroweich beschäftigt Zillionen von Progammierern, die jede Woche eine Patchsammlung zum stopfen genau solcher Probleme herausbringt. Oliver
> Auch wenn es jetzt tut, würde mich doch mal interessieren, wie sich > 2 vollkommen unterschiedliche Module auf die Art und Weise > beeinflussen können. Nun, mit der Fragestellung kommst du in der Tat schwer drauf. Sie beeinflussen sich nämlich gar nicht. Du hattest einfach einen numerischen Überlauf in deinen Berechnungen, der daraus resultierte, dass die uint8_t-Variablen vor der Berechnung des gesamten Ausdrucks nicht etwa in uint16_t umgewandelt werden, sondern zuerst einmal in int (und von da ggf. in unsigned int, falls der Rest des Ausdrucks oder die Zuweisung das verlangt). Damit wurden aber plötzlich Zahlen oberhalb 128 zu negativen 16-bit-int erweitert, entsprechend kam hinterher kompletter Blödsinn raus. Mit irgendeinem anderen ,Modul' hatte das rein gar nichts zu tun. > TempChannel kommt nicht mit einem Defaultwert von 0 ins Leben. Hier muss ich Karl-Heinz ausnahmsweise widersprechen. TempChannel kommt sehr wohl mit einem Defaultwert von 0 ins Leben, da der C-Standard dies für eine statische Variable so verlangt. Es ist also (in diesem Falle!) komplett legitim, die Initialisierung wegzulassen.
Aeh. Mein Fehler. Globale und static werden default initialisiert. Yep. Man vergisst so viel im Laufe der Zeit. Zu meiner Entschuldigung kann ich nur anführen, dass ich mir schon vor Jahren angewöhnt habe, Variablen bei der Deklaration zu initialisieren (oder in C++ im Konstruktor). Auf lange Sicht fährt man einfach besser damit. Ich hab schon zuviele Stunden damit verbracht, dubiose Fehler zu suchen, die sich hinterher als nicht initialisierte Variablen herausgestellt haben.
Naja, bis vor kurzem hat das noch Speicherplatz verschwendet beim GCC, da ein explizit zu 0 initialisierter Wert Platz im .data einnahm, während die implizit initialisierten im .bss keinen Platz gebraucht haben. Mittlerweile ist GCC aber zumindest in der Lage, die unnötige Initialisierung zu erkennen und die Variable dann trotzdem ins .bss zu schieben.
Ja. Hab ich gelesen. Hat mich auch viel Überwindung gekostet, globale Variablen nicht mehr explizit mit 0 zu intialisieren. Interessant: Beim neueren gcc darf man das wieder ohne einen Penalty. Gute Information, Danke Jörg.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.