www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PIC - Probleme mit Timer


Autor: Julian W. (julian-w) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich wollte mir ein kleines Programm schreiben, dass folgendes macht:

Zählt von 90 runter (jede Sekunde wird 1 abgezogen) bis null und dann 
wieder von vorne.

Als Ausgabe benutzte ich ein HD44780-LCD Display, als PIC hab ich einen 
PIC16F84A, der mit 4 MHZ getaktet ist.

Die Ausgabe am Display funktioniert, jedoch zählt das Programm einfach 
nicht runter.

Programmablauf:
-Display initalisieren
-Timer initalisiern
-Wort "TIMER" am Display ausgeben

Timer:
-Interrupts auschalten
-Status sichern
-Bis 15 zählen (1 Sekunden)
 - Sekunden 1 abzeiehen (wenn null, wieder Standardwert setzten)
 - In einer und zehner zerteilen
 - Am Display ausgeben
-Status wiederherstellen
-Interrupts erlauben

Info's zum Programm
-Timer: Vorverteiler 256:1, komme auf etwa 15,2 Interrupts pro Sekunde
-Ausgabe: Display sollte immer zur 9. Stelle springen
-Variablen:
  -Sekunde - speichert die kompletten Sekunden
  -Zehner - speichert die Zehnerstelle der Sekunden
  -Einer - speichert die Einerstelle der Sekunden

-HexDec: Teil das Register Sekunden in die Einer und Zehner
-Display: Die Routinen sind von sprut und funktionieren auch


Wäre über Hilfe dankbar!

MfG
Julian

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es könnte nicht schaden loops3 bei main auch einen
Startwert zu geben. Sonst musst du evtl. 17 Sekunden
warten bevor das erste mal runtergezählt wird.

Diese beiden Zeilen in der Interruptroutine löschen
  bcf     INTCON, GIE
  bsf     INTCON, GIE

Das hier:

Int_end
  swapf  s_copy, w  ; STATUS zur�ck
  movwf  STATUS
  swapf  w_copy, f  ; w zur�ck mit flags
  swapf  w_copy, w

  bcf     INTCON, T0IF    ; Interrupt-Flag l�schen
    bsf     INTCON, GIE     ; enable Interrupt (macht RETFIE aber auch 
allein)

    retfie


änderst du besser so:


Int_end
  bcf     INTCON, T0IF    ; Interrupt-Flag l�schen

  swapf  s_copy, w  ; STATUS zur�ck
  movwf  STATUS
  swapf  w_copy, f  ; w zur�ck mit flags
  swapf  w_copy, w

  retfie

Autor: Julian W. (julian-w) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hab den Code geändert, funzt aber trotzdem nicht (hab 1min gewartet, um 
zu testen, ob es evtl. an der Timerconfig liegt, ist aber nichts 
passiert) :(

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
movlw  B'00001111'  ; pull-up, internen Takt z�hlen, Vorteiler 256:1
  movwf  OPTION_REG

Da liegt der Vorteiler glaube ich auf dem WDT. ;)
Was kann man überhaupt auf dem Display sehen?

Autor: Julian W. (julian-w) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auf dem Display wird immer nur "Timer" ausgegeben.
Der Timer wird aber ausgelöst, wenn ich nämlich zu Anfang z.B. einfach 
eine 1 Ausgebe, ist direkt das ganze Display voll mit einsen.

Code:
[...]

  org    0x00
  goto   main

  org    0x04
intvec

  movwf  w_copy    ; w retten
  swapf  STATUS, w   ; STATUS retten
  bcf  STATUS, RP0  ; Bank 0
  movwf  s_copy

  movlw  '1'
  movwf  LcdDaten
  call  OutLcdDaten

[...]

Interrupts scheinen also ausgelöst zu werden. Auch die Loops3-"Schleife" 
(ist ja keine wirkliche Schleife) funktioniert (wenn ich da den Code zur 
Ausgabe ans Display setzte), nur nachdem er von den Sekunden 1 abgezogen 
hat, gibt es Porbleme. Er springt nämlicher dann immer zu Ende_zählen.

Beispiel:

Code:
[...]

; Intrupt servic routine
Int_serv

  ; Pr�fen, ob 1Sek vorbei ist
  decfsz  loops3, F
  goto    Int_end

  movlw  '1'
  movwf  LcdDaten
  call  OutLcdDaten

  ; Z�hlervariable neu setzten
  movlw Z�hler
  movwf loops3

  ; 1 Sekunde abziehen, wenn 0, von vorne z�hlen
  decfsz sekunden, F
  goto Ende_z�hlen

  movlw  '2'
  movwf  LcdDaten
  call  OutLcdDaten

[...]

Ende_zählen
  movlw  '3'
  movwf  LcdDaten
  call  OutLcdDaten
[...]

Hier erschienen nur 1 und 3 auf dem Display

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>nur nachdem er von den Sekunden 1 abgezogen
>hat, gibt es Porbleme. Er springt nämlicher dann immer zu Ende_zählen.

>  ; 1 Sekunde abziehen, wenn 0, von vorne z�hlen
>  decfsz sekunden, F
>  goto Ende_z�hlen

