-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: Problem Portabfrage alle 25ms

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    03.10.2004
    Alter
    50
    Beiträge
    50

    Problem Portabfrage alle 25ms

    Anzeige

    Hallo Forum,

    Ich möchte über einen Atmega8 3,686 Mhz getaktet.
    Den Portd.3 alle 25ms abfragen ob dieser Port auf Masse liegt.
    Dieses soll genau 10 Sekunden dauern.
    Dann müsste ich ja 400 Werte bekommen, das ist nicht der Fall.
    Ich bekomme mal 307,317,323,... Werte heraus nie die 400.
    Code:
    $regfile = "m8def.dat"
    $crystal = 3686400
    $baud = 9600                                                'Baudrate der UART: 9600 Baud
    
    Config Timer1 = Timer , Prescale = 64
    On Timer1 Timer_irq
    Const Timervorgabe = 7936                                   ' Const 7936
    
    
     Ddrd = &B00000000
     Ddrc = &B11111111
    Portd = &B11111111
    
    
    Dim Sekunden As Byte
    Dim P3 As Byte
    Dim P4 As Byte
    Dim A As Byte
    Dim T0 As Long
    Dim T1 As Long
    Dim E1 As Long
    Declare Sub Ledon
    Declare Sub Main
    Declare Sub Abfragen
    Declare Sub Ende
    Declare Sub Zler1
    
    Enable Timer1
    Enable Interrupts
    
    
    Main:
    '----------------------------------------------------------
    '########   einschalten Portd.2  ####################
    '----------------------------------------------------------
    Do
      Debounce Pind.2 , 0 , Abfragen , Sub                      'Entprellt
    Loop
    
    
    '----------------------------------------------------------
    '########   Abfrage des Portd.3  ###################
    '----------------------------------------------------------
    Abfragen:
    
    Portc.3 = 1                                                 
    
    A = 0
    
    Do
    
    Zler1:
    
    Waitms 25
    
    P3 = Pind.3
    
    If P3 = 0 Then
        Portc.1 = 1                                             'Led An 
    '    Portc.2 = 1                                             ' Summer an Portc.2 an
        A = A + 1
        Print " A " ; A
      If A = 8 Then
         Goto Ledon
      End If
          Goto Zler1
        Else
        Portc.1 = 0                                             'Led Aus 
    '    Portc.2 = 0                                             ' Summer an Portc.2 aus
        A = 0
    End If
    
    
    Loop
    
    '----------------------------------------------------------
    '############ Led und Summer  #############################
    '----------------------------------------------------------
    
    Ledon:
    
    T0 = 0
    T1 = 0
    
    Print "S"                                                   'Senden ein S über RS232
    Sekunden = 0                                                ' Sek auf 0 stellen dass die 10 S
    
    Do
    If Sekunden < 1 Then
       Portc.0 = 1                                              'Led zeigt 10 Sek.an
    '   Print "  " ; Sekunden                                   ' Kontrolle der Skunden
        Else
        Portc.0 = 0                                             'Led wird aus geschaltet
    '    Sekunden = 0                                            'Sekunden werden auf 0 gestzt
       Goto Ende
    End If
    
    'Print Pind.4 ; "  "                                        ' Kontrolle des Portsd.4
    P4 = Pind.3
      If P4 = 1 Then
    '     Print "0"                                              'Senden ein 0 über RS232
         Portc.1 = 0                                            ' Led aus Portc.1
         Portc.2 = 0                                            ' Summer an Portc.2 aus
         T0 = T0 + 1
         Print "0" ; " " ; T0
       Else
    '   Print "1"                                                'Senden ein 1 über RS232
         Portc.1 = 1                                            ' Led ein Portc.1
         Portc.2 = 1                                            ' Summer an Portc.2 ein
         T1 = T1 + 1
         Print "1" ; " " ; T1
           End If
    
    Waitms 25                                                   ' Abfrage alle 25 ms
    
    
    Loop
    
    '------------------------------------------------------------
    '#######   Ende  ###############
    '------------------------------------------------------------
    
    Ende:
    
    E1 = T0 + T1
    Print "E"                                                   'Senden ein E über RS232
    Print "  "
    Print "  "
    Print "   Treffer = " ; T1
    Print " N.Treffer = " ; T0
    Print "  "
    Print "   Gesammt = " ; E1
    Print "  "
    Print "   Sekunde = " ; Sekunden
    Print "  "
    Print "  "
    
    T0 = 0
    T1 = 0
    Sekunden = 0
    
    Portc.1 = 0                                                 ' Led an Portc.1 aus
    Portc.2 = 0                                                 ' Summer aus Portc.2
    Portc.3 = 0                                                 ' Laser einschalten
    
    Goto Main
    
    '-------------------------------------------------------------
    '##########   Timer Skundenbasis #############################
    '-------------------------------------------------------------
    
    Timer_irq:
    Timer1 = Timervorgabe
    Incr Sekunden
    Return
    
    End
    Kann mir jemand helfen welche Werte falsch sind.

    mfg
    Enterprise

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    28.05.2007
    Ort
    Mannheim
    Alter
    30
    Beiträge
    270

    -

    Das ist ganz einfach:
    dein Controller wartet 25ms, danach überprüft er den Portstatus, vergleicht ihn und reagiert drauf. Das alles braucht auch nochmal Zeit.
    schon alleine das senden von " A " (3 Bytes) benötigt bei 9600 Baud etwa 3ms.
    und wenn der Pin das 8. mal in folge auf Null ist, dann macht der Controller ja noch mehr...
    Desshalb nimmt er effektiv nicht alle 25ms den Portstatus auf, sondern immer in unterschiedlichen Abständen.
    Je nach dem ob der Pin 0 oder 1 ist und wie oft der Pin auf 0 ist, dauert es immer länger als 25 ms bis der nächste Wert abgefragt wird.
    Und desshalb hast du auch immer unterschiedlich viele Werte. Die Anzahl hängt halt davon ab wie oft der Pin auf 0 war.

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    46
    Beiträge
    765
    Du solltest die 400 Werte erstmal zwischenspeichern und sie dann anschließend auswerten.

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    31
    Beiträge
    4.255
    Oder den 25ms-Abfragetakt über einen Timer erzeugen...

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    03.10.2004
    Alter
    50
    Beiträge
    50
    Danke für die Infos.

    Kann das funktionieren mit 25ms und über die RS232 zu übertragen.

    Es soll in Echtzeit über die RS232 übertragen werden, also mit

    zwischen speichern ist nicht.

    UWEGW Wie könnte ich das mit dem Timer einrichten ?


    mfg
    Enterprise

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    46
    Beiträge
    765
    Ich habe mir das noch mal genauer angesehen. Du könntest Zeit sparen, indem du nicht in jeder Schleife p3=pind.3 zuweist, sondern ganz oben ein p3 alias pind.3. Dann könntest du den Timer auf 25 ms einstellen. Alle 40 Durchläufe setzt du dann sekunden eins hoch. So hast du deine 25ms. Dann natürlich die wait25ms rausnehmen und aus der do loop Schleife ein sub machen, welches vom Timer alle 25ms angesprungen wird.

    Config Timer1 = Timer , Prescale = 8
    On Timer1 Timer_irq
    Const Timervorgabe = 54016 ' Const 7936

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    03.10.2004
    Alter
    50
    Beiträge
    50
    Hallo,

    Habe versucht deine Aussage um zu setzen.
    Habe warscheinlich etwas nicht richtig verstanden.
    Das Hauptprogramm fängt erst bei Ledon: an.
    Die Definition P3 habe ich jetzt nur einmal.
    Habe eine FOR Next Schleife eingebaut das war glaube ich nicht richtig.
    Den Zusammenhang vom Interupt ins Programmspringen habe ich noch nicht richtig verstanden wo ?
    Kannst du mir vielleicht zeigen wo ich die Änderungen machen soll.


    Code:
    $regfile = "m8def.dat"
    $crystal = 3686400
    $baud = 9600                                                'Baudrate der UART: 9600 Baud
    
    'Config Timer1 = Timer , Prescale = 64
    'On Timer1 Timer_irq
    'Const Timervorgabe = 7936                                   ' Const 7936
    
    Config Timer1 = Timer , Prescale = 8
    On Timer1 Timer_irq
    Const Timervorgabe = 54016 
    
     Ddrd = &B00000000
     Ddrc = &B11111111
    Portd = &B11111111
    
    
    Dim Sekunden As Byte
    Dim P3 As Byte
    Dim P4 As Byte
    Dim A As Byte
    Dim T0 As Long
    Dim T1 As Long
    Dim E1 As Long
    Dim Durchl40 As Long
    Declare Sub Durchlauf10s
    Declare Sub Ledon
    Declare Sub Main
    Declare Sub Abfragen
    Declare Sub Ende
    Declare Sub Zler1
    
    Enable Timer1
    Enable Interrupts
    
    
    Main:
    
    P3 = Pind.3
    
    '----------------------------------------------------------
    '########   einschalten Portd.2  ####################
    '----------------------------------------------------------
    Do
      Debounce Pind.2 , 0 , Abfragen , Sub                      'Entprellt
    Loop
    
    
    '----------------------------------------------------------
    '########   Abfrage des Portd.3  ###################
    '----------------------------------------------------------
    Abfragen:
    
    Portc.3 = 1                                                 
    
    A = 0
    
    Do
    
    Zler1:
    
    Waitms 25
    
    'P3 = Pind.3
    
    If P3 = 0 Then
        Portc.1 = 1                                             'Led An
    '    Portc.2 = 1                                             ' Summer an Portc.2 an
        A = A + 1
        Print " A " ; A
      If A = 8 Then
         Goto Ledon
      End If
          Goto Zler1
        Else
        Portc.1 = 0                                             'Led Aus
    '    Portc.2 = 0                                             ' Summer an Portc.2 aus
        A = 0
    End If
    
    
    Loop
    
    '----------------------------------------------------------
    '############ Led und Summer  #############################
    '----------------------------------------------------------
    
    Ledon:
    
    T0 = 0
    T1 = 0
    
    Print "S"                                                   'Senden ein S über RS232
    Sekunden = 0                                                ' Sek auf 0 stellen dass die 10 S
    
    'Do
    For I = 1 to 40
    
    If Sekunden < 10 Then
       Portc.0 = 1                                              'Led zeigt 10 Sek.an
    '   Print "  " ; Sekunden                                   ' Kontrolle der Skunden
        Else
        Portc.0 = 0                                             'Led wird aus geschaltet
    '    Sekunden = 0                                            'Sekunden werden auf 0 gestzt
       Goto Ende
    End If
    
    'Print Pind.4 ; "  "                                        ' Kontrolle des Portsd.4
    P4 = Pind.3
      If P4 = 1 Then
    '     Print "0"                                              'Senden ein 0 über RS232
         Portc.1 = 0                                            ' Led aus Portc.1
         Portc.2 = 0                                            ' Summer an Portc.2 aus
         T0 = T0 + 1
         Print "0" ; " " ; T0
       Else
    '   Print "1"                                                'Senden ein 1 über RS232
         Portc.1 = 1                                            ' Led ein Portc.1
         Portc.2 = 1                                            ' Summer an Portc.2 ein
         T1 = T1 + 1
         Print "1" ; " " ; T1
           End If
    
    'Waitms 25                                                   ' Abfrage alle 25 ms
    'Loop
    
    Next I
    
    '------------------------------------------------------------
    '#######   Ende  ###############
    '------------------------------------------------------------
    
    Ende:
    
    E1 = T0 + T1
    Print "E"                                                   'Senden ein E über RS232
    Print "  "
    Print "  "
    Print "   Treffer = " ; T1
    Print " N.Treffer = " ; T0
    Print "  "
    Print "   Gesammt = " ; E1
    Print "  "
    Print "   Sekunde = " ; Sekunden
    Print "  "
    Print "  "
    
    T0 = 0
    T1 = 0
    Sekunden = 0
    
    Portc.1 = 0                                                 ' Led an Portc.1 aus
    Portc.2 = 0                                                 ' Summer aus Portc.2
    Portc.3 = 0                                                 ' Laser einschalten
    
    Goto Main
    
    '-------------------------------------------------------------
    '##########   Timer Skundenbasis #############################
    '-------------------------------------------------------------
    
    Timer_irq:
    Timer1 = Timervorgabe
    Incr Sekunden
    Return
    
    End
    mfg
    Enterprise

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    46
    Beiträge
    765
    So, mein erster Entwurf. Musst evtl noch Fehler ausmerzen, habe gerade keine Zeit zum testen.

    Du könntest mehr Reserve rausholen, wenn du nen schnelleren Quarz nimmst, die Baudrate erhöhst, den Code optimierst...

    Code:
    $regfile = "m8def.dat"
    $crystal = 3686400
    $baud = 9600                                                'Baudrate der UART: 9600 Baud
    
    'Config Timer1 = Timer , Prescale = 64
    'On Timer1 Timer_irq
    'Const Timervorgabe = 7936                                   ' Const 7936
    
    Config Timer1 = Timer , Prescale = 8
    On Timer1 Timer_irq
    Const Timervorgabe = 54016
    
     Ddrd = &B00000000
     Ddrc = &B11111111
    Portd = &B11111111
    
    
    Dim Sek As Byte
    Dim Sekunden As Byte
    Dim P3 As Byte
    Dim P4 As Byte
    Dim A As Byte
    Dim T0 As Long
    Dim T1 As Long
    Dim E1 As Long
    Dim Durchl40 As Long
    Declare Sub Durchlauf10s
    Declare Sub Ledon
    Declare Sub Main
    Declare Sub Abfragen
    Declare Sub Ende
    Declare Sub Zler1
    
    Config Portc.1 = Output
    Config Portc.2 = Output
    Config Portc.3 = Output
    Config Portd.2 = Input
    
    
    
    Enable Timer1
    Enable Interrupts
    
    
    'Main:
    
    Led1 Alias Portc.1
    Summer Alias Portc.2
    Laser Alias Portc.3
    
    P3 Alias Pind.3
    Eingang Alias Pind.2
    
    'P4 Alias Pind.3
    
    Main:
    Sek = 0
    
    
    
    '----------------------------------------------------------
    '########   einschalten Portd.2  ####################
    '----------------------------------------------------------
    'Do
    '  Debounce Pind.2 , 0 , Abfragen , Sub                      'Entprellt
    'Loop
    
    
    '----------------------------------------------------------
    '########   Abfrage des Portd.3  ###################
    '----------------------------------------------------------
    Sub Abfragen()
    
       Set Laser                                                   'Portc.3 = 1
    
       'A = 0
    
       'Do
    
       Zler1:
    
       'Waitms 25
    
       'P3 = Pind.3
    
       If P3 = 0 Then
          Set Led1                                                 'Led An
       '   set summer                                             ' Summer an Portc.2 an
           A = A + 1
           Print " A " ; A
           If A = 8 Then
              Gosub Ledon
           End If
           'Goto Zler1
       Else
           Reset Led1                                              'Led Aus
       '    reset summer                                             ' Summer an Portc.2 aus
           A = 0
       End If
    
    
       End Sub
       'loop
    
    '----------------------------------------------------------
    '############ Led und Summer  #############################
    '----------------------------------------------------------
    
    Ledon:
    A = 0
    T0 = 0
    T1 = 0
    
    Print "S"                                                   'Senden ein S über RS232
    Sekunden = 0                                                ' Sek auf 0 stellen dass die 10 S
    
    'Do
    'For I = 1 to 40
    
    If Sekunden < 10 Then
       Portc.0 = 1                                              'Led zeigt 10 Sek.an
    '   Print "  " ; Sekunden                                   ' Kontrolle der Skunden
        Else
        Portc.0 = 0                                             'Led wird aus geschaltet
    '    Sekunden = 0                                            'Sekunden werden auf 0 gestzt
       Goto Ende
    End If
    
    'Print Pind.4 ; "  "                                        ' Kontrolle des Portsd.4
    If P4 = 1 Then
    '     Print "0"                                              'Senden ein 0 über RS232
         Portc.1 = 0                                            ' Led aus Portc.1
         Portc.2 = 0                                            ' Summer an Portc.2 aus
         T0 = T0 + 1
         Print "0" ; " " ; T0
       Else
    '   Print "1"                                                'Senden ein 1 über RS232
         Portc.1 = 1                                            ' Led ein Portc.1
         Portc.2 = 1                                            ' Summer an Portc.2 ein
         T1 = T1 + 1
         Print "1" ; " " ; T1
    End If
    Return
    'Waitms 25                                                   ' Abfrage alle 25 ms
    'Loop
    
    'Next I
    
    '------------------------------------------------------------
    '#######   Ende  ###############
    '------------------------------------------------------------
    
    Ende:
    
    E1 = T0 + T1
    Print "E"                                                   'Senden ein E über RS232
    Print "  "
    Print "  "
    Print "   Treffer = " ; T1
    Print " N.Treffer = " ; T0
    Print "  "
    Print "   Gesammt = " ; E1
    Print "  "
    Print "   Sekunde = " ; Sekunden
    Print "  "
    Print "  "
    
    T0 = 0
    T1 = 0
    Sekunden = 0
    
    Reset Led1                                                  ' Led an Portc.1 aus
    Reset Summer                                                ' Summer aus Portc.2
    Reset Summer                                                ' Laser einschalten
    Goto Main
    
    '-------------------------------------------------------------
    '##########   Timer Skundenbasis #############################
    '-------------------------------------------------------------
    
    Timer_irq:
       Timer1 = Timervorgabe
       Sek = Sek + 1
       If Sek = 40 Then
          Incr Sekunden
          Sek = 0
       End If
       Call Abfragen
       If Sekunden = 10 Then
          Sekunden = 0
          Goto Ende
       End If
    
    return
    
    End

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    03.10.2004
    Alter
    50
    Beiträge
    50
    Danke peterfido,

    Habe deine Verbesserungen in mein Script eingebaut.
    Nun funktioniert es.


    Diese Anweißung hat bei mir nicht funktioniert.

    Config Portc.1 = Output
    Config Portc.2 = Output
    Config Portc.3 = Output
    Config Portd.2 = Input

    Habe es dann so geändert.

    Config Portc = Output
    Config Portd = Input


    Wie kann man den Timer1 Ausschalten ?
    So dass, er nicht den Interrupt alle 25ms startet.


    mfg
    Enterprise

  10. #10
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    46
    Beiträge
    765
    DAfür gibt es disable timer1

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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