Brauche Hilfe !
Mein Code macht undefinierbare Probleme - er läuft zwar stabil, doch die Bahn/Rampe wird nicht ordnungsgemäß mit Geschwindigkeit 0 beendet.

Eigentlich soll per CTC-Mode eine Frequenz für eine Schrittmotorendstufe erzeugt werden um bei gegebener Strecke auf ein Speedlimit zu beschneunigen und rechtzeitig vor ende der Strecke auf "Null" abgebremst zu haben.
Ich habe einer Timer auf 200Hz eingestellt um eine Interruptroutine in gleichbleibenden Zeitabständen die Berechnungen durchführen zu lassen.
Im Hauptprogramm wird eigentlich nur ein neuer Durchlauf gestartet und die Ausgabe auf dem Display gemacht.

Problem 1:
ich lasse mir bei jedem Timerereigniss einen Interrupt auslösen, damit ich
die ausgegebenen Pulse genau zählen kann.
Ich lasse eine Variable bei 0 beginnen und hochzählen und am Display anzeigen, die andere Variable zählt von vorgegebener Strecke ( 8000 ) herunter.
In einer If Abfrage wird der Timer gestoppt, wenn auf Null heruntergezählt wurde -> so wünsche ich es mir - aber er macht es nicht !

Es kommt manchmal vor, dass die Routine auf unergründliche Weise viel
früher zum ende kommt, die eine Variable ist nicht bis auf Null runter gekommen , und die andere nicht bei 8000 angekommen - Noch viel dubioser : nicht einmal mit einer rechnerisch erklärbaren Differenz!
Obwohl die beiden Variablen genau untereinander runter/hochgezählt werden , scheint eine von beiden Zeilen manchmal nicht bearbeitet zu werden, da z.B. die eine Variable bei 8000 angekommen ist, die andere aber noch bei weitem nicht bei Null angekommen ist , sie steht z.b. bei 50

Gibt es Jemanden in dieser Gemeinde, der mir das erklären kann ??


Problem 2:
Ich beobachte aber in aller Regel eine große Geschwindigkeit beim ende der Strecke - manchmal bremst er auch zu früh und läuft mit einer minimalen Geschwindigkeit( meine Vorgabe ) zum ende der Strecke.


Code:
$hwstack = 192
$swstack = 192
$framesize = 128
'you might need to raise these numbers if your code grows !!!!!!! (unexpected behaviour of the program often results of too small stacks)

'----------------------------------------------------------------------------------------------------------------------------------

$regfile = "m128def.dat"
$crystal = 16000000                                         'enter the used clock of your actual microcontroller

Declare Sub Geschwindigkeit
Declare Sub Rampe
Declare Sub Timerladen

Const Frq = 16000000                                        '# hier muss die Prozessorfrequenz nochmal rein !!!!
Const T3prescale = 64                                       '# Timer3 Vorteiler
Const T0prescale = 1024                                     '# Timer3 Vorteiler
Const True = 1
Const False = 0
Const Time0 = 78                                            ' für 200Hz Wiederholrate
'##############
'#  A/D Port  #
'##############
Config Adc = Single , Prescaler = Auto , Reference = Internal
'########### FrequenzGenerator mittels Timer0    ###############
Config Timer0 = Timer , Prescale = T0prescale               '###### Interrupr für die Wiederholrate / sekunde
Load Timer0 , Time0
On Ovf0 Timer0_ovf
Enable Timer0
Start Timer0
'########### PWM Generator mittels Timer3, Porta ###############
Stop Timer3
Config Timer3 = Timer , Prescale = T3prescale , Clear Timer = 1 , Compare A = Toggle       ' 1. Achse
On Compare3a Compare_3a_int                                 ' When Timer3 = Compare3A register
Compare3a = 55000                                           ' Load the TimerLimit value into the Compare1A (OCR1A) register

Disable Compare3a


Config Porte.3 = Output
'###############################################################
                                                            'Now we need to select Port B as to an output port (data output to the display)
Ddrb = &B11111111                                           'DDR = Data direction register; All 8 ports switched to output (1)

Ddra = &B00000000                                           'switch all 8 Ports of Port A to input (0), Pin (PA.0 - PA.7)
Porta = &B11111111                                          'All port pins have individually selectable pull-up resistors. Here we enable these pull-up-resisitors, so these Pins are always at logical 1
                                                            'You need to pull these Pins against ground (GND)
Ddrc = &B00000000                                           'switch all Ports of Port C to input
Portc = &B11111111

Ddrd = &B00000000                                           'switch all Ports of Port D to input
Portd = &B11111111                                          'all pull-up-Resistors turned on

'Ddre = &B00000000                                           'switch all Ports of Port E to input
'Porte = &B11111111                                          'all pull-up-Resistors turned on

Ddrf = &B00000000                                           'switch all Ports of Port F to input
Portf = &B11111111                                          'all pull-up-Resistors turned on

Ddrg = &B00000000                                           'switch all Ports of Port G to input
Portg = &B11111111                                          'all pull-up-Resistors turned on
                                         'all pull-up-Resistors turned on

Debug0 Alias Porta.0
Debug1 Alias Porta.1
Debug2 Alias Porta.2
Debug3 Alias Porta.3
Debug4 Alias Porta.4
Debug5 Alias Porta.5
Debug6 Alias Porta.6
Debug7 Alias Porta.7


'##### Variablen #############################################
Dim Problem As Bit
Dim Menudraw As Bit
Dim Init As Bit
Dim Modus As Bit
Dim Continus As Bit
Dim Port As String * 14
Dim Timer3reload As Word
Dim Schrittzaehler As Long
Dim T3basis As Long
Dim T0basis As Long
Dim Wunschspeedlong As Long
Dim Speedakt As Single
Dim Speedquadrat As Single                                  ' Speedakt zum Quadrat
Dim Wiederholrate As Single
Dim Gesamtschritte As Long
Dim Halbschritte As Long
Dim Beschleunischritte As Long
Dim Schritte As Long
Dim Umin As Long                                            ' so viele Schritte sing vom Weg noch übrig
Dim Uminmax As Long
Dim Beschleunigung As Single
Dim Speedlimit As Single
Dim Zeitincrement As Single
Dim Wunschspeed As Single
Dim Minspeed As Single
Dim Tick As Single
Const Fertig = 1
Const Nichtfertig = 0
Dim Schleife As Byte
Dim Untersetzung As Integer
Dim Schritteproumdrehung As Integer
Dim Acc As Single
Dim Speed As Single
Dim Timecount As Long
Dim Count As Long
Dim Sek As Single


 Enable Interrupts
Menudraw = 1
Wunschspeed = 1
Schrittzaehler = 0
Beschleunigung = 30
Speedlimit = 30
Minspeed = 10
Modus = 1
Init = 0
Gesamtschritte = 4000
'############################################################################################
'4 - Definition of used ports and pull up resistors
$include Init21_display3000.bas                             'At our boards we are using Port B for the SPI-communication to the LCD.

   Orientation = Portrait                                   ' fürs Display
   Graphics_mode = 65k_uncompressed                         'select the needed color mode, here 65.536 colors
   Call Lcd_cls

'##################################################################
Start Adc


'##################################################################


T3basis = Frq / T3prescale                                  ' berechnung der Grundgeschwindigkeit aus Frq und Teiler
T0basis = Frq / T0prescale
Wiederholrate = T0basis / Time0
Tick = 1 / Wiederholrate

Do                                                          ' Schleife Hauptprogramm  - eigentlich nur zum anzeigen der Variablen aus dem Display
  Toggle Debug1

  If Schleife = Fertig Then                                 ' Wenn eine Rampe komplett ist
     Waitms 700                                             ' Variablen neu bestücken
     Schleife = Nichtfertig                                 ' um neuen Durchlauf nach Wartezeit starten
     Schrittzaehler = 0
     Gesamtschritte = 8000
     Beschleunigung = Beschleunigung + 100
     Speedlimit = Speedlimit + 200
     Init = 0
     Modus = 1
     Halbschritte = Gesamtschritte / 2
     Uminmax = 0
   End If


'#### Anzeige auf dem LCD zur Kontrolle #########################

   If Menudraw = 1 Then

       Port = "Gesamtschritte"
       Call Lcd_print(port , 8 , 32 , 1 , 1 , 1 , White , Black)

       Port = "Speedakt "
       Call Lcd_print(port , 8 , 45 , 1 , 1 , 1 , White , Black)

       Port = "Schrittzaehl"
       Call Lcd_print(port , 8 , 100 , 1 , 1 , 1 , White , Black)

       Port = "Umin"
       Call Lcd_print(port , 8 , 120 , 1 , 1 , 1 , Green , Black)

       Port = "Modus"
       Call Lcd_print(port , 8 , 130 , 1 , 1 , 1 , Green , Black)

       Port = "sek"
       Call Lcd_print(port , 8 , 150 , 1 , 1 , 1 , Green , Black)


   Menudraw = 0
  End If


   Port = Str(gesamtschritte)
   Port = Format(port , "0000000")
   If Len(port) < 8 Then
    Call Lcd_print(port , 85 , 32 , 1 , 1 , 1 , Green , Black)
   End If

   Port = Fusing(speed , "####.#")
   Port = Format(port , "0000000")
   If Len(port) < 8 Then
    Call Lcd_print(port , 85 , 45 , 1 , 1 , 1 , Blue , Black)
   End If

  Port = Str(schrittzaehler)
   Port = Format(port , "0000000")
   If Len(port) < 8 Then
    Call Lcd_print(port , 85 , 100 , 1 , 1 , 1 , White , Black)
   End If

  Port = Str(uminmax)
   Port = Format(port , "00000.0")
   If Len(port) < 8 Then
    Call Lcd_print(port , 85 , 120 , 1 , 1 , 1 , White , Black)
   End If

  Port = Str(modus)
    Call Lcd_print(port , 85 , 130 , 1 , 1 , 1 , White , Black)

   Port = Fusing(sek , "####.##")
   Port = Format(port , "000000")
   If Len(port) < 8 Then
    Call Lcd_print(port , 85 , 150 , 1 , 1 , 1 , White , Black)
   End If

  Acc = Beschleunigung * Tick                               ' Berechnung der Beschleunigungsrate
Loop

End



'#########################################
'# Timerinterruptrutine       alle 5ms   #
'#########################################
Timer0_ovf:
  Load Timer0 , Time0
   Debug0 = 1
      Incr Count
      Enable Interrupts

  Call Geschwindigkeit                                      ' Gteschwindigkeitsberechnung
      If Init = 0 Then
         Start Timer3
         Enable Compare3a
         Init = 1
      End If

  Call Rampe                                                ' berechnung der Wunschgeschwindigkeit für die Rampe

  Call Timerladen
  Debug0 = 0                                                ' Timer mit Sollwert bestücken
  Return



'################################
'# Compare Interrupt Timer3a    #
'################################
Compare_3a_int:
  If Timer3 < Timer3reload And Problem = True Then Compare3a = Timer3reload       'bei Problemen Timer hier neu laden
  Toggle Porta.6
   Incr Schrittzaehler                                      ' Schrittzaehler hochzählen
   Decr Gesamtschritte                                      ' Gesamtschritte runterzählen

   If Gesamtschritte <= 0 Then                              ' wenn Gesamtschritte auf Null > keine Pulse mehr
         Stop Timer3
         Disable Compare3a
      Schleife = Fertig
      Timecount = Count                                     ' Zeit eines Ablaufes speichern
      Count = 0
    End If

Return


'###################################
'# Sub Geschwindigkeitsberechnung  #
'###################################
Sub Geschwindigkeit
      Speedakt = T3basis / Compare3a                        '#  Frequenzbasis / PWM WERT
      Speed = Speedakt / 2                                  '   / 2   da 2 Interrupte für eine Periode benötigt werden
End Sub

'###################################
'# Sub Beschleunigungsrampe  #
'###################################
Sub Rampe
      Umin = Speedakt * 6                                   '  60 für 1 Min
      Umin = Umin / 8                                       '800  Schritte pro umin &
                                                            ' > zum Anzeigen mit 2 Kommastellen nur durch 8
      If Umin > Uminmax Then                                ' zum Speichern der max. U/min
        Uminmax = Umin
      End If

    If Modus = 1 Then                                       ' wenn beschleunigt wird :
         If Wunschspeed > 0 Then                            ' wenn gefahren werden soll
             If Wunschspeed < Speedlimit Then               ' wenn Speedlimit noch nicht erreicht
                Wunschspeed = Wunschspeed + Acc             ' Berechnung der beschleunigung
                If Schrittzaehler > Halbschritte Then       ' noch in der beschleunigungsphase darf nur die hälfte der Strecke beschleunigt werden
                   Modus = 0
                   Continus = 0
                End If
             Else
                If Continus = 0 Then
                   Beschleunischritte = Schrittzaehler
                   Continus = 1
                End If
                If Beschleunischritte > Gesamtschritte Then
                   Modus = 0
                End If
             End If
         Else
           Wunschspeed = 1
         End If
    Else                                                    ' Bremsung einleiten !!
        If Wunschspeed > 0 Then
          Wunschspeed = Wunschspeed - Acc                   ' Beschleunigungsfaktor abziehen
        Else
          Wunschspeed = 0
        End If
    End If
     Sek = Timecount / Wiederholrate                        ' wie lange hat eine Rampe gesauert
End Sub



Sub Timerladen:                                             ' Timerwert aus "Wunschspeed" errechnen
   If Wunschspeed > 0 Then
        Wunschspeedlong = Wunschspeed
     Timer3reload = T3basis / Wunschspeedlong
   Else
     Timer3reload = 30000
   End If
     If Timer3reload > 30000 Then Timer3reload = 30000      ' Grenzen für den erlaubte werde für die Geschwindigkeit
     If Timer3reload < 10 Then Timer3reload = 10
     If Timer3 < Timer3reload Then
        Compare3a = Timer3reload
        Problem = False
     Else
        Problem = True
     End If
End Sub

$include Glcd21_display3000.bas

$include Glcd21_fonts.bas
'Dummy Data um Fehlermeldungen bei der Kompilierung der Standardroutinen zu vermeiden
'Die Tabelle wird dann bei Nutzung eines indizierten Grafikdatei mit "echten" Daten ausgetauscht
   Colortable:
   Data 0
kann mal bitte jemand sie meinen Code anschauen und konstruktive Kritik
üben - ich bitte darum - ich komme hier nicht weiter - habe schon die berechnung der Bahnsteuerung mit Gleichnungen aus dem Physik-Buch gemacht und da hab ich auch die selben Ergebnisse bekommen.

Ich Programmiere mit der neusten Bascom Version und setzte
einen AT Mega 128 auf einer Platine von Display3000 (D071)ein.


vielen Dank.