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.