Timer0 blicke nicht ganz durch !!!
Dienstag, 22. Mai 2012
 
 

PIC Mikrocontroller Forum  |  PIC Mikrocontroller  |  Programmiersprache Assembler  |  Timer (Assembler)  |  Timer0 blicke nicht ganz durch !!! « vorheriges nächstes »
Seiten: [1] Nach unten Drucken
Autor Thema: Timer0 blicke nicht ganz durch !!!  (Gelesen 4161 mal)
 
theborg
Full Member
***
Offline Offline

Beiträge: 216



Profil anzeigen WWW
« am: November 25, 2006, 22:18:28 »

Hi irgendwie blicke ich durch das FAQ bei sprut.de nicht durch ich möchte den timer0 dafür nutzen das ein laufender Motor bei Taster Berührung gestoppt wird und dann für 1-2s in den Rückwarts gang geht hat kann mir jemand dabei mal helfen ?

Soweit ich verstanden habe muss ich den timer0 starten und bei taster Berührung Reseten so das er von vorne anfegt zu Zählen wen er einmal durch ist setzt er ein bit das ich abfragen kann in der zwischenzeit lasse ich den Motor rückwärts laufen bis das bit gesetzt ist sobald das bit gesetzt ist kann ich dann normal mit meinen Programm fortfahren.

Nur wie ich das mache hab ich keine Ahnung.
Gespeichert

Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 969



Profil anzeigen WWW
« Antworten #1 am: November 26, 2006, 11:49:45 »

zunächst wollen wir wissen: welchen PIC nutzt du und wie Fragst du die Tasten ab (Polling oder Interrupt) ?

Um 1 Sekunde rückwärts zu laufen, musst du ja wissen, wie weit du zählen musst. Die Zeit, die der Timer0 verzögert errechnet sich wie folgt:
(Dauer eines Befehls) * Prescalerwert * (Anzahl Befehle bis zum überlauf)
Abhängig davon stellst du den entsprechenden Prescalerwert ein, und löscht das T0CS-Bit, damit der Zähler seinen Takt vom interenen Oszillator bekommt. Den Timer0 kann man nicht explizit anhalten oder stoppen, du musst also jedes mal, wenn eine Taste gedrückt wird, den Zählerstand neu laden. Ob der Timer0 nun übergelaufen ist, setzt er das Bit T0IF im INTCON-Register. Du kannst das entweder per Polling abfragen oder einen Interrupt auslösen lassen.

Beispiel:
Dein PIC läuft mir 4Mhz, du willst 1s verzögern. Ein Befehl dauert dann 1µs (1*10^-6s). Um eine Sekunde zu "erzeugen" müssen 1s/1µs-Schritte gezählt werden, dh eine Millionen Befehle. Bei einem Prescalerwert von 256 wären das 3906 Schritte, der Timer0 kann aber nur bis 255 zählen!! Entwerder schaust du, dass der Timer0 3906/255=15 mal überläuft, oder du nutzt den Timer1, der kann bis 65535 zählen. Dazu müsstest du (65535-3906)=61628 in das Zählerregister schreiben und dann warten bis er überläuft.

Noch Fragen?

Gruß Stefan

Gespeichert

theborg
Full Member
***
Offline Offline

Beiträge: 216



Profil anzeigen WWW
« Antworten #2 am: November 26, 2006, 12:33:50 »

UFF najut hab hier noch ne kleinere Schaltung liegen mit der werde ich wohl erstmal dann rumspielen der pic ist ein 16f627a ich nutze den internen tackt der ist bei 4mhz auf genauigkeit kommt es bei der sache nicht so an denke auch mal mein quelcode ist etwas vermurkst.

Code:
;list p=16f627a
include "p16f627a.inc"

__CONFIG _WDT_OFF & _PWRTE_OFF & _INTOSC_OSC_NOCLKOUT & _MCLRE_OFF & _BOREN_OFF & _LVP_OFF & _DATA_CP_OFF & _CP_OFF


org    0x00
goto   main
org    0x04

;PIN Bezeichnung IN/Out Funktion
;----------------------------------------
;1 RA2 in Taster für modien auswahl
;10 RB4
;9 RB3 out Blinker Links
;8 RB2 out Bremslicht
;7 RB1 out Blinker Rechts
;6 RB0 out Licht

main
call PortREG
goto BremsLicht

