PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Attiny2313, Timer-Counter-Wie gehts?



sebastian.fr
14.03.2006, 22:28
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

Bernhard.Erfurt
25.03.2006, 02:05
Mit einem Timer problemlos möglich

Vielleicht kannst Du Dir dort ein paar Anregungen holen

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

sebastian.fr
26.03.2006, 20:53
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

Bernhard.Erfurt
26.03.2006, 21:01
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

sebastian.fr
27.03.2006, 18:51
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

SprinterSB
27.03.2006, 19:23
Schickst du auch mal 40€ vorbei für's WinRAR?

sebastian.fr
27.03.2006, 19:41
Sorry,
im Anhang als Zip-Datei.

Gruesse

Sebastian

SprinterSB
27.03.2006, 19:57
Das sieht doch ok aus, bis auf die Initialisierung des SP, denn SL hat nach dem Reset nen zufälligen Wert.

Bernhard.Erfurt
27.03.2006, 20:59
@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

Bernhard.Erfurt
27.03.2006, 21:03
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

sebastian.fr
28.03.2006, 23:45
Hallo ihr zwei,

vielen Dank schon mal für eure super Hilfen. Ich hatte heute nicht viel Zeit mich damit zu beschäftigen. Aber der erste Versuch hat auf jeden Fall mal geklappt. Merci...

Mal schauen wies weitergeht!!! Am Wochende werde ich mich nochmals dransetzen.. So long..

Sebastian

Bernhard.Erfurt
29.03.2006, 00:35
Gern geschehen

Unsere BANK-DATEN geben wir Dir später ;)

Gruß Bernhard

sebastian.fr
04.04.2006, 22:22
Hallo nochmal,

das mit den Bankdaten sollte eigentlich klar gehen, fehlt nur noch die Kohle, die ich ggf. mal in ferner Zukunft verdienen werde.. *scherz.

Ich habe das Programm jetzt fertig. Alles funktioniert Dank eurer Mithilfe. Ich würde mich jedoch trotzdem freuen wenn ihr einen Blick darüberwerfen könntet um mir mitzuteilen ob das so auch "absturzsicher" programmiert ist. Eure Tips sind alle umgesetzt worden und freuen sich auf weitere.

Vielen Dank und viele liebe Gruesse

Sebastian

Bernhard.Erfurt
04.04.2006, 22:48
>fehlt nur noch die Kohle, die ich ggf. mal in ferner Zukunft verdienen >werde.. *scherz.

..verdienen werde.... ? Mag sein, dass Du vielleicht jetzt noch keine verdienst, aber vielleicht erhälst Du jetzt schon welche ??? ;)

Hab mal kurz Deinen Code überflogen, konnte nichts auffälliges finden.

Bernhard