-         

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

Thema: Attiny2313, Timer-Counter-Wie gehts?

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    14.03.2006
    Beiträge
    6

    Attiny2313, Timer-Counter-Wie gehts?

    Anzeige

    Hallo zusammen,
    ich habe vor kurzem angefangen im Assember AVM-Mikroprozessadoren zu programmieren. Jetzt bin ich vor ein für mich unlösbares Problem gestoßen.
    Wie ist es möglich während einem laufenden Programm das einen Ausgang aktiviert, diesen in einem Gewissen Takt ein und auszuschalten. Das ganze soll ca. die Geschwindigkeit eines Andreaskreuzes am Bahnübergang haben.

    Ich habe folgenden funktionierenden Code geschrieben:
    ;************************************************* *************
    .include "tn2313def.inc" ; Definitionen für Attiny2313 *
    ;************************************************* *************

    ; Schrankensteuerung Modelleisenbahn
    ; Interner RC-Oszi, 1MHz, Tiny 45
    ; Stand: 03.03.2006
    ;
    ; Software um eine Bahnschranke bei durchfahren der Lichtschranke durch
    ; den Modellzug zu schließen und nach vollständigem Austritt des Zuges
    ; incl. dessen Anhänger aus dem Schrankenbereich wieder zu öffnen
    ;
    ; PORTB
    ; PB0: IN P Lichtschranke 1
    ; PB1: IN P Lichtschranke 2
    ; PB2: OUT - Schranke oeffnen (High aktiv)
    ; PB3: OUT - Schranke schließen (High aktiv)
    ; PB4: OUT - Andreaskreuz
    ; PB5: OUT - Andreaskreuz
    ; merker1 Durchfahrene Lichtschranke 1
    ; merker2 Durvhfahrene Lichtschranke 2

    ; Register Definition

    ; General Purpose
    .def a = r16 ;Register 16 als a definieren
    .def b = r17 ;Register 17 als b definieren

    ; Interrupt
    ; .def i_a = r19 ;Wird nicht benötigt
    ; .def sSREG = r1
    .DEF merker1 = r21 ;Register 21 wird als merker1 definiert
    .DEF merker2 = r22 ;Register 22 wird als merker2 definiert

    RESET: ldi a, low(RAMEND) ;Lade in a low(RAMEND)
    out SPL, a ;Gebe a im SPL aus

    ;IO-Init
    ldi a, 0b11111111 ;Lade in a die Hex-Zahl
    out PORTB, a ;Gebe a an PORTB aus / initialisierung des Ports
    ldi a, 0b00111100 ;Lade in a Hex-Zahl
    out DDRB, a ;Gebe a an DDRB aus / 0==Eingang; 1==Ausgang

    cbi PORTB,2 ;Setze Ausgang PB,2 auf Low
    cbi PORTB,3 ;Setze Ausgang PB,3 auf Low
    cbi PORTB,4 ;Setze Ausgang PB,4 auf Low
    cbi PORTB,5 ;Setze Ausgang PB,5 auf Low

    rjmp oeffnen ;Springe zu oeffnen

    start: CLR merker1 ;Lade die Zahl 0 in merker1
    CLR merker2 ;Lade die Zahl 0 in merker2

    ls1: sbic PINB, 0
    rjmp ls2 ;Wenn PB0!=0 springe zu ls2
    CPI merker1,1
    BREQ ls11 ;Wenn merker1==1 springe zu ls11
    CPI merker2,1
    BREQ ls11 ;Wenn merker2==1 springe zu ls11
    ldi merker1 ,1 ;Setze merker1 auf High (1)

    ldi a, 20 ;Pause von 20*10ms
    rcall WAIT_M ;um beim Steckerziehen eine schließung zu vermeiden

    sbi PORTB,3 ;Setze Ausgang PB3 auf High /
    ;Anfang Schranke schließen
    sbi PORTB,4 ;Andreaskreuz aktvieren
    sbi PORTB,5
    ldi a, 50
    rcall WAIT_M ;Pause von 50*10ms
    cbi portb,3 ;Setze Ausgang PB3 auf Low /
    ;Ende Schranke schließen

    ls11: CPI merker2,1
    BREQ warten ;Wenn merker2==1 springe zu warten

    ls2: sbic PINB, 1
    rjmp ls1 ;Wenn PB1!=0 springe zu ls1
    CPI merker2,1
    BREQ ls22 ;Wenn merker2==1 springe zu ls22
    CPI merker1,1
    BREQ ls22 ;Wenn merker1==1 springe zu ls22
    ldi merker2, 1 ;Setze merker2 auf High (1)

    ldi a, 20 ;Pause von 20*10ms
    rcall WAIT_M ;um beim Steckerziehen eine schließung zu vermeiden

    sbi PORTB,3 ;Setze Ausgang PB3 auf High /
    ;Anfang Schranke schließen
    sbi PORTB,4 ;Andreaskreuz aktvieren
    sbi PORTB,5
    ldi a, 50
    rcall WAIT_M ;Pause von 50*10ms
    cbi portb,3 ;Setze Ausgang PB3 auf Low /
    ;Ende Schranke schließen

    ls22: CPI merker1,0
    BREQ ls1 ;Wenn merker1==0 springe zu ls1

    ;Die folgende warten-Schleife wird mehrmals durchlaufen
    ;um die Abstände zwischen den Anhängern zu überbrücken

    warten: ldi R25, 0b01111111 ;Lade in das Register25 die Hex Zahl (dez:127) /
    ;Ein Takt benötigt 1ys
    warten0: sbis PINB, 0
    rjmp warten ;Wenn PB0==1 springe zu warten
    sbis PINB, 1
    rjmp warten ;Wenn PB1==1 springe zu warten
    ldi a, 1
    rcall WAIT_M ;Pause von 1*10ms
    DEC R25 ;Decrementierung des Wertes im Register 25 um 1
    BRNE warten0 ;Wenn die Zahl im R25!=0 ist springe zu warten0

    oeffnen: sbi portb,2 ;Setze Ausgang PB2 auf High / Anfang Schranke öffnen
    cbi PORTB,4 ;Andreaskreuz deaktvieren
    cbi PORTB,5
    ldi a, 50
    rcall WAIT_M ;Pause von 50*10ms
    cbi portb,2 ;Setze Ausgang PB2 auf Low / Ende Schranke öffnen
    rjmp start ;Springe zu start

    ;Zeitschleife
    ;Übergabe: a - Länge= 10ms * a (a:1..255)

    WAIT_M:
    WM_0: ldi b, 0xFF
    WM_1: lpm
    lpm
    lpm
    lpm
    lpm
    lpm
    lpm
    lpm
    lpm
    lpm
    lpm
    lpm
    lpm
    lpm
    wdr
    wdr
    dec b
    brne WM_1
    dec a
    brne WM_0
    ret

    Kann mir jemand helfen wie ich den PB4 und PB5 nach der aktivierung zum blinken bringe und nach der deaktivierung durch das Programm wieder zum ausschalten??

    Viele liebe Gruesse

    Sebastian Frei

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    17.02.2005
    Ort
    Erfurt
    Alter
    52
    Beiträge
    134
    Mit einem Timer problemlos möglich

    Vielleicht kannst Du Dir dort ein paar Anregungen holen

    http://www.mikrocontroller.net/forum/read-4-159103.html

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    14.03.2006
    Beiträge
    6
    Vielen Dank für deine Antwort.

    So wie dieser verlinkte Timer funktioniert konnte ich im AVM-Studio simulieren. Das wäre auch genau das was ich bräuchte, nur leider funktioniert das Programm so nicht für den Attiny2313.
    Dort bringt er eine Fehlermeldung beim Stack. Da habe ich einfach den SPH rausgelöscht, da der bei dem controller nicht zur Verfügung steht. Aber der Timer läuft dann nur einmal durch und hängt dann.

    An was liegt das? Wie kann ich das problem lösen. Ich bröuchte also nur einen Timer anlegen und dieser bei Überlauf (ca. alle 2 Sekunden) ins verlinkte programm springen. Wer kann mir weiterhelfen??

    Gruss Sebastian

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    17.02.2005
    Ort
    Erfurt
    Alter
    52
    Beiträge
    134
    Sebastian

    >Aber der Timer läuft dann nur einmal durch und hängt dann.

    vielleicht hast Du nur den "reti" Befehl vergessen ?

    Bei solchen Problemchen ist es immer besser, wenn Du uns den kompletten Programm-Code zur Verfügung stellst.

    Sonst "orakeln" wir nur

    Trotzdem, großes LOB an Dich, denn Du programmierst sehr übersichtlich und nachvollziehbar.


    Bernhard

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    14.03.2006
    Beiträge
    6
    Hallo Bernhard,

    vielen Dank für die schnelle Rückantwort. Ich habe das Hauptprogramm herausgelöscht um mich auf das wesentliche zu konzentrieren. Es geht also nur um den Timer. Der läuft auch einmal durch, aber dann glaube ich fast, dass ihm der Stack fehlt um wieder zurückzuspringen.
    Ehrlich gesagt habe ich noch nicht viel Ahnung in sachen Mikrocontroller, aber ich bin fleißig dabei mir das ganze anzueignen. Ich bin dabei ein Buch durchzulesen, aber leider verstehe ich noch nicht alles. Na ja dieses Semester werde ich noch microcontroller bekommen.

    Na ja egal. Kannst du mir bitte helfen, damit ich das ganze für den Attiny 2313 zum laufen bekomme. Wäre echt nett.

    Bis dann und viele liebe Gruesse

    Sebastian

    Der Quellcode ist im Anhang ersichtlich
    Angehängte Dateien Angehängte Dateien

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Schickst du auch mal 40€ vorbei für's WinRAR?
    Disclaimer: none. Sue me.

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    14.03.2006
    Beiträge
    6
    Sorry,
    im Anhang als Zip-Datei.

    Gruesse

    Sebastian
    Angehängte Dateien Angehängte Dateien

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Das sieht doch ok aus, bis auf die Initialisierung des SP, denn SL hat nach dem Reset nen zufälligen Wert.
    Disclaimer: none. Sue me.

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    17.02.2005
    Ort
    Erfurt
    Alter
    52
    Beiträge
    134
    @Sebastian

    Der Fehler lag bei den Interrupt-Vektoren,
    ich habe sie aus dem Datenblatt herauskopiert
    und bei Dir eingefügt.
    Der µC sprang auf die falsche Adresse und bekam sofort ein reti

    Immer aufpassen, wenn Du für einen anderen µC die Software anpasst,
    nicht nur die include "2313def.inc" ändern, Die Vektoren sin leider meistens unterschiedlich.

    Ein paar Vereinfachungen habe ich auch gleich mit vorgenommen,
    denn mit Resourcen muss man sehr geizen

    Die Interrupt-Routine habe ich Dir auch gleich vernünftig vorbereitet,
    denn alle Register müssen gesichert werden die beim Interrupt benötigt werden, sonst gibt es unangenehme Fehlfunktionen des Programmes und man(n) sucht stundenlang.

    Viel Spaß

    Bernhard
    Angehängte Dateien Angehängte Dateien

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    17.02.2005
    Ort
    Erfurt
    Alter
    52
    Beiträge
    134
    kleine Änderung in der Timer-Routine

    ; Timerwert neu einstellen
    ldi temp,timerwert
    mov tsw,temp
    out tcnt0,tsw

    bitte ändern in:

    ; Timerwert neu einstellen
    out tcnt0,tsw

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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