Das hast du ja auch so programmiert ;)
Über  goto Ende_z�hlen springt er nur wenn
sekunden 0 ist.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Über  goto Ende_z�hlen springt er nur wenn
>sekunden 0 ist.

Korrektur: wenn sekunden 0 wird nach dem dekrement.

Autor: Julian W. (julian-w) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nunja, müsstest den ganzen Code lesen. Die [...] bedeuten nämlich, dass 
da gekürzt wurde. In wirklichkeit steht da:

Ende_zählen
  ; Sekunden 0, deshab Wert wieder setzten
  movlw Max_Sekunden
  movwf sekunden

und damit sollte sekunden wieder 90 sein (ist der Wert von Max_Sekunden 
z.Z.)

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Über  goto Ende_z�hlen springt er nur wenn
>sekunden 0 ist.

Vieleicht etwas schlecht formuliert.
goto Ende_z�hlen wird ausgeführt solange
sekunden nicht 0 ist nach dem dekrement.

Autor: Julian W. (julian-w) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Stimme. Kleiner Denkfehler gemacht. Dürfte aber so gehen:

decfsz sekunden, F
goto Sekunde_NN

goto Ende_zählen

Sekunde_NN

Autor: Julian W. (julian-w) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Code funktioniert aber auch nicht :(

Am Display steht nur:
TIMER   )( SEK

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Am Display steht nur:
>TIMER   )( SEK

Dann funktioniert HexDec wohl nicht!

Autor: Julian W. (julian-w) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nunja, HexDec sollte funzen, da diese Routine aus einem funktionierendem 
Projekt (Kurzzeittimer, ist hier im Forum) ist.
Auch ändert sich die Zeichen nie, was sie ja eigentlich sollten, da die 
Variable sekunden stendig verringert wird.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  movlw sekunden

Was ist hier falsch?

Autor: Julian W. (julian-w) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
holger wrote:
>>  movlw sekunden
>
> Was ist hier falsch?

Würde mal sagen: nichs.
Kommt aber darauf an, wo das steht.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>>  movlw sekunden
>> Was ist hier falsch?

>Würde mal sagen: nichs.

Oh doch, übersetze den Befehl

Bewege Konstante sekunden (0x27) nach w.

Wie wäre es mit einem movwf sekunden?

Autor: Julian W. (julian-w) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nunja, wenn ich jetzt noch wüsst, wo das steht, wäre das nicht schlecht. 
Hab es nur einmal hier gefunden:

Code:
 ; Einer und Zehner berechnen
 movlw sekunden
 movwf temp

 call HexDec

Und hier soll der Wert von sekunden nach temp kopiert werden. Stimmt 
doch, oder?

Autor: Julian W. (julian-w) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder wäre das hier richtig?:

Code:
 ; Einer und Zehner berechnen
 movf sekunden, 0
 movwf temp

 call HexDec

Autor: Sven Stefan (stepp64) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, movlw kopiert die Adresse von Sekunden nach W also 0x27. Wenn du 
den Inhalt von sekunden nach W haben willst, musst du movfw schreiben. 
OK?

Sven

Autor: Julian W. (julian-w) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab nochmal bei Sprut geschaut, da steht folgendes (der Befehl movfw ist 
gar nicht aufgeführt):

MOVF
Kopiere den Inhalt der Speicherzelle f nach...

 wenn d=0:
 Der Inhalt der Speicherzelle f wird in das Arbeitsregister kopiert

 wenn d=1
 Der Inhalt der Speicherzelle wird in die selbe Speicherzelle kopiert.
 Es passiert also gar nichts. Allerdings kann man dadurch prüfen, ob in
 der Speicherzelle der Wert 0 steht, da dann das Zero-Flag gesetzt
 werden würde.

MOVWF
Kopiere den Inhalt von W in die Speicherzelle f

MOVLW
Kopiere einen Zahl (k) nach W

Und ich will den Wert von sekunden in W haben, damit ich diesen später 
in temp laden kann, also schreibe ich dafür:

Code:
  movf sekunden, w ;Inhalt von sekunden nach w kopieren
  movwf temp       ;Inhalt von w nach temp kopieren

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>MOVF
>Kopiere den Inhalt der Speicherzelle f nach...

Richtich der war das! Tschuldigung kenn mich mit Assembler
nicht so gut aus.

Autor: Sven Stefan (stepp64) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Julian W. wrote:

>
> Und ich will den Wert von sekunden in W haben, damit ich diesen später
> in temp laden kann, also schreibe ich dafür:
>
> Code:
>   movf sekunden, w ;Inhalt von sekunden nach w kopieren
>   movwf temp       ;Inhalt von w nach temp kopieren

Ja, das ist so richtig.

Es gibt aber noch die Pseudo- oder auch Spezialbefehle. Unter denen 
befindet sich der Befehl movfw. Er macht genau das selbe wie movf 
blabla,w.

Die Pseudobefehle kennt nur der Assembler. Er übersetzt sie in die 
entsprechenden "echten" Befehle. Ich nutze eigentlich nur movfw von 
diesen Befehlen. Die anderen eigentlich nicht.

Sven

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.