- fchao-Sinus-Wechselrichter AliExpress         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 23

Thema: Riesen Problem mit Int0, Timer1 und Impulszählung

  1. #11
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    30.10.2005
    Ort
    Mönchengladbach
    Alter
    54
    Beiträge
    114
    Anzeige

    Praxistest und DIY Projekte
    Zitat Zitat von Guy
    Beim AVR kannst du keine zwei Interrrupt gleichzeitig ausführen, oder aus einem Interrrupt in einen andren springen.
    Bist Du sicher? Im WinAVR gibt es zwei Macros (SIGNAL und INTERRUPT), sie unterscheiden sich darin, dass bei SIGNAL Inteterrupts nicht unterbrochen werden können, bei INTERRUPT wohl.

    Problematisch wirds doch dann erst, wenn ein Interrupt sich selbst unterbricht, was bei einem einfachen Zähler-Inkrement in einem Counter Overflow wohl kaum su erwarten ist.

    Allerdings würde dadurch auch während der Abarbeitung der Sekunden-Routine kein Zählimpuls verloren gehen.

  2. #12
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    14.12.2005
    Beiträge
    161
    ...jetzt kenn ich mich gar net mer aus...

    Ich habe bisher nur begrenzte Erfahrung mit der Proggerei.

    Zitat Zitat von Guy
    Es gibt noch eine andre Möglichkeit. Du läßt das Programm in einer DO Schleife laufen. wartest immer auf steigende oder fallende Flanke und Zählst dann jedesmal eine Variable hohe, und machst dann deine Brechungen. Die Berechnungen dürfen aber auch nicht zulange dauern weil sonst auch Impulse verlorengehen können. Mit dem Timer Springst du dann jede Sekunde zur Ausgabe. Aber auch hier besteht das Risiko das währen der abarbeiteung dieser Routine Impulse verloren gehen.
    Also aus dem Bauch raus gefällt mir die Lösung. Da komm ich auch Kopfmäßig noch mit
    Das kommt meiner Bisherigen Routine am nächsten. Da ich mit dem hochzählen einer Variablen besser zurecht komme.

    Ich hab allerdings sowas mit den Timern als Counter noch nie gemacht. Wie konfiguriere ich dann den Timer1 das bei jeder Flankenänderung (ob steigend oder fallend) eine Variable hochgezählt wird? Kurzes Beispiel wäre super.

    Gruß
    Markus

  3. #13
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    14.12.2005
    Beiträge
    161
    Hallo Guy

    jetzt hab ich aber das nächste Problem. Ist mir gerade eingefallen:

    Den 16bit Timer1 brauche ich als counter aber mit dem Timer0 bekomme ich ja gar keine Sekunde hin. Dann würde die Ausgabe ja längsten 15mal in der Sekunde kommen. Das müllt mir ja die RS232 zu.

    Und nu??? Hast Du eine Idee? Ich bin hier voll am Ende.

    Gruß
    Markus

  4. #14
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.04.2005
    Ort
    Aarau
    Alter
    41
    Beiträge
    982
    hallo markus

    du kannst ja im timer0 interrupt einfach ne variabel raufzählen und wen sie auf 15 ist, variabel auf null setzen und dein wert ausgeben...

    gruss bluesmash

  5. #15
    Benutzer Stammmitglied
    Registriert seit
    14.09.2005
    Alter
    68
    Beiträge
    77
    So könntest du das machen. Timer1 zählt die Impulse. Mit Timer0 springst du 15 mal in der Sekunde in die Timer_irq Routine. Dort machst du einen Zähler. Wenn der Zähler 15 erreicht hat = 1 Sekunde, dann gibst du den Wehrte aus.
    Code:
    Dim Zahler_timer As Integer
    
    Config Timer1 = Counter , Edge = Falling
    'oder Edge = Rising
    
    $regfile = "m16def.dat"
    $crystal = 3686400
    $baud = 9600
    
    Config Timer0 = Timer , Prescale = 1024
    On Timer0 Timer_irq
    Const Timervorgabe = 16
    
    Enable Timer0
    Enable Timer1
    
    Enable Interrupts
    
    Do
    Loop
    End
    
    Timer_irq:
      Timer0 = Timervorgabe
      Zahler_timer = Zahler_timer + 1
       If Zahler_timer => 15 Then
          Print Timer1
          Timer1 = 0
          Zahler_timer = 0
        End If
       Return
    Eine andre Möglichkeit ist den Timer0 zum zählen der Impulse benutzen. Dann bei jedem Überlauf in eine Unterroutine springen und jedes mal 255 zu einer Variable rechnen. Bei 1 Sekunde diese Variable + den Timer0 ausgeben.

    Am besten währe es wenn du einen Controller mit zwei 16 Bit Timern nimmst.

    Um dir mal den Unterschied zwischen Timer und Counter zu erklären. Im Prinzip ist es sehr einfach. Jeder Timer ist nur ein Counter. Mit Config Timer1 = Counter oder Config Timer1 = Timer entscheidest du nur was der Counter Zählt. Interner Takt oder externer Takt.


    @xanadu
    Ob das jetzt an Bascom oder am AVR liegt kann ich auch nicht hundertprozentig sagen. Nur bei Bascom ist es mal so. Aber wenn das möglich ist aus einem INTERRUPT in einen andren zuspringen, dann muß man auch Prioritäten setzten können. Es ist ja nicht immer erwünscht wegen einen unwichtigen INTERRUPT einen wichtigen zu unterbrechen.

  6. #16
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    14.12.2005
    Beiträge
    161
    Hallo Bluesmash,

    ...mensch logisch! Hab da gerade voll die Hirnblockade gehabt.

    Jetzt geht es.


    Aber mal was anderes. Wie bekomme ich es hin, das eine Long-Variable die über RS232 vom Impulsmesser gesand wird auf einem LCD beim Empfänger auch richtig angezeigt wird.

    Es ist so, das ich im Terminalprogramm den Zahlenwert wunderbar sehe so wie er tatsächlich ist, auf dem LCD aber nicht.

    Konkret:

    Mein Impulsmesser sendet jede Sekunde über RS232 mit "Pirint Impulswert" den Zahlenwert. (von 0 - kann bis 100.000 hochlaufen) diese Variable "Impulswert" ist beim Sender eine Long-Variable. Schließe ich an die RS232 das Terminalprogramm an sehe ich wunderbar die Zahlen hochlaufen.

    Schließe ich aber einen anderen Mega8 mit LCD an kommt anstelle der Zahl nur undefinierbarer Müll auf dem Display.

    Display geht, da alle anderen Sachen wunderbar angezeigt werden.

    Code beim Empfänger:

    Code:
    $regfile = "m8def.dat"
    $crystal = 3686400
    $baud = 19200
    
    Dim Impulswert As Long
     
    Config Lcd = 20 * 4                                    
    Config Lcdpin = Pin , E = Portd.3 , Rs = Portd.2 , Db7 = Portd.7 , Db6 = Portd.6 , Db5 = Portd.5 , Db4 = Portd.4
    
    
    CLS
    Lcd "Impulswert:"
    
    Do
    
    Impulswert = Inkey()
    
    Locate 1, 13
    Lcd Dfmimpulse
    
    Loop
    Ich hab es schon mit "Input", "Inputbin", "waitkey()" usw. probiert. Jedesmal kommt was anderes undefinierbares.

    Eine Idee?

    Gruß
    Markus

  7. #17
    Benutzer Stammmitglied
    Registriert seit
    14.09.2005
    Alter
    68
    Beiträge
    77
    Also wenn ich das richtig verstehe sendest du von einem Controller zum andren über die RS232. Wenn ich jetzt deine zwei Programme sehe die du hier rein gestellt hast, dann hast du im Sender $baud = 9600 eingestellt, und im Empfänger $baud = 19200. Das würde natürlich den Müll erklären.

  8. #18
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    14.12.2005
    Beiträge
    161
    Hallo Guy,

    uhps.. Schreibfehler. Beide laufen auf der gleichen Baudrate von 9600.

    Sorry.

    Gruß
    Markus

  9. #19
    Benutzer Stammmitglied
    Registriert seit
    14.09.2005
    Alter
    68
    Beiträge
    77
    OK, Inkey gibt dir den ASCII code zurück. Das heißt du muß den wieder umwandeln mit Chr(xy)

  10. #20
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    30.10.2005
    Ort
    Mönchengladbach
    Alter
    54
    Beiträge
    114
    Zitat Zitat von Guy
    Aber wenn das möglich ist aus einem INTERRUPT in einen andren zuspringen, dann muß man auch Prioritäten setzten können. Es ist ja nicht immer erwünscht wegen einen unwichtigen INTERRUPT einen wichtigen zu unterbrechen.
    Aus dem Datenblatt vom Atmega 32:

    "The interrupts have priority in accordance with their
    interrupt vector position. The lower the interrupt vector address, the higher the priority."

    Die höchste Prio haben die externen Interrupts, danach kommen die Timer.

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

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

Labornetzteil AliExpress