PortREG
;Analog Ports Abschalten
BSF CMCON, CM0
BSF CMCON, CM1
BSF CMCON, CM2
;PORTB Ports Einstellen
bsf STATUS, RP0 ; auf Bank 1 umschalten
movlw B'00000000' ; PortB I/O setzen (1=In, 0=Out) (Reinfolge RB7,RB6...)
movwf TRISB ; PortB I/O setzen
bcf STATUS, RP0 ; auf Bank 0 schalten
clrf PORTB ; PortB auf 0 setzen
;PORTA Ports Einstellen
bsf STATUS, RP0 ; auf Bank 1 umschalten
movlw B'11111111' ; PortB I/O setzen (1=In, 0=Out) (Reinfolge RB7,RB6...)
movwf TRISA ; PortB I/O setzen
bcf STATUS, RP0 ; auf Bank 0 schalten
clrf PORTA ; PortB auf 0 setzen
BremsLicht
btfsc PORTA, 2 ; ist RA2 High?
goto BremsLicht
clrf PORTB
bsf PORTB, 2
btfsc PORTA, 2 ; ist RA2 High?
goto BlinkerLinks
goto BremsLicht
BlinkerLinks
btfsc PORTA, 2 ; ist RA2 High?
goto BlinkerLinks
clrf PORTB
bsf PORTB, 3
btfsc PORTA, 2 ; ist RA2 High?
goto BlinkerRechts
goto BlinkerLinks
BlinkerRechts
btfsc PORTA, 2 ; ist RA2 High?
goto BlinkerRechts
clrf PORTB
bsf PORTB, 1 ; led an
btfsc PORTA, 2 ; ist RA2 High?
goto Licht
goto BlinkerRechts
Licht
btfsc PORTA, 2 ; ist RA2 High?
goto Licht
clrf PORTB
bsf PORTB, 0
btfsc PORTA, 2 ; ist RA2 High?
goto Allesein
goto Licht
Allesein
btfsc PORTA, 2 ; ist RA2 High?
goto Allesein
clrf PORTB
movlw B'00001111'
movwf PORTB
btfsc PORTA, 2 ; ist RA2 High?
goto BremsLicht
goto Allesein
end

beim BlinkerLinks und beim BlinkerRechts möchte ich das die led etwar im sec. takt blinkt
Gespeichert

Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 969



Profil anzeigen WWW
« Antworten #3 am: November 26, 2006, 14:54:57 »

Du sollest lieber mit call-Befehlen als den goto's arbeiten, das macht dein Programm deutlich übersichtlicher. Der Programmierstil mit goto macht einfache Sachen meist unnötig kompliziert.

Zitat
beim BlinkerLinks und beim BlinkerRechts möchte ich das die led etwar im sec. takt blinkt
Dann solltest du dort eine Funktion aufrufen (call) , die das einen Timer startet, der alle 1 Sekunde nen Interrupt liefert. Da schaust du dann, ob die an oder aus ist und setzt sie dementsprechend.

Dein Programm sollte eher so aufgebaut sein (Pseudo-Code):

initialiserung

main

call "lese taster"
call "verarbeite taster"

goto main


In "verarbeite Taster" änderst du immer nur eine sache (blinker an, bremslicht an etc.) ohne die vorherigen Einstellungen zu ändern.

Gespeichert

theborg
Full Member
***
Offline Offline

Beiträge: 216



Profil anzeigen WWW
« Antworten #4 am: November 26, 2006, 17:04:54 »

Hi habs hinbekommen die Erklärung war echt super nur eine frage ich kann max 250ms machen pro Schleife jetzt möchte ich den Timer so nutzen das ich mehrere Zeiten ausführen kann deshalb habe ich ne schleife Geschreiben wo ich den Timer 12mal abruffe um auf 3s zu kommen da ich mehrere unterschiedliche Zeiten brauche. nur geht das auch Irgendwie anders (ohne einen zweiten timer zu benutzen)?

Code:
;list p=16f627a
include "p16f627a.inc"

__CONFIG _WDT_OFF & _PWRTE_OFF & _INTOSC_OSC_NOCLKOUT & _MCLRE_OFF & _BOREN_OFF & _LVP_OFF & _DATA_CP_OFF & _CP_OFF


org    0x00
goto   main
org    0x04

cblock  0x10
t1
t2
endc

;PIN Bezeichnung IN/Out Funktion
;----------------------------------------
;1 RA2 in Taster für modien auswahl
;10 RB4
;9 RB3 out Blinker Links
;8 RB2 out Bremslicht
;7 RB1 out Blinker Rechts
;6 RB0 out Licht

