Forum: Mikrocontroller und Digitale Elektronik Programm läuft träge


von Sebastian (Gast)


Lesenswert?

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

von lowlevel (Gast)


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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".

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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)?

von Sebastian (Gast)


Lesenswert?

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.

von Sebastian (Gast)


Lesenswert?

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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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".

von Karl H. (kbuchegg)


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.