Hallo alle zusammen, ich stehe mal wieder vor einem eigenartigen Problem! Ich habe einen Atmel AT90CAN128 und sende damit LIN und CAN Nachrichten. Die LIN Nachrichten "sollen" mittels eines Timers (ISR(TIMER0_COMP_vect)) der auf 100kHz eingestellt ist, alle 10ms eine LIN Botschaft versenden. Wenn ich jetzt LIN Nachrichten versende MIT dem Timer, bekomme ich nur Errorflags. Wenn ich den Timer ausschalte und dann nochmal Nachrichten sende, bekomme ich alles richtig raus. Bei CAN ist es egal ob Timer an oder aus, da kommt immer alles korrekt raus. Meine Frage jetzt: Kann es sein das der Timer soviel Reccoursen benötigt, das meine LIN Nachrichten nicht mehr sauber versendet werden können ?
Andreas P. schrieb: > Kann es sein das der Timer soviel Reccoursen benötigt Was erwartest Du denn bei wahnsinns 10µs Interruptrate? Rechne mal nach, wie wenig CPU-Zyklen das sind. Dem CAN macht das nichts, da er das Protokoll komplett in Hardware macht. So als Faustregel, ein Interrupt sollte nicht schneller als alle 500 Zyklen aufgerufen werden. Wenn Du 10ms brauchst, nimm auch nen 10ms Interrupt. Peter
Ich habe jetzt auch mal auf dem UART geschaut was dort ankommt. Also die Daten kommen richtig am UART an! @Peter: Ich habe einen "Vergleichstimer", der wie folgt aufgebaut ist: Ich habe eine 8MHz CLK, daher lasse ich den Timer bis 80 Zählen, dann soll in Interrupt ausgelöst werden (also 8MHz/80Schritte = 100kHz) Ich kann aber max. bis 255 Schritte vergleichen, daher funktioniert deine Idee mit dem "alle 10ms" ausführen leider nicht. Da ich den Counter auch noch für andere Zwecke nutzen möchte, muss dieser min. alle 1ms ausgelöst werden. Wie kann ich den Counter "langsamer" machen, so das meine Reccursen nicht so ausgelastet werden.
1 | void init_timer() |
2 | {
|
3 | hundert_taus_sek=0; |
4 | zehn_taus_sek=0; |
5 | millisekunden=0; |
6 | hundert_sek=0; |
7 | zehntel_sek=0; |
8 | sekunde=0; |
9 | |
10 | TCCR0A =(1<<WGM01)|(1<<CS00); // CTC-> Clear Timer on Comparematch, Prescaler off |
11 | OCR0A= 0x50; //bis 80 Zählen ->100kHz (8MHz CLK) |
12 | |
13 | |
14 | TIMSK0 |= (1<<OCIE0A); //Compare Interrupt aktivieren |
15 | }
|
16 | |
17 | |
18 | ISR(TIMER0_COMP_vect) |
19 | {
|
20 | hundert_taus_sek++; |
21 | if(hundert_taus_sek==10) |
22 | {
|
23 | zehn_taus_sek++; |
24 | hundert_taus_sek=0; |
25 | |
26 | if( delay_count > 0 ) // Nachrichtenverzögerung (1/10ms) |
27 | {
|
28 | delay_count--; |
29 | }
|
30 | |
31 | if(zehn_taus_sek==10) |
32 | {
|
33 | PORTA ^= (1<<PA0); //**********DEBUGG LED********+ |
34 | millisekunden++; |
35 | |
36 | zehn_taus_sek=0; |
37 | if(millisekunden==10) |
38 | {
|
39 | millisekunden=0; |
40 | hundert_sek++; |
41 | PORTA ^= (1<<PA2); //**********DEBUGG LED********+ |
42 | if(hundert_sek==10) |
43 | {
|
44 | hundert_sek=0; |
45 | zehntel_sek++; |
46 | PORTA ^= (1<<PA4); //**********DEBUGG LED********+ |
47 | if(zehntel_sek==10) |
48 | {
|
49 | zehntel_sek=0; |
50 | sekunde++; |
51 | PORTA ^= (1<<PA6); //**********DEBUGG LED********+ |
52 | |
53 | trigger_time++; |
54 | if(sekunde == 43200) //12 Stunden |
55 | {
|
56 | modus=3; |
57 | new_file=1; |
58 | sekunde=0; |
59 | trigger_time=0; |
60 | }
|
61 | }
|
62 | }
|
63 | }
|
64 | }
|
65 | }
|
66 | }
|
Andreas P. schrieb: > Ich habe eine 8MHz CLK, daher lasse ich den Timer bis 80 Zählen, dann > soll in Interrupt ausgelöst werden (also 8MHz/80Schritte = 100kHz) 80 Schritte ist schon verdammt wenig. Das sind ungefähr 60 Assemblerinstruktionen. Davon gehen bei C schon mal gut und gerne 20 bis 30 für die ISR Preämbel/Ausstieg drauf, so dass kaum mehr was übrig bleibt. Für die ISR. Aber auch das Hauptprogramm muss ja auch noch arbeiten. > Ich kann aber max. bis 255 Schritte vergleichen, daher funktioniert > deine Idee mit dem "alle 10ms" ausführen leider nicht. Du hast ja auch noch einen Vorteiler. > Da ich den Counter auch noch für andere Zwecke nutzen möchte, muss > dieser min. alle 1ms ausgelöst werden. 100kHz sind aber auch keine 1ms
Hallo Karl heinz, ich habe den Vorteiler ganz überlesen... habe jetzt einen Vorteiler von 8 genommen --> 1MHz und lasse bis 100Schritte zählen was dann eine Interruptauslösung von 10kHz ergibt. Jetzt funktioniert auch das versenden von LIN Nachrichten mit eingeschaltenem Timer !
1 | TCCR0A =(1<<WGM01)|(1<<CS01); // CTC-> Clear Timer on Comparematch, Prescaler 8 ---> 8.000.000 / 8 = 1MHz |
2 | OCR0A= 0x64; //bis 100 Zählen ->10kHz (8MHz CLK) |
Ich werde die Auslösezeit trotzdem noch runterschrauben um auf der sicheren Seite zu sein. !!!!!!! DANKE MAL WIEDER FÜR EURE HILFE !!!!!!!!!!! Gruß Andreas P.
Andreas P. schrieb: > Ich werde die Auslösezeit trotzdem noch runterschrauben um auf der > sicheren Seite zu sein. Und noch was. Kein Mensch sagt, dass du die ISR in 10-er Bruchteilen aufrufen musst. Da du dann sowieso noch einen Software-Teiler hinten nachschaltest, kannst du anstelle von alle 100-Timer Schritte ja auch alle 200 Timer Schritte die ISR auslösen lassen. In der ISR zählst du dann eben nicht bis 100 sondern nur bis 50 um die weiteren Aktionen auslösen zu lassen und hast dann für die Aktionsauslösung immer noch dasselbe Timing. Aber mit nur der Hälfte der ISR Aufrufe.
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.