Guten Tag,
Ich habe die Vermutung das mein Programm zu viel ram verschluckt...bin
mir aber nicht sicher.
Und zwar:
Ich nutze einen Atmega16@16mhz mit dem ich einen tlc5940 ansteuere, was
durch 2 timer-interrupts funktioniert.
Mit der IRMP-Lib kann ich erfolgreich ein RC6 signal über uart
ausgeben, doch nur, solange der timer-interrupt eines tlc-timers (der
andere toggelt nur einen ausgang) ausgeschaltet ist.
In der config der IRMP-Lib sind 15000 Interrupts / Sekunde eingestellt.
Der TLC5940-Timer führt 1953 Interrupts / Sekunde aus.
(Wenn ich das richtig berechnet habe, init:)
timo91 schrieb:> Ich habe die Vermutung das mein Programm zu viel ram verschluckt...bin> mir aber nicht sicher.
Ja, wieviel schluckt es denn?
Hast du einen Listfile und einen Simulator? Nur du kennst das Programm.
Was tut dein Programm, wenn es nicht funktioniert?
Guten morgen,
Danke für die schnellen Antoworten :)
Ich habs jetzt inzwischen soweit bekommen, das fast alles miteinander
funktioniert, doch wenn ich meine fade-funktionen laufen lasse startet
der µC immer wieder neu.
Das liegt dann in dem fall doch am RAM oder?
timo91 schrieb:> Das liegt dann in dem fall doch am RAM oder?
Völlig klar, oder am Osterhasen.
Woher sollen wir wissen wieviel dein Programm ram braucht? Wenn du es
nichtmal weißt.
Nutzt du dynamische allokierung zur Laufzeit? Ansonsten müsstet du ja
den Ram Bedarf schon zur Compilierzeit sehen.
Bei vielen verschachtelten Interrupts kann dir auch der Stackpointer in
den Heap laufen. Sollte halt nicht passieren dass sich INTs
verschachteln, vorallem nicht unkontrolliert. Aber nur du kennst das
Program, also was willst du?
gruß cyblord
Ok ich habe den kompletten Source-Code jetzt mal angehängt. Falls jemand
zeit & lust hat sich das mal an zu schauen wäre ich ihm oder auch ihr =D
sehr dankbar.
Ich weiß der Code ist ziemlich unsauber und man kann noch vieles
verbessern. Doch das jetzige problem beschränkt sich darauf das jede
teil funktion funktioniert, nur zusammen nicht.
Und zwar:
In der Schleife der main-function wird Erstens geschaut ob IRMP etwas
empfangen hat, wenn ja wird der RC6-command mit zwei werten verglichen
und je nach dem wird eine led dunklet oder heller gestellt.
Am ende der Schleife wird updateFades() aufgerufen um die fades zu
aktualisieren (ne is klar), doch danach wird updatePrograms() aufgerufen
um die Fade-Programme (steuerung mit mehreren fades hintereinander usw)
zu aktualisieren.
Wenn diese beide Funktionen in der main-schleife aufgerufen werden,
empfängt IRMP aufeinmal nichts mehr. Doch sobald ich entweder
updatePrograms() oder updateFades auskommentiere funktioniert IRMP
aufeinmal wieder und empfängt.
Der controller startet auch nicht mehr neu oder so, es funktioniert
einfach nur nicht wenn diese beide funktionen in der Schleife aufgerufen
werden.
Falls es am RAM liegen sollte könnte man da noch vieles tun z.B. die
TLC5940 werte nicht bitweise in 8bit zu speichern..doch ich wollte
erstmal sicher gehen ob es daran liegt.
Viel dank
timo91
Das sind schon mal fast 600 Bytes. Dazu hast du noch ein paar
Strukturen, die Speicherplatz brauchen und dein uC hat gerade mal 1kB...
> Falls es am RAM liegen sollte könnte man da noch vieles tun> ..doch ich wollte erstmal sicher gehen ob es daran liegt.
Du kannst einfach im Listing nachsehen, oder an den Meldungen, die der
Compiler ausspuckt...
Wobei das aber auch nur der statische RAM ist.
Dazu kommt nochmal der Stack.
Meine Vermutung:
Du kratzt knapp unterhalb der 1kB die der mega16 hat.
Dann rufst du paar verschachtelte Funktionen auf, der Stack wächst in
den Heap und richtet dort ordentlich Schaden an.
Aber - natürlich nur ne Vermutung...
So in der Art hab mir ich das auch schon gedacht, denn schon als ich
IRMP und fade.c miteinander einbinden wollte funktionierte auch erstmal
überhaupt nichts bis ich den fade-struct array von 16 auf 3 elemente
herabgesetzt habe.
Hab mir von anfang an gedacht das es keine gute idee ist die bits in nem
langen uint8 array zu speichern.
Ich werd mich jetzt mal ranmachen und das alles so umschreiben das ich
durch überarbeiten der Datenspeicherung viel ram spar und werds dann
nochmal mit IRMP zusammen ausprobieren und berichten.
Vielen Danke für die Infos.
timo91 schrieb:> Hab mir von anfang an gedacht das es keine gute idee ist die bits in nem> langen uint8 array zu speichern.
Ach, das sind nur Bits? Dann kannst Du die Arrays auf ein Achtel (+1)
herunterschrumpfen.
Mal so hingeschmiert:
1
#define setarraybit(a,x) a[x/8] |= (1<<(x%8))
2
#define resetarraybit(a,x) a[x/8] &= ~(1<<(x%8))
3
#define getarraybit(a,x) a[x/8] & (1<<(x%8))
Ist nicht getestet, sollte aber so gehen.
Wenn Du zum Beispiel 123 Bits brauchst, dann definierst Du das Array so:
1
#define MAX_BITS 123
2
uint8_tmyarray[MAX_BITS/8+1];
Anwendung:
1
setarraybit(myarray,23);// Setze Bit 23 (angefangen bei 0!)
2
resetarraybit(myarray,24);// Setze Bit 24 zurück
3
4
if(getarraybit(myarray,23))// Teste, ob Bit 23 gesetzt
5
{
6
irgendwas();// Bit ist gesetzt!
7
}
Viel Spaß,
Frank
P.S.
Sei unbesorgt: Der gcc wird die Division durch 8 durch einen
Schiebebefehl ersetzen. Ebenso wird der Modulo-Operator durch
entsprechendes Maskieren erledigt. Die obigen Macros sind daher bei
Optimierung mit -Os nicht sehr CPU-intensiv.
Der Controller verhält sich wirklich ziemlich komisch.
Ich habe versucht es in kleine varine mit kleineren arrays um zu
schreiben auch Frank M.'s idee habe ich versucht. Doch bisher noch
keinen Erfolg.
Ich konnte jedoch den kleineren der beiden arrays (uint8_t dcData[96 *
TLC5940_N]) auskommentieren weil es nur optional ist.
Doch zu den problIch em:
Egal ob ich die updateFades() & updatePrograms() nur einmal in der
endlos-schleife oder nur alle 1, 2 oder 50 mal.
Doch sobald ich eine der beiden funktionen garnicht aufrufe aus
auskomenntiere funktioniert IRMP wunderbar.
Ideen?
timo91 schrieb:> Ich habe versucht es in kleine varine mit kleineren arrays um zu> schreiben
Und, wie sieht die Speicherauslastung jetzt aus?
> Egal ob ich die updateFades() & updatePrograms() nur einmal in der> endlos-schleife oder nur alle 1, 2 oder 50 mal.
Hast du gesehen: dieser Satz ist noch nicht ganz fertig...
WAS funktioniert dann nicht mehr? WIE stllst du das fest?
Kann es sein, dass die beiden Funktionen zusammen einfach zu lange
dauern?
Lothar Miller schrieb:> timo91 schrieb:>> Ich habe versucht es in kleine varine mit kleineren arrays um zu>> schreiben> Und, wie sieht die Speicherauslastung jetzt aus?>
Nachdem der array entfernt wurde spuckt die funktion 214 freie bytes
aus, was ja eigentlich reichen sollte.
>> Egal ob ich die updateFades() & updatePrograms() nur einmal in der>> endlos-schleife oder nur alle 1, 2 oder 50 mal.> Hast du gesehen: dieser Satz ist noch nicht ganz fertig...>
Srry, :
Egal ob ich die updateFades() und updatePrograms() nur einmal in der
endlos-schleife oder nur nach 1, 2 oder 50 mal aufrufe, IRMP will dann
nichmehr.
> WAS funktioniert dann nicht mehr? WIE stllst du das fest?> Kann es sein, dass die beiden Funktionen zusammen einfach zu lange> dauern?
IRMP, also das empfangen mit einer RC6 fernbedienung.
In der endlos-schleife:
1
if (irmp_get_data (&irmp_data))
2
{
3
if(irmp_data.command == 16)
4
{
5
puts("LAUTER ");
6
//cli();
7
//fade_up(24);
8
//sei();
9
}
10
else if(irmp_data.command == 17)
11
{
12
puts("LEISER ");
13
//cli();
14
//fade_down(24);
15
//sei();
16
}
Doch sobald updateFades() und updatePrograms() zusammen in der
endlos-schleife aufgerufen werden empfang ich kein IR signal mehr.
Viel dank bis hierhin schonmal :)
Naja ich hab noch weitere dinge ausprobiert:
Anstatt die updateFades() & updatePrograms function hab ich einfach
versucht wie weit ich mit einem delay in der endlos-schleife hoch gehen
kann bis IRMP nichts mehr empfängt. Ich habs bis 1ms hochgetestet und
der IRMP empfang immernoch daten (doch auch nicht mehr ganz sauber).
Ich habe den freien ram mit aufrufen der funktionen ohne ausgeben
lassen, ca 216bytes frei.
Was ist da los?!
timo91 schrieb:> Ich habs bis 1ms hochgetestet und> der IRMP empfang immernoch daten (doch auch nicht mehr ganz sauber).
Da IRMP die IR-Signale über die Timer1-ISR empfängt, ist das auch nicht
das Problem. Da kannst Du noch so lange Delays einbauen: zumindest ein
IR-Kommando empfängt dann IRMP immer noch, das nächste allerdings erst,
wenn Du das erste auch "abgeholt" hast.
> Ich habe den freien ram mit aufrufen der funktionen ohne ausgeben> lassen, ca 216bytes frei.
Sollte reichen, wenn Du keine gößeren lokalen(!) Arrays in irgendeiner
Funktion stecken hast.
> Was ist da los?!
Was macht denn ISR(TIMER2_COMP_vect) so alles? Da gibt es eine
for(;;)-Schleife drin. Solange diese Schleife läuft, werden natürlich
keine anderen Interrupts mehr aufgerufen und IRMP könnte dann wegen
verlorener Interrupts ins Schleudern geraten.
Abhilfe: Setze in Deiner Timer2-ISR lediglich ein volatile-Flag, dass Du
diese Kopierschleife (oder was es auch sein mag) ausführen musst und
verlagere die Schleife ins main.
Gruß,
Frank
Frank M. schrieb:> timo91 schrieb:>> Ich habs bis 1ms hochgetestet und>> der IRMP empfang immernoch daten (doch auch nicht mehr ganz sauber).>> Da IRMP die IR-Signale über die Timer1-ISR empfängt, ist das auch nicht> das Problem. Da kannst Du noch so lange Delays einbauen: zumindest ein> IR-Kommando empfängt dann IRMP immer noch, das nächste allerdings erst,> wenn Du das erste auch "abgeholt" hast.>
Joa genau das hatte ich auch im Sinn doch mich wunderte wieso es nur
nicht empfängt wenn die funktionen aufgerufen werden
>> Ich habe den freien ram mit aufrufen der funktionen ohne ausgeben>> lassen, ca 216bytes frei.>> Sollte reichen, wenn Du keine gößeren lokalen(!) Arrays in irgendeiner> Funktion stecken hast.>
Nein nicht innerhalb funktionen.
>>> Was ist da los?!>> Was macht denn ISR(TIMER2_COMP_vect) so alles? Da gibt es eine> for(;;)-Schleife drin. Solange diese Schleife läuft, werden natürlich> keine anderen Interrupts mehr aufgerufen und IRMP könnte dann wegen> verlorener Interrupts ins Schleudern geraten.>> Abhilfe: Setze in Deiner Timer2-ISR lediglich ein volatile-Flag, dass Du> diese Kopierschleife (oder was es auch sein mag) ausführen musst und> verlagere die Schleife ins main.>
In der ISR2 werden wenn gsUpdate gesetzt ist, bits (für helligkeit
verschiedener kanäle) an den TLC5940 übertragen.
ich habe ss jetzt mal so laufen lassen das ich in der ISR2 die
kopier-schleife auskommentiert habe, jedoch in der endlos-schleife der
main-function beide funktionen (updateFades() und updatePrograms()) drin
stehen hab...uuund IR-Signale werden aufeinmal empfangen!!
Der kopiertvorgang kann ich leider nicht einfach in die schleife
schieben da es in bestimmten zeitabständen geschickt werden muss. (ISR2
löst ca 2000 interrupts/s aus).
Ich habe auch versucht in der ISR1 des IRMP am anfang ein cli() und am
ende ein sei() zu setzten..doch dies hat leider nichts geholfen.
Deshalb hab ich daran gedacht das ich die ISR1 und ISR2 zusammenfüge.
Die ISR1 des IRMP macht 10 000 Interrupts/s (Ist auf minimale
einstellung und läuft prima (range ist 10-20k default 15k).
Da aber 10k Interrupts/s für die Kopierfunktion der ISR2 zuviel sind,
dachte ich daran in der ISR2() sowas zu intigrieren:
1
static uint8_t callISR2 = 0;
2
if(callISR2 >4)
3
{
4
ISR2();
5
callISR2 = 0;
6
7
}
8
callISR2++;*/
Das würde die doch die 10 000 Interrupts /5 Teilen ..also auch ca. 2000
Aufrufe pro sekunde.
Richtig?
Danke leute ihr seid klasse :)
Ich habe es wie oben beschrieben mal versucht...und es hat nicht
geklappt. Ich habe den TIMER2 ausgemacht und rufe ISR2 jetzt von der
ISR1 aus auf. Das Faden usw hat alles funktioniert (also der TLC) aber
IRMP nicht.
Dann hab ich wie vorgeschlagen die ISR2 in die schleife der
main-function einzufügen und ...TADA alles funktioniert schön
miteinander.
Nur hab ich jetzt eben nicht mehr das genaue timing für die
datenübertragung. Denn falls mehrere fade-programme gleichzeitig laufen
steigt die zeit zwischen den übertragungen was nicht sehr gut ist.
Ich versuch später mal die update-functionen in eine ISR zu packen..mal
sehen ob das funktioniert.
Doch wieso kann ich nicht beide funktionen über ISRs aufrufen?
Liegt es an der Zeit die, die datenübertragung benötigt? Hat IRMP
nichtmehr funktioniert weil die ISR2() zur datenübertragung zulange
dauert und sich die interrupts dann irgendwie verschachtelt haben?
mfg
timo
timo91 schrieb:> Ich habe es wie oben beschrieben mal versucht...und es hat nicht> geklappt. Ich habe den TIMER2 ausgemacht und rufe ISR2 jetzt von der> ISR1 aus auf. Das Faden usw hat alles funktioniert (also der TLC) aber> IRMP nicht.> Dann hab ich wie vorgeschlagen die ISR2 in die schleife der> main-function einzufügen und ...TADA alles funktioniert schön> miteinander.
wie erwartet
> Nur hab ich jetzt eben nicht mehr das genaue timing für die> datenübertragung.
du kannst dir in der ISR an der stelle ein Flag setzen wo die
Tranferroutine war, das fragst du dann in Main ab und startest das
Update der TLC's
> Denn falls mehrere fade-programme gleichzeitig laufen> steigt die zeit zwischen den übertragungen was nicht sehr gut ist.
das verstehe ich nicht ganz, die Zeit für Übertragungen würde auch in
der ISR steigen
> Ich versuch später mal die update-functionen in eine ISR zu packen..mal> sehen ob das funktioniert.>> Doch wieso kann ich nicht beide funktionen über ISRs aufrufen?> Liegt es an der Zeit die, die datenübertragung benötigt?
genau - die Übertragung dauert zu lang
> Hat IRMP> nichtmehr funktioniert weil die ISR2() zur datenübertragung zulange> dauert und sich die interrupts dann irgendwie verschachtelt haben?
verschachtelt nicht, aber die IRMP-ISR muss eben warten wenn die
Übertragung läuft! Damit IRMP funktioniert, darf keine andere ISR länger
brauchen als die Zeit zwischen 2 IRMP INT's (bei 15kHz also ca. 0.07ms)
du könntest den Transfer zum TLC beschleunigen, wenn du dafür die
SPI-Schnittstelle verwendest - falls der TLC eine höhere Geschwindigkeit
zulässt.
Sascha