main
call PortREG
goto Tasterabfragen
Tasterabfragen
btfsc PORTA, 2 ; ist RA2 High?
call BremsLicht
call Wait3s
btfsc PORTA, 2 ; ist RA2 High?
call BlinkerLinks
call Wait3s
btfsc PORTA, 2 ; ist RA2 High?
call BlinkerRechts
call Wait3s
btfsc PORTA, 2 ; ist RA2 High?
call Licht
call Wait3s
btfsc PORTA, 2 ; ist RA2 High?
call Warnblinker
call Wait3s
btfsc PORTA, 2 ; ist RA2 High?
call Allesein
call Wait3s
goto Tasterabfragen
BremsLicht
movlw B'00000100'
movwf PORTB
bsf PORTB, 2
return
BlinkerLinks
movlw B'00001000'
movwf PORTB
return
BlinkerRechts
movlw B'00000010'
movwf PORTB
return
Licht
movlw B'00000001'
movwf PORTB
return
Warnblinker
movlw B'00001010'
movwf PORTB
return
Allesein
movlw B'00001111'
movwf PORTB
return
Wait3s ;Wait 3s
call Wait ;Wait 250ms
call Wait ;Wait 250ms
call Wait ;Wait 250ms
call Wait ;Wait 250ms
call Wait ;Wait 250ms
call Wait ;Wait 250ms
call Wait ;Wait 250ms
call Wait ;Wait 250ms
call Wait ;Wait 250ms
call Wait ;Wait 250ms
call Wait ;Wait 250ms
call Wait ;Wait 250ms
call Wait ;Wait 250ms
call Wait ;Wait 250ms
call Wait ;Wait 250ms
call Wait ;Wait 250ms
return
Wait ; Warteschleife für 250 ms
        movlw .250
        movwf t1
top
movlw .250
movwf t2
top2
nop
decfsz t2, F
goto top2
decfsz t1, F
goto top
retlw .0

PortREG
;Analog Ports Abschalten
BSF CMCON, CM0
BSF CMCON, CM1
BSF CMCON, CM2
;PORTB Ports Einstellen
bsf STATUS, RP0 ; auf Bank 1 umschalten
movlw B'00000000' ; PortB I/O setzen (1=In, 0=Out) (Reinfolge RB7,RB6...)
movwf TRISB ; PortB I/O setzen
bcf STATUS, RP0 ; auf Bank 0 schalten
clrf PORTB ; PortB auf 0 setzen
;PORTA Ports Einstellen
bsf STATUS, RP0 ; auf Bank 1 umschalten
movlw B'11111111' ; PortB I/O setzen (1=In, 0=Out) (Reinfolge RB7,RB6...)
movwf TRISA ; PortB I/O setzen
bcf STATUS, RP0 ; auf Bank 0 schalten
clrf PORTA ; PortB auf 0 setzen
return
end
« Letzte Änderung: November 26, 2006, 17:08:34 von theborg » Gespeichert

Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 969



Profil anzeigen WWW
« Antworten #5 am: November 26, 2006, 17:10:15 »

Anstatt 12mal call wait zu schreiben könntest du auch
Code:
wait_3s

movlw D'12'
movwf counter
wait_3s_loop
call wait
decfsz counter, f
goto wait_3s_loop
return
schreiben.

Deine Lösung hat halt den Nachteil, dass der PIC während des Wartens nichts anderes tun kann. Wenn das für dich kein Problem ist, ist das ok. Wenn du aber noch Sensoren etc. abfragen willst, sollest du auf Interrupts setzen. Denn in 3Sekunden kann so ein PIC schon einiges Berechnen/Verabeiten.
« Letzte Änderung: November 26, 2006, 17:14:05 von Stampede » Gespeichert

theborg
Full Member
***
Offline Offline

Beiträge: 216



Profil anzeigen WWW
« Antworten #6 am: Dezember 02, 2006, 15:26:44 »

Hi bevor ich jetzt ein neues Tema eröffne hab ich nocht ne frage der Quellcode steht hier ja noch ich benutze am pic16f627A den internen Ossiolator jetzt hab ich leider ein Problem in dem Programmier Board funktioniert alles so wie es soll nur sobald ich den Chip in der eigentlichen Anwendung benutze schalten die Ports nach lust und Laune durch jetzt hab ich die Befürchtung das das so ist weil ich mclr direkt auf Vss gelegt habe da kein Wiederstand in die kleine Schaltung passt sonst würde mir nichts einfallen.

mfg tb

Aso hier mal nen kleines bild woran ich grade bastel ist zwar mit nen Controller etwas übertrieben aber nen schönes Anfängerprojekt.
 
Gespeichert

theborg
Full Member
***
Offline Offline

Beiträge: 216



Profil anzeigen WWW
« Antworten #7 am: Dezember 03, 2006, 11:01:23 »

fehler gefunden Zunge mir ist beim zusammenbau scheinbar etwas Kleber auf die Platiene getropft dieses hat einen leiterschluss bewirkt da sich kleber und lötzin nicht vertragen haben.

mfg tb
Gespeichert

Seiten: [1] Nach oben Drucken 
« vorheriges nächstes »
Gehe zu:  

Powered by MySQL Powered by PHP Made for Mozilla (Firefox) Made for Internet Explorer
Seite erstellt in 0.173 Sekunden mit 20 Zugriffen.
 
Top! Top!