-         

Ergebnis 1 bis 10 von 10

Thema: ?? Falsche Taktfrequenz vorgaukeln bei ATMega8 ??

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    17.01.2006
    Ort
    Homberg (Efze)/Nordhessen
    Alter
    32
    Beiträge
    207

    ?? Falsche Taktfrequenz vorgaukeln bei ATMega8 ??

    Anzeige

    Hallo,

    es geht um folgendes: Ich habe eine Anwendung mit Display und schnell wechselnden Werten.
    In der Hauptschleife befindet sich ein gosub befehl über den in jedem Programmdurchlauf ein mal das Sub zur aktualisierung der Displaywerte aufgerufen wird.

    Wenn das Programm läuft werden die Displaywerte aber für diese Verhältnisse sehr langsam aktualisiert (ich schätze mal so alle 10-50ms), jedenfalls ist ein ganz leichtes flackern beim überschreiben zu sehen, wenn sich ein Wert schnell ändert (man dreht z.B. schnell ein Poti) dann scheint er zu springen. Das ist sehr unschön und auch die Tasterabfrage läuft so schlecht, dass gern mal ein Tastendruck der per debounce in der Hauptschleife einfach "übersehen" wird.

    Wenn ich nun den $crystal auf 1.600.000 statt 16.000.000 stelle, funktioniert alles wunderbar so wie ich das möchte.

    Jetzt bin ich etwas irritiert: Ich dachte bisher immer, dass pro Takt ein kompletter Programmdurchlauf stattfindet. Nach dieser Feststellung wäre das aber widerlegt.

    Kann mir jemand genauer erklären was es mit dem Verhältnis von Taktfrequenz und Programmabarbeitung auf sich hat?
    Und wie kann ich dann errechnen wie lange ein Programmdurchlauf dauert? (bei mir scheint es im Moment im Millisekundenbereich zu sein was ich für höchst unglaubwürdig halte)
    Und vor allem: Wer hat eine Idee wie ich mein Problem lösen kann ohne dem Controller einen falschen Takt vorgaukeln zu müssen?

    Edit: Ja ich habe einen 16Mhz externen Quarz auf dem Board, Ich habe auch das Fusebit in Bascom geändert (1111: External XTAL)
    Grüße Paul

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    17.04.2006
    Beiträge
    2.193
    Ohoh, massive Fehlinformiertheit. Ein Taktzyklus führt bei den AVRs idR einen Maschinen(!!!)befehl aus, einer Deiner Basic-Befehle kann zu einigen zehn Maschinenbefehlen führen, Du bist da ziemlich komplett dem Compiler ausgeliefert. Mit C sieht's etwas besser aus, aber wirklich ausrechnen kann man das nur im Maschinencode. Millisekunden ist aber durchaus denkbar.

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    17.01.2006
    Ort
    Homberg (Efze)/Nordhessen
    Alter
    32
    Beiträge
    207
    und wäre es dann legitim mein Problem mit dem vorgaukeln einer geringerer Taktfrequenz zu lösen? Ich verstehe dann aber immer noch nicht wie er das Programm dann schneller abarbeitet, bleibt doch die Anzahl der Befehle und die tatsächliche Taktfrequenz die gleiche
    Grüße Paul

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    14.05.2004
    Alter
    36
    Beiträge
    170
    Also mit Bascom kenne ich mich nicht aus, aber es wird definitiv nicht mit jedem Takt das Programm einmal durchlaufen! Das kann ja auch nicht sein, weil ein großes Programm (in der Regel) viel länger braucht.

    Jeder Befehl braucht einige Takte zeit, genau weiß ich auch nicht wieviel...
    Noch als Hinweis: Beim AVRStudio kann man die Takte und die benötigte Zeit ablesen, die benötigt werden in der Simulation. Geht vielleicht bei Bascom auch?

    Und noch was:
    Der Schwindel mit der Frequenz könnte sich auf Pausenzeiten auswirken, hast du welche drin, dann mach die mal kürzer?!

  5. #5
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    17.01.2006
    Ort
    Homberg (Efze)/Nordhessen
    Alter
    32
    Beiträge
    207
    Hi,

    also ich poste euch mal meinen code. ich habe einen waitms befehl drin und einen pulsein befehl. Allerdings ändert sich an der Tatsache auch nichts wenn ich die beiden befehle aus dem Programm nehme, habe ich eben ausprobiert.

    Code:
    '*******************************************************************************
    '* PROGRAMM: RPM-ControllerV1.0BETA  DATUM: 02.07.2007                         *
    '*******************************************************************************
    
    '===============================================================================
    ' Hardware:
    '
    ' RN-Minicontrol Controllerboard mit Mega8
    '
    ' RPM-Controllermodul V1.0, Anschluss an JP5 von RN-Minicontrol
    '
    ' RN-LCD-Adaptermodul, Anschluss an 10-pol Wannenbuchse CTRL, Anschluss der
    ' LCD Bedientaster: T1 an JP6/1, T2 an JP6/2, GND an JP6/4, T3 an JP1/1
    '
    ' Potentiometer an JP3
    '
    '
    '
    '===============================================================================
    
    
    
    '===============================================================================
    ' Compiler
    '===============================================================================
     $regfile = "m168def.dat"                                   'Mega8
     $crystal = 16000000                                        '16Mhz Quarz
     '$baud = 9600
    '-------------------------------------------------------------------------------
    
    
    '===============================================================================
    ' Ein- und Ausgänge:
    '
    ' PD4: Ausgang, Ansteuerung von ZU-Relais
    ' PB4: Eingang, Rechtecksignal der Zündspannung
    ' PC1: ADC1 Eingang, Potentiometer von JP4 zur Drehzahleinstellung
    ' PD5: Eingang, LCD Taster 1
    ' PB2: Eingang, LCD Taster 2
    ' PD2: Eingang, LCD Taster 3
    '
    '
    '===============================================================================
    
    Config Pind.4 = Output                                      'ZU-Relais
    Config Pinb.4 = Input                                       'Zündspannung
    Config Pinc.1 = Input                                       'Poti
    Config Pind.5 = Input
    Portd.5 = 1                                                 'Taster1
    Config Pinb.2 = Input
    Portb.2 = 1                                                 'Taster2
    Config Pind.2 = Input
    Portd.2 = 1                                                 'Taster3
    '-------------------------------------------------------------------------------
    
    '===============================================================================
    ' ADC-Kanäle
    '===============================================================================
    Config Adc = Single , Prescaler = Auto , Reference = Avcc
    Start Adc
    
    Config Debounce = 5
    '-------------------------------------------------------------------------------
    
    '===============================================================================
    ' Variablen
    '===============================================================================
     Dim Signal_in As Word                                      'eingangsimpulse in 1x10µs
     Dim Rpm_ist As Long                                        'Istwert Drehzahl
     Dim Adc1 As Word                                           'Eingangswert Poti 0-1023
     Dim Rpm_soll As Word                                       'Sollwert Drehzahlbegrenzung
     Dim Faktor As Byte                                         'Drehzahlfaktor
     Dim Unterbrecherdauer As Byte                              'Einschaltdauer Unterbrecher
     Dim Unterbrecherfrequenz As Byte                           'Zuschaltfrequenz Unterbrecher
     Dim Timerunterbrecher As Byte                              'Timing für Unterbrecher
     Dim Rpm_dif As Word                                        'Differenz Soll und Ist
    '-------------------------------------------------------------------------------
    
    '===============================================================================
    ' Variablenvoreinstellung bei Programmstart
    '===============================================================================
    Faktor = 1
    Unterbrecherdauer = 10
    Unterbrecherfrequenz = 200
    '-------------------------------------------------------------------------------
    
    
    '===============================================================================
    ' Subs
    '===============================================================================
     Declare Sub Displayaktualisierung
     Declare Sub Faktoreinstellung
     Declare Sub Unterbrecherdauer
     Declare Sub Unterbrecherfrequenz
     Declare Sub Unterbrecher
    '-------------------------------------------------------------------------------
    
    '===============================================================================
    '    LCD Parametrieren
    '-------------------------------------------------------------------------------
    
    Config Lcd = 20 * 4a , Chipset = Ks077
    Config Lcdpin = Pin , Db4 = Portb.5 , Db5 = Portb.0 , Db6 = Portd.7 , Db7 = Portd.6 , E = Portb.3 , Rs = Portc.2
    Config Lcdbus = 4
    
    Initlcd
    
    Config Pind.3 = Output                                      'R/W = 0 -> Schreiben
    Portd.3 = 0
    
    Config Pinc.3 = Output                                      'Portc.3 = 0 -> Beleuchtung aus
    Portc.3 = 0
    
    Waitms 200
    
    Initlcd
    
    Locate 1 , 1
    Cls
    Locate 2 , 1
    Cls
    Locate 3 , 1
    Cls
    Locate 4 , 1
    Cls
    
    '*******************************************************************************
    '* HAUPTPROGRAMM                                                               *
    '*******************************************************************************
    
     Do
    
    
    '===============================================================================
    '    Datenerfassung Drehzahl
    '-------------------------------------------------------------------------------
    
     'Pulsein Signal_in , Pinb , 4 , 0
    
       Rpm_ist = 1500000 / Signal_in
    
       Rpm_ist = Rpm_ist * Faktor
    
    '-------------------------------------------------------------------------------
    
    '===============================================================================
    '    Aufruf Displayaktualisierung
    '-------------------------------------------------------------------------------
    
    
       Gosub Displayaktualisierung
    
    
    '-------------------------------------------------------------------------------
    
    '===============================================================================
    '    Counter für Zündunterbrechung
    '-------------------------------------------------------------------------------
    
     Incr Timerunterbrecher
    
       If Timerunterbrecher = Unterbrecherfrequenz Then
       Gosub Unterbrecher
    
     End If
    
    '-------------------------------------------------------------------------------
    
    '===============================================================================
    '    Abfrage Tastereingabe
    '-------------------------------------------------------------------------------
    
     Debounce Pind.2 , 0 , Faktoreinstellung , Sub
    
     Debounce Pind.5 , 0 , Unterbrecherdauer , Sub
    
     Debounce Pinb.2 , 0 , Unterbrecherfrequenz , Sub
    
     '-------------------------------------------------------------------------------
    
     Loop
    
    
    '-------------------------------------------------------------------------------
    
    '*******************************************************************************
    '* SUBS                                                                        *
    '*******************************************************************************
    
    
    'OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
       Sub Displayaktualisierung
    'OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
    
    '===============================================================================
    '  Zeile 1: Anzeigen der Ist-Drehzahl
    '-------------------------------------------------------------------------------
       If Rpm_ist < 5000 Then
    
       Locate 1 , 6
       Lcd "     "
    
          Locate 1 , 1
          Lcd "RPM= " ; Rpm_ist
          Locate 1 , 10
          Lcd "U/min"
    
    
    
    
       End If
    '-------------------------------------------------------------------------------
    
    
    '===============================================================================
    '  Zeile 1: Bargraph-Animation
    '-------------------------------------------------------------------------------
    
       Rpm_dif = Rpm_soll - Rpm_ist
    
       Locate 1 , 16
       Lcd "     "
    
          If Rpm_dif < 2000 Then
          Locate 1 , 16
          Lcd ">    "
          End If
    
             If Rpm_dif < 1600 Then
             Locate 1 , 16
             Lcd ">>   "
             End If
    
                If Rpm_dif < 1200 Then
                Locate 1 , 16
                Lcd ">>>  "
                End If
    
                   If Rpm_dif < 800 Then
                   Locate 1 , 16
                   Lcd ">>>> "
                   End If
    
                      If Rpm_dif < 400 Then
                      Locate 1 , 16
                      Lcd ">>>>>"
                      End If
    
    
    '-------------------------------------------------------------------------------
    
    
    '===============================================================================
    '  Zeile 2:  Anzeige Soll-Drehzahl
    '-------------------------------------------------------------------------------
    
       Locate 2 , 11
       Lcd "     "
    
       Adc1 = Getadc(1)
       Rpm_soll = Adc1 * 15
    
       Locate 2 , 1
       Lcd "RPM-Limit=" ; Rpm_soll
       Locate 2 , 16
       Lcd "U/min"
    
    '-------------------------------------------------------------------------------
    
    
    '===============================================================================
    '  Zeile 3:   Anzeige Drehzahlfaktor
    '-------------------------------------------------------------------------------
    
    Locate 3 , 16
    Lcd " "
    
    Locate 3 , 1
    Lcd "Drehzahlfaktor " ; Faktor
    
    '-------------------------------------------------------------------------------
    
    
    '===============================================================================
    '  Zeile 4:   Anzeige Unterbrecherdauer und -Frequenz
    '-------------------------------------------------------------------------------
    
    Locate 4 , 7
    Lcd "   "
    Locate 4 , 18
    Lcd "   "
    
    Locate 4 , 1
    Lcd "Dauer=" ; Unterbrecherdauer
    Locate 4 , 10
    Lcd "ms"
    Locate 4 , 13
    Lcd "Freq=" ; Unterbrecherfrequenz
    
    
    '-------------------------------------------------------------------------------
    
    
    End Sub
    '===============================================================================
    
    
    
    'OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
       Sub Faktoreinstellung
    'OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
    
    If Faktor = 1 Then
    
       Faktor = 2
       Return
    
    End If
    
    
    If Faktor = 2 Then
    
       Faktor = 4
       Return
    
    End If
    
    
    If Faktor = 4 Then
    
       Faktor = 1
       Return
    
    End If
    
    
    
    End Sub
    '===============================================================================
    
    
    'OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
       Sub Unterbrecherdauer
    'OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
    
       Unterbrecherdauer = Unterbrecherdauer + 10
    
       If Unterbrecherdauer > 150 Then
       Unterbrecherdauer = 10
       End If
    
    
    
    End Sub
    '===============================================================================
    
    
    'OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
       Sub Unterbrecherfrequenz
    'OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
    
       Unterbrecherfrequenz = Unterbrecherfrequenz + 10
    
       If Unterbrecherfrequenz > 240 Then
       Unterbrecherfrequenz = 50
       End If
    
    End Sub
    '===============================================================================
    
    
    'OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
       Sub Unterbrecher
    'OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
    
       If Rpm_ist > Rpm_soll Then
       Portd.4 = 1
       'Waitus Unterbrecherdauer
       Portd.4 = 0
       End If
    
    End Sub
    '===============================================================================
    
    
    '===
     End
    '===
    Grüße Paul

  6. #6
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    17.01.2006
    Ort
    Homberg (Efze)/Nordhessen
    Alter
    32
    Beiträge
    207
    Hmm... mein Verdacht fällt immer mehr auf die Fusebits...

    Dort kann man mehrere Ext. Crystals auswählen aber von 16 Mhz ist da nie die Rede. Auch im Datenblatt steht was von "For resonators, the maximum frequency is 8 MHz with CKOPT unprogrammed and
    16 MHz with CKOPT programmed."
    Was bitte ist jetzt CKOPT, und was bedeutet CKOPT programmed?
    Grüße Paul

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    10.12.2004
    Ort
    LEV
    Beiträge
    505
    Hallo,
    einige Zeilen höher im Datenblatt ist auch die Funktion der CKOPT Fuse
    beschrieben:

    "The CKOPT Fuse selects between two different Oscillator amplifier modes.
    When CKOPT is programmed, the Oscillator output will oscillate a full
    rail-to-rail swing on the output. This mode is suitable when operating
    in a very noisy environment or when the output from XTAL2 drives
    a second clock buffer. This mode has a wide frequency range.
    When CKOPT is unprogrammed, the Oscillator has a smaller output swing.
    This reduces power consumption considerably. This mode has a limited
    frequency range and it cannot be used to drive other clock buffers."

    Gruß Jan

  8. #8
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    17.01.2006
    Ort
    Homberg (Efze)/Nordhessen
    Alter
    32
    Beiträge
    207
    Hi,

    ja, das habe ich mir auch durchgelesen, bloß finde ich im Bascom Programmer weit und breit nichts vom CKOPT

    Ich müsste nur wissen wie man in Bascom einstellt dass man einen externen Quarz verwendet, dann wäre ich schon glücklich.
    Grüße Paul

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    10.07.2004
    Ort
    Nürnberg
    Alter
    36
    Beiträge
    186
    Hi,
    ich stelle mir meine Fuses immer mit PonyProg ein! Ist schön buntes Microsoft Prinzip!
    Da klickst du einfach auf das Schlosssymbol dann erscheint eine Tafel mit allen FuseBits die dein Controller hat, dann klickst du auf read, dann zeigts dir an was wie gesetzt ist, Häckchen bedeuted unprogrammed! Dann machst du Häckchen dazu oder weg und klickst auf write!
    Fertig, ist Super einfach!!
    Achja und wie ich die setzen muss schau ich hier nach:http://palmavr.sourceforge.net/cgi-bin/fc.cgi
    Viel Erfolg
    Ich bin keine Signatur ich mach hier nur sauber

  10. #10
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    11.04.2005
    Beiträge
    1.469
    Hi,
    Ich verstehe dann aber immer noch nicht wie er das Programm dann schneller abarbeitet, bleibt doch die Anzahl der Befehle und die tatsächliche Taktfrequenz die gleiche
    Bascom berechnet die Wartezeiten für's Display aus deiner Angabe der Taktfrequenz. Wenn du keine extra Library verwendest, muss RW auf GND liegen. Dadurch kannst du aber das Busy Flag des Displays nicht auslesen.
    Um sicherzugehen, daß das Display bereit für neue Daten ist, legt Bascom eben eine kleine Pause ein.
    Diese ist allerdings so lange gewählt, daß es 100%ig auch immer mit jedem Display geht.
    Die meisten Displays sind aber schneller mit dem Verarbeiten der Daten fertig.
    Wenn du Bascom jetzt eine niedrigere Quarzfrequenz vorlügst, macht der Compiler die Wartezeiten eben kürzer.
    Bei den Displays, die ich so verwende, geht's bis auf ein viertel der Wartezeit einwandfrei.
    Wenn du also eine niedrigere Taktfrequenz angibst, werden auch die Wartezeiten kürzer.
    Das daß natürlich keine saubere Lösung ist, ist klar.
    Es ändern sich ja auch alle anderen Zeiten.
    Der UART läuft dann auch anderer Datenrate, alle wait Befehle stimmen dann nicht mehr etc.
    Man muss da schon höllisch aufpassen

    Beispiel:
    $crystal = 4000000 ' Bei Quarz 16 MHz
    Baud = 4800 'Baudrate ist 19200 BPS
    waitms = 400 'Wartezeit ist 100ms

    Besser wäre es, das Busy Flag abzufragen zb. mit der lcd4busy.lib.
    Damit sollte die Displayausgabe schneller gehen.

    Gruß
    Christopher

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •