Hallo alle zusammen ich habe jetzt ein programm fertig was sehr träge läuft.Ich benutze einen Atmega8 intern 8Mhz.Kann mir einer sagen was ich verändern kann um es zu verschnellern?Der ADC reagiert träge und das Display.MfG Sebastian $regfile = "m8def.dat" $crystal = 8000000 $hwstack = 64 $swstack = 64 $framesize = 64 Config Lcd = 16 * 2 Config Lcdbus = 4 Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2 Cursor Off Config Portb.1 = Output Config Portc.0 = Input Config Portc.1 = Input Config Portb.2 = Output Config Portb.0 = Input Portb.0 = 1 Const True = 1 Const False = 0 Const Measure_success = 0 Const Measure_failed = 1 Const Measure_request = 2 Dim Frequency As Long Dim Capt_prev_val As Word Dim Capt_curr_val As Word Dim Measure_result As Long Dim Capt_result As Word At Measure_result Overlay Dim Ovf_result As Word At Measure_result + 2 Overlay Dim Ovf_ctr As Word Dim Ovf_exeed_ctr As Byte Dim Grad As Word Dim Grad1 As Word Dim Rpm As Word Dim F_str As String * 10 Dim Got_edge As Byte Dim Measure_status As Byte Config Timer1 = Timer , Prescale = 1 On Capture1 Isr_capt Enable Capture1 On Ovf1 Isr_ovf Enable Ovf1 Ovf_ctr = 0 Ovf_exeed_ctr = 0 Got_edge = False Tifr = Bits(icf1 , Tov1) Enable Interrupts Config Timer2 = Pwm , Prescale = 8 , Compare Pwm = Clear Up , Pwm = On Enable Timer2 Start Timer2 Config Adc = Free , Prescaler = 4 , Reference = Internal Start Adc Cls Do Locate 2 , 1 Measure_status = Measure_request While Measure_status = Measure_request Wend If Measure_status = Measure_success Then If Measure_result > 0 Then Measure_result = Measure_result / 10 Frequency = 826787928 / Measure_result F_str = Str(frequency) Lcd "Freq: " ; Format(f_str , "000.000") ; " Hz" Else Lcd "Fehler, Ergebnis = 0" End If End If Grad = Getadc(0) / 5 If Grad > 200 Then Grad = 200 Locate 1 , 1 Lcd Grad ; "ß" Rpm = Getadc(1) If Rpm = 1 Then Rpm = 0 If Rpm > 1000 Then Rpm = 1000 Locate 1 , 7 Lcd Rpm ; "Rpm" Rpm = Rpm / 4 Ocr2 = Rpm If Grad < 60 Then Portb.2 = 1 Else Portb.2 = 0 End If Waitms 30 Loop End Isr_capt: Capt_curr_val = Capture1 If Measure_status = Measure_request And Got_edge = True Then Capt_result = Capt_curr_val - Capt_prev_val Measure_status = Measure_success If Tifr.tov1 = 1 Then If Capt_curr_val < 2000 Then Incr Ovf_ctr Tifr = 2 ^ Tov1 Else Measure_status = Measure_request Incr Ovf_exeed_ctr If Ovf_exeed_ctr > 9 Then Measure_status = Measure_failed Ovf_exeed_ctr = 0 End If End If Else Ovf_exeed_ctr = 0 End If If Capt_curr_val < Capt_prev_val Then Decr Ovf_ctr End If Ovf_result = Ovf_ctr End If Capt_prev_val = Capt_curr_val Ovf_ctr = 0 Got_edge = True Return Isr_ovf: Incr Ovf_ct If Ovf_ctr > 122 Then If Ovf_ctr > 126 Then Got_edge = False Ovf_ctr = 0 If Measure_status = Measure_request Then Measure_status = Measure_failed End If Return
Hallo, erst mal. Wenn ein uC "träge" läuft hat das natürlich entweder damit zu tun, dass er relativ viel zu tun hat oder dass delays an der falschen Stelle ausgeführt werden. Du wartest an einer Stelle 30ms. Kann das vielleicht der Grund sein? Mit was programmierst du da eigentlich. Ist das BASIC? Wusste gar nicht das es da auch Compiler für den AVR gibt. Gruß lowlevel
lowlevel schrieb: > Ist das BASIC? Wusste gar nicht das es da auch Compiler für den AVR gibt. Bascom heißt das Ding. Kann man da den Text nicht auch sinnvoll formatieren? So kann das ja kein Mensch lesen... Sebastian schrieb: > Ich benutze einen Atmega8 intern 8Mhz.Kann mir einer sagen was ich > verändern kann um es zu verschnellern?Der ADC reagiert träge und das > Display. Hast du evtl noch die clkdiv8 Fuse eingeschaltet? BTW: > Ich benutze einen Atmega8 intern 8Mhz.Kann mir einer sagen was ich > verändern kann um es zu verschnellern?Der ADC reagiert träge und das > Display. Nach einem Satzzeichen kommt ein Leerzeichen. Wenn nicht, nennt man das "Klempen".
Läuft das Programm überhaupt? Isr_ovf: Incr Ovf_ct If Ovf_ctr > 122 Then ' <=== wo ist das End If davon? If Ovf_ctr > 126 Then Got_edge = False Ovf_ctr = 0 If Measure_status = Measure_request Then Measure_status = Measure_failed End If Return
Stefan B. schrieb: > If Ovf_ctr > 122 Then ' <=== wo ist das End If davon? Sowas sollte ein Compiler (egal welche Sprache) aber merken und anmeckern... :-o
Hi
>Hast du evtl noch die clkdiv8 Fuse eingeschaltet?
Hat der ATMega8 nicht. Was aber nicht ausschließt, das er nicht mit 8MHz
läuft.
MfG Spess
spess53 schrieb: > Hat der ATMega8 nicht. Schlag$ߧ"#~putt... :-/ > Was aber nicht ausschließt, das er nicht mit 8MHz läuft. Das meinte ich... ;-) Der Controller wird nämlich mit 1MHz internem Oszillator ausgeliefert. Und wenn da am Programmer (!) nichts umgestellt wurde (CKSEL3..0), dann läuft der auch mit 1 MHz. Also die Frage: wurde beim Programmieren auf die richtige Taktquelle umgeschaltet (das allein reicht nicht aus: $crystal = 8000000)?
Also die Fuse bitz sind so gesetzt Int. RC Osc. 8 MHz; Start-up time: 6 CK + 4 ms Brown-out detection level at VCC=2.7 V Serial program downloading (SPI) enabled Boot Flash section size=1024 words Boot start address=0x0C00; default value sonst nichts Divide by 8 habe ich garnicht weiß auch nicht warum das bei dem nicht da ist. Ist aber Atmega8L-8PU. das end if ist irgendwie nicht mit kopiert worden im Programm ist es aber drinne.
Ps es betrift auch nur den ADC der nicht richtig läuft habe ich germerkt die Frequenz wird sofort angezeigt ohne verzögerung.Aber wenn ich die Potis drehe werden die Werte auf dem Display langsam verändert.Kontroll Led für das PWM reagiert auch nur langsam.Sie läßt sich nicht fein dosieren sondern spring von sagen wir mal 10% auf 20% Helligkeit usw. Das wait habe ich jetzt rausgenommen ohne Veränderung.
Sebastian schrieb: > Das wait habe ich jetzt rausgenommen ohne Veränderung. Poste mal dein aktuelles Programm (ohne die angesprochenen Undurchsichtigkeiten) als .bas Anhang. Ich kanns nur wiederholen: Lothar Miller schrieb: > Nach einem Satzzeichen kommt ein Leerzeichen. > Wenn nicht, nennt man das "Klempen".
Lothar Miller schrieb: > Sebastian schrieb: >> Das wait habe ich jetzt rausgenommen ohne Veränderung. > Poste mal dein aktuelles Programm (ohne die angesprochenen > Undurchsichtigkeiten) als .bas Anhang. Aber bitte, formatiere es vorher erst etwas um. Das ist nämlich wirklich nicht vernünftig zu lesen. Einrückungen sind dein Freund! Benutze sie! Am Beispiel deiner Hauptschleife
1 | Do |
2 | Locate 2 , 1 |
3 | |
4 | Measure_status = Measure_request |
5 | While Measure_status = Measure_request |
6 | Wend |
7 | |
8 | If Measure_status = Measure_success Then |
9 | If Measure_result > 0 Then |
10 | Measure_result = Measure_result / 10 |
11 | Frequency = 826787928 / Measure_result |
12 | F_str = Str(frequency) |
13 | Lcd "Freq: " ; Format(f_str , "000.000") ; " Hz" |
14 | Else |
15 | Lcd "Fehler, Ergebnis = 0" |
16 | End If |
17 | End If |
18 | |
19 | Grad = Getadc(0) / 5 |
20 | If Grad > 200 Then Grad = 200 |
21 | |
22 | Locate 1 , 1 |
23 | Lcd Grad ; "ß" |
24 | |
25 | Rpm = Getadc(1) |
26 | If Rpm = 1 Then Rpm = 0 |
27 | If Rpm > 1000 Then Rpm = 1000 |
28 | |
29 | Locate 1 , 7 |
30 | Lcd Rpm ; "Rpm" |
31 | |
32 | Rpm = Rpm / 4 |
33 | Ocr2 = Rpm |
34 | |
35 | If Grad < 60 Then |
36 | Portb.2 = 1 |
37 | Else |
38 | Portb.2 = 0 |
39 | End If |
40 | |
41 | Waitms 30 |
42 | Loop |
43 | |
44 | End |
So ist das schon viel leichter zu lesen, weil einem die Einrückhierarchie sagt, welche Teile zusammen gehören und wo neue Abschnitte anfangen. Durch Leerzeilen wird eine logische Struktur geschaffen, in der zusammengehörende Abschnitte gruppiert werden und man erkennt, wo ein neuer 'Gedankengang' im Programm anfängt.
Ich würde das Hauptprogramm so umstrukturieren, dass die Frequenzmessung parallel zu den ADC Messungen laufen kann und nicht wie bisher auf den Abschluss der Frequenzmessung gewartet wird. Musst du aber prüfen, ob das bei deinem Projekt Sinn macht.
1 | Measure_status = Measure_request ' Erste Frequenzmessung anstoßen |
2 | Do |
3 | ' Frequenz-Messung |
4 | If Measure_status <> Measure_request Then |
5 | ' Frequenzmessung ist abgeschlossen oder fehlgeschlagen |
6 | If Measure_status = Measure_success AND Measure_result > 0 Then |
7 | Gosub Frequenz_Berechnen_und_Ausgeben |
8 | End If |
9 | Measure_status = Measure_request ' nächste Frequenzmessung anstoßen |
10 | End If |
11 | |
12 | ' Grad-Messung (ADC) |
13 | Gosub Grad_Messen_und_Ausgeben |
14 | |
15 | ' RPM-Messung (ADC) |
16 | Gosub PRM_Messen_und_Ausgeben |
17 | Loop |
Innerhalb der Gosubs würde ich neue Roh-Messwerte mit gespeicherten Roh-Messwerten aus der vorherigen Messung vergleichen und die langwierige Berechnung der Ausgabewerte, deren Formatierung und die Ausgabe nur machen, wenn sich beide unterscheiden. In diesem Fall den neuen Messwert als alten Messwert übernehmen.
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.