PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 2.Programm :)



µautonom
05.09.2007, 15:56
Hallo, ich hab nun ein neues Porgramm geschrieben.
Und zwar soll der Taster 3mal betätigt werden, erst dann darf die LEd angehen. Leider macht er nicht das...., er macht die LEd immer an wenn ich taster betätigt hab.
Benutze den PIC16F628A falls man das noch wissen muss^^


start
movlw 3
movwf 0x20 ;Speicherzelle wird die Zahl3 geladen
bcf PORTB, 0 ;LED ausmachen , fals sie gesetzt ist

anf
btfsc PORTA, 0 ; Taster=0(betätigt), übergehe den nachfolgenend Befehl
goto anf
decfsz 0x20, 1 ;Die Zahl3 um 1 verringern, wenn Speicherzelle = 0 nachfolgenen Befhel übergehen udn LEd anmachen
goto anf
bsf PORTB, 0
clrw ;Arbeistregister löschen
goto start

end


Was mach ich falsch?

Mfg

PICVB
05.09.2007, 16:13
hallo µautonom
ich vermute mal du benutzt einen normalen mechanischen Taster oder?
die LED geht jedes mal an, da der Taster prellt. Da der µC in µSekunden das kleine Programm durchläuft zählt er die 3 bei einem Tastendruck herunter.
Du musst denn Taster entprellen und im Programm darfs erst weitergehn wenn der Taster wieder losgelassen wurde.

Gruß Carsten

µautonom
05.09.2007, 16:20
Hi, PICVB ja ich benutze diese "Mikrotaster" das ist doch ein mechansicher Taster oder^^


die LED geht jedes mal an, da der Taster prellt. Da der µC in µSekunden das kleine Programm durchläuft zählt er die 3 bei einem Tastendruck herunter.
Du musst denn Taster entprellen und im Programm darfs erst weitergehn wenn der Taster wieder losgelassen wurde.

....oh man daran hab ich gar nicht gedacht, das ist gut möglich, danke dir.

Mal sehn ob ich es hinbekomme, wenn nicht, meld ich mich nochmal.

Mfg

µautonom
05.09.2007, 19:37
Irgendwie krieg ich es nicht raus


start
movlw 3
movwf 0x20 ; Speicherzelle wird die Zahl3 geladen
bcf PORTB, 0 ; LED ausmachen , fals sie gesetzt ist

anf
btfsc PORTA, 0 ; Taster=0(betätigt), übergehe den nachfolgenend Befehl
;wenn PORTA den Wert 0 hat, dann übergehen den nachfolgenden Befehl.
btfss PORTA, 0 ;wenn PORTA den Wert 1 hat, dann übergehen den nachfolgenden Befehl.
decfsz 0x20, 1 ; Die Zahl 3 um 1 verringern, wenn Speicherzelle = 0 nachfolgenden Befehl übergehen und Led anmachen
goto anf

bsf PORTB, 0
clrw ; Arbeistregister löschen
goto start

end

Ich hab nochmal ne Bedingung gestellt, das wenn der Schalter unebtätigt ist, wieder den taster abfragen soll. Dann sollte er solange in der Schleife bleiben bis der Taster betätigt wird und zum Counter springen. Wenn das Ergebnis 0 ist Led anmachen, aber er macht trotzdem die LED an. Irgendwie werd ich nicht schlau draus ....

Mfg

frank85
05.09.2007, 21:28
Hallo. Probier es mal so. Ich hab es selbst aber nicht getestet!!




start
movlw 3
movwf 0x20
bcf PORTB, 0

anf
btfsc PORTA, 0
goto punkt2

punkt1

btfss PORTA, 0
goto punkt1
decfsz 0x20, 1

punkt2

goto anf
bsf PORTB, 0
clrw
goto start

end




MfG

frank

PICture
06.09.2007, 07:12
Hallo!

Wenn es die einzige Aufgabe des PICs ist, kann mann sich zum entprellen eines Tasters endlose Warteschleifen mit Bedingung leisten. Das Prinzip:

Der PIC prüft eine Taste endlos. Wenn sie gedrückt wird, geht er in die zweite endlose Schleife und wartet, bis sie los gelassen wird. Erst dann macht er was, z.B. erhöht ein Zähler usw. Danach springt er an Anfang (in die erste Schleife). Zur Verdeutlichung ein PDA im Code. Die Änderung des Zählers geschieht also erst beim Loslassen der Taste, das Programm ist aber sehr einfach.

MfG



.---+---------->V
| | Taste gedrückt ? J >.
| | N |
| | V |
| `-----------´ |
| |
| .----------->V
| | Taste losgelassen ? J >.
| | N |
| | V |
| `------------´ |
| |
| V
| Zähler erhöhen
| usw.
| V
`-----------------------------------------´

J = ja
N = nein

robotcheck
06.09.2007, 09:16
Hallo,

ich bin zum einen Überrascht, dass die LED überhaupt leuchtet.

Wenn Du Dir die letzen Programmzeilen noch mal anschaust:

1. Die LED wird eingeschaltet
2. Rücksprung zu Start
3. Dort wird die LED wieder ausgeschaltet

Nach dem Einschalten der LED werden also nur 6 Befehle abgearbeitet, bevor die LED wieder ausgeht.
Bei einem 4 MHz Quartz sind das ca. 6µs.
Dieser Ablauf geschieht so schnell, dass das kurze Leuchten der LED gar nicht gesehen werden kann.

Frage: Welchen Taktgeber benutzt Du?
Kleiner Tip zum Üben: Wenn Du den PIC mit einem RC-Glied taktest (wenige Hz), dann kannst Du bei kleinen Programmen die einzelnen Schritte gut mitverfolgen.
Außerdem fällt das Prellen des Schalters nicht ins Gewicht, weil der PIC zu langsam ist.

Zum Schalterprellen:

Es gibt Schalter, die prellen richtig lang und es gibt welche, die prellen (fast) gar nicht.

Ich habe mal mit einem OSZI nachgemessen und bei einem (hochwertigen) Schalter einige ms Prellzeit gemessen - siehe Anhang.
Entprellen mit dem PIC ist möglich, wenn man nach der High-Erkennung eine Zeitschleife startet (am besten ca. 10 ms)
und erst danach mit dem Programm weitermacht. (also keinen Timer benutzen, sondern eine verschachtelte Zeitschleife).

Dann kannst Du dich entscheiden, ob das Programm erst beim Loslassen weitergeht oder sofort. Auch beim Loslassen kann der Taster prellen !!

µautonom
06.09.2007, 11:37
Hallo Leute danke erstmal das ihr mir helft,

@frank85 den COde werd ichgleich mal testen.

@PICture, ja ich erstelle mir auch bevor ich loslege zu programmieren ein Programmablaufplan(PAP) oder Struktogramm, sah so ähnlich wie deins aus.
Sehr hilfreich

@robotcheck hab dazu noch ein interessanten Artikel gefunden

http://www.mikrocontroller.net/articles/Entprellung
Wenn ich richtig verstanden udn das aus deiner 2.Grafik richtig deute kann es passieren das bei einigen Tastern die "prellen" den Zustand während man ihn gedrückt hält ändern "prelllen" ? in der 2. Grafik sieht man ja das sich der Zustand an einigen Stellen einfach ändert.


Frage: Welchen Taktgeber benutzt Du?
Ich benutze einen 8Mhz Resonater, vielleicht sollte ich es mal mit einem Takt im Hz bereich probieren.

Mfg

robotcheck
06.09.2007, 15:54
Hallo,
fast richtig... Das Prellen entsteht genau in dem Moment, wenn die mechanischen Kontakte durch den Druck des Fingers aufeinandertreffen.
Der Widerstand des Schalters muss sich in diesem Augenblick von unendlich Ohm auf null Ohm reduzieren. Das geschieht innerhalb von Nano- bis Millisekunden.

Das Prellen kann sich noch verstärken, wenn man dafür anfällige Schalter ganz langsam drückt und am Schaltpunkt hält.

Ist der Kontakt danach richtig hergestellt, gibt es kein Prellen mehr, bis sich der Kontakt wieder öffnet. Beim Öffnen kann dann genau das gleiche passieren.

Mit dem PIC löst man das Entprellen mit einer Zeitschleife. 10 ms Entprellzeit sind für einen Tastendruck nicht viel. Daher stört es in der Regel nicht, wenn das Programm an dieser Stelle eben 10 ms auf der Stelle tritt.

Bei 8 MHz sind das 20000 Zählschritte.

Die Zeitschleife sollte als Unterprogramm abgelegt werden. Dadurch kann sie bei jedem Öffnen und Schließen des Tasters mit nur einem Befehl aufgerufen werden.

Solltest Du weiterhin Probleme damit haben, dann Poste bitte das ganze Programm. Vielleicht ist ja noch was in der Konfigurierung falsch.

µautonom
06.09.2007, 16:39
Hi,


Mit dem PIC löst man das Entprellen mit einer Zeitschleife. 10 ms Entprellzeit sind für einen Tastendruck nicht viel. Daher stört es in der Regel nicht, wenn das Programm an dieser Stelle eben 10 ms auf der Stelle tritt.

Nun ja wo kann ich nachgucken wieviel Zyklen ein Befehl hat und wieviel µSek. ein Zyklus ist. Beim 80C535 kann ich mich noch errinern, das ich eine Befehlsliste hatte in der eine Extra Spalte für "Zyklen" gedruckt wurde und ein Zyklus wurde genau in 0,75µs abgearbeitet.
Wie sieht es bei den PICs aus? Nur so kann ich ja eine genau 10ms lange Warteschleife programmieren oder geht das auch anders?



Die Zeitschleife sollte als Unterprogramm abgelegt werden. Dadurch kann sie bei jedem Öffnen und Schließen des Tasters mit nur einem Befehl aufgerufen werden.


Reicht da ein "call" um das Unterprogramm aufzurufen oder kann ich das mit "goto" lösen?

Digger hat in meinem Thread "1.Programm" Delay Zeiten die an 8MHz angepasst sind eingebaut, hab ich aber auch nicht so wriklich verstanden wie man das macht und ob ich das verwenden kann?

->
;**********SUB _Routinen*************************
DEL1MS movlw D'198' ;t=(n-1)*5+2(call)+6(ret)+7(Kopf)
movwf count
nop
goto $+1
goto $+1
DLY1MS goto $+1
decfsz count,f
goto DLY1MS
return
DEL200MS movlw D'199'
movwf tempa
DLY200 call DEL1MS
decfsz tempa,f
goto DLY200
movlw D'132'
movwf count
TWEEK200 decfsz count,f
goto TWEEK200
nop
return
DELAY500 movlw D'250'
movwf tempa
DLY500 call DEL1MS
decfsz tempa,f
goto DLY500
movlw D'64'
movwf tweek
TWEEK500 decfsz tweek,f
goto TWEEK500
movlw D'250'
movwf tempa
DLY501 call DEL1MS
decfsz tempa,f
goto DLY501
movlw D'64'
movwf tweek
TWEEK501 decfsz tweek,f
goto TWEEK501
return
end

ich werd das erstmal alleien versuchen, wenn ich es nicht hinbekomme werd ich den ganzen Code posten. Vielen Dank ^^

EDIT::// @frank85 Hab gerade deinen Code getestet , es tut sich leider nix,

PICture
07.09.2007, 06:38
Hallo µautonom!

Hast Du schon in Wiki nachgeschaut? Vielleicht findest Du dort etwas nutzliches:

https://www.roboternetz.de/wissen/index.php/PIC_Assembler

Viel Spass beim ewentuellen Lesen! :)

MfG

robotcheck
07.09.2007, 06:42
Hallo,

der PIC benötigt genau 4 Takte, um einen Befehl abzuarbeiten.
Bei 8 MHz arbeitet der PIC also in Wirklichkeit mit 2 MHz und das entspricht 0,5 µs/Befehl. Daher 10 ms = 20000 Takte. Du brauchst mindestens 2 Zählregister (verschachteln).

Ein Unterprogramm wird mit Call aufgerufen und das Unterprogramm mit Return wieder verlassen.

Vergiss aber fürs erste mal das Unterprogramm. Hier kann es nämlich noch notwendig werden, das W-Register, oder das Status-Register zu retten, weil die Zeitschleife diese Register verändert.

Baue die Zeitschleife für den Anfang direkt hinter die Schalterabfrage.

Ändere auch gleich (zum Test) Dein Programm so ab, dass es nach 3 mal Drücken die LED anmacht und stehenbleibt, also nicht mehr an den Anfang zurückspringt.

Unter WWW.sprut.de gibt es zu all diesen Problemen gute Beispiele.

Also weiterhin viel Glück!

µautonom
07.09.2007, 10:34
Hallo Leute,

@PICture ich habs wahrscheinlich übersehen, dachte da gibt es nur Artikel zum AVR, werd ich mir mal alles gründlich durchlesen, danke.

@robotcheck
Danke fur die Info


Ändere auch gleich (zum Test) Dein Programm so ab, dass es nach 3 mal Drücken die LED anmacht und stehenbleibt, also nicht mehr an den Anfang zurückspringt.

Werd ich probieren, bis dahin vielen dank

Mfg

µautonom
07.09.2007, 19:24
Hi Leute, puhhhh ich habs endlich geschafft \:D/ Die Led blinkt wenn ich den Taster 3mal betätigt hab! Schaut euch bitte meienn Code an, kann man da noch was verbesern? Was ist unnötig was könnte man rausnehemen.



;************************************************* ****************
;
; Includedatei für den PIC16F628A
list p=16f628a
include "p16f628a.inc"
;
;************************************************* ****************
; Configuration festlegen
; 8Mhz Resonator: Brown out Reset on, Data Protection off, Power up Timer on, Watchdog off, LV-Programmierung off

__CONFIG _BODEN_ON & _CP_OFF & _DATA_CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _MCLRE_OFF & _HS_OSC & _LVP_OFF


org 0x0000 ;Programmstart
goto MAIN
org 0x004 ; Interruptbehandlung

;************************************************* ***************
; Pinfunktion festlegen
;************************************************* ***************

MAIN
bcf STATUS,RP0
bcf STATUS,RP1 ; Bank0

movlw 0x07 ;Comperators off
movwf CMCON ;I/O Funktion ermöglichen

clrf PORTA
clrf PORTB ; alle Ausgänge Low

BCF STATUS, RP1 ;Bank 1 auswählen
BSF STATUS, RP0

movlw 0x01 ;Pins config
movwf TRISA ;PORTA RA0 Input, rest Output

movlw 0x00 ;PortB Output
movwf TRISB

bcf STATUS, RP0 ;Bank 0 auswählen
; hier bei Bedarf andere Register
; für Timer,CCP,EEprom,Usart,Vref
; initialisieren

;************************************************* ****************
;Programm
;************************************************* ****************



movlw 3
movwf 0x20 ; Speicherzelle wird die Zahl3 geladen

anf
btfsc PORTA, 0
goto anf

movlw 255 ;Zählregister
movwf 0x21

S1 movlw 255
movwf 0x22

S11 decfsz 0x22, 1
goto S11
decfsz 0x21, 1
goto S1
goto weiter
weiter nop
nop
nop
nop
btfss PORTA, 0
goto anf
decfsz 0x20, 1
goto anf
bsf PORTB, 0
clrw

end


Aber eine Sache stört mich immer noch, die LED leuchtet nicht so kräftig, wie bei den vorherigen Programmen die nicht funtkionierten, woran kann das liegen? Aufgebaut ist alles richtig, es muss am Programm liegen.


Mfg

PICture
07.09.2007, 19:59
Hi µautonom!

Kannst Du, bitte, Dein PAD/PAP posten? Es ist viel einfacher zum Überprüfen und evtl. Fehler finden.

MfG

µautonom
07.09.2007, 20:25
Hi, PICture

meinst du damit den Programmablaufplan?
Ist der selbe Ablauf den du mir vorgeschlagen hast, nur das ich ne verschachtelte Zählschleife nach der 1.Tasterabfrage eingebaut habe.

Ich zeichne das immer auf einem Blatt Papier nur hab grad keinen Scanner da
mein Programmm funktioniert ja, die Sache ist nur die das die LED nicht so kräftig leuchtet, ich dneke das liegt daran das der PIC die LEd zu wieder löscht, weil ich ja ein Sprungbefehl zum Anfang eingebaut hab in der sie wieder gelöscht wird.

EDIT:// Ich hab den Code noch einmal ein wenig Kommentiert, sollte so übersichtlicher sein.



;************************************************* ****************
;Programm
;************************************************* ****************



movlw 3
movwf 0x20 ; Speicherzelle wird die Zahl3 geladen

anf
btfsc PORTA, 0 ;Taster gedrückt = 0! zur Verschachtelen Zählschleife springen
goto anf

;************************************************* ************************
;Zählschleife
;************************************************* ************************

movlw 255 ; 1 Zählregister
movwf 0x21

S1 movlw 255 ; 2 Zählregister
movwf 0x22

S11 decfsz 0x22, 1
goto S11
decfsz 0x21, 1
goto S1

;************************************************* ************************
goto weiter
weiter nop
nop
nop
nop

btfss PORTA, 0 ;Taster losgelassen =1? zum Counter übergehen
goto anf

decfsz 0x20, 1 ; Counter = 0 - Led an
goto anf
bsf PORTB, 0
clrw

end



Mfg

robotcheck
07.09.2007, 21:26
OK, es geht in die richtige Richtung :-k

Die LED leuchtet deshalb nicht hell, weil Dein Programm in das end hineinläuft. Das bedeutet, der Controller springt an die Adresse 0000 zurück und Dein Programm beginnt von vorn.
Dort werden die Ausgänge und somit die LED wieder ausgeschaltet.
Da die LED danach wieder eingeschaltet wird, ist das Programm nicht ganz in Ordnung. Zuerst musst Du dafür sorgen, dass das Programm nach dem Einschalten der LED stehenbleibt.

Bitte halte Dich an die Schreibregeln:

Wenn Du eine HEX-Zahl verwendest, dann schreibe 0x4C oder h'4C'
Wenn Du eine DEZIMALE-Zahl verwendest, dann schreibe d'255'
Wenn Du eine BINÄRE-Zahl verwendest, dann schreibe b'00001111'
Wenn Du einen Buchstaben aus der ASCII-Tabelle verwendest, dann schreibe a'T'

Hier sind ein paar Kommentare und Ergänzungen:



;************************************************* ****************
;Programm
;************************************************* ****************


movlw 3 ; BITTE SCHREIBE movlw d'3' FÜR DEZIMALE ZAHL
movwf 0x20 ; Speicherzelle wird die Zahl3 geladen

anf
btfsc PORTA, 0 ; Taster gedrückt = 0! zur Verschachtelen Zählschleife springen
goto anf ; DU VERWENDEST EINEN ÖFFNER???

;************************************************* ************************
;Zählschleife
;************************************************* ************************

movlw 255 ; LADE REGISTER MIT movlw d'100'
movwf 0x21

S1
movlw 255 ; LADE REGISTER MIT movlw d'200'
movwf 0x22 ; 100 x 200 = 20000 TAKTE+Zusatzbefehle (goto...)

S11
decfsz 0x22, 1 ; SCHREIBE NUR decfsz 0x22
goto S11
decfsz 0x21, 1 ; SCHREIBE NUR decfsz 0x21
goto S1

;************************************************* ************************
goto weiter ; RAUS, DAS goto IST ÜBERFLÜSSIG
weiter ; RAUS, DIE SPRUNGMARKE IST ÜBERFLÜSSIG
nop ; RAUS, BEFEHL IST ÜBERFLÜSSIG
nop ; RAUS, BEFEHL IST ÜBERFLÜSSIG
nop ; RAUS, BEFEHL IST ÜBERFLÜSSIG
nop ; RAUS, BEFEHL IST ÜBERFLÜSSIG

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!
; DER TASTER WIRD GERADE GEDRÜCKT, ALSO WARTE, BIS WIEDER LOSGELASSEN

t_los
btfss PORTA, 0 ;Taster losgelassen =1? zum Counter übergehen
goto t_los

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!
; NOCHMAL ZEITSCHLEIFE, WEIL DER TASTER AUCH BEIM LOSLASSEN PRELLEN KANN

movlw d'100' ; LADE REGISTER MIT movlw d'100'
movwf 0x21

S2
movlw d'200' ; LADE REGISTER MIT movlw d'200'
movwf 0x22 ; 100 x 200 = 20000 TAKTE+Zusatzbefehle (goto...)

S22
decfsz 0x22 ; SCHREIBE NUR decfsz 0x22
goto S22
decfsz 0x21 ; SCHREIBE NUR decfsz 0x21
goto S2
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!



decfsz 0x20, 1 ; Counter = 0 - Led an ; SCHREIBE NUR decfsz 0x20
goto anf
bsf PORTB, 0
clrw ; RAUS, BEFEHL IST ÜBERFLÜSSIG

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!
loop
goto loop ; ENDLOS-SCHLEIFE, HIER BLEIBT DAS PROGRAMM STEHEN UND LÄUFT NICHT IN end
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!

end

µautonom
07.09.2007, 21:55
Hi robotcheck, vielen Dank das du dir Mühe gemacht hast, jede Zeile kommentiert hast. An meinem Programmierstil muss ich noch arbeiten :D:D


DU VERWENDEST EINEN ÖFFNER??? Das liegt an der Tasterschaltung, von Sprut, dei taster sind alle auf High-Zustand, sobal ein Taster gedrückt wird, wird dieser auf Masse gezogen sprich = "0".


SCHREIBE NUR decfsz 0x22

Das wusst ich gar nicht, ich schaue mir immer die Befehle bei sprut nach
Da ist die Syntax DECFSZ f,d


wenn d=0:
Vom Wert in f wird 1 abgezogen, und das Ergebnis in W gespeichert.

wenn d=1:
Vom Wert in f wird 1 abgezogen, und das Ergebnis wieder in f gespeichert.

Ist das Ergebnis der Subtraktion Null, dann wird der nächste Befehl im Programm übersprungen, und mit dem übernächsten weitergebacht.

Das mit nop und goto weiter hab ich vergessen zu editieren^^, wusste schon das das unsinnig war :D

ich könnte ja doch einfach am Ende nachdem die LEd angemacht wird, weider einen Zählschleife einbauen, sodas die LEd ein wenig länger blinkt damit man weider die Taster 3 mal betätigt um sie leuchten zu lassen, bei deine Endlosschleife würde sie doch die ganze Zeit anbleiben richtig?

Mfg

robotcheck
07.09.2007, 22:19
Hi,

Du hast Recht mit dem decfsz-Befehl . 8-[

Ich habe das Programm auf die Schnelle kommentiert.
Du kannst übrigens für d=0 auch W schreiben und für d=1 auch F.
Also decfsz,W oder decfsz,F
Falls Du gar nichts schreibst, wird d=1 gesetzt.
Aber das entspricht nicht unbedingt den Schreibregeln.


Die Idee mit der Zeitschleife am Ende des Programmes ist gut, sollte aber erst gemacht werden, wenn das eigentliche Programm läuft.
Also die LED muss erstmal HELL leuchten.
Außerdem brauchst Du dann eine große Zeitschleife aus mindestens 3-4 Registern, sonst ist die Schleife zu schnell runtergezählt.

Ich würde eher vorschlagen, den Taster nochmal abzufragen.

Also 3 x drücken = LED an und beim 4ten mal drücken = LED wieder aus und zurück an den Anfang.

Noch etwas: Die Endlosschleife sollte grundsätzlich bei jedem Programm vor dem end stehen, auch wenn sie gar nicht ausgeführt wird. Damit verhindert man sicher, dass das Programm (aus welchen Gründen auch immer) ins end hineinläuft.

µautonom
08.09.2007, 13:37
Ok danke für die Tipps, wenn ich das erstma geschaft hab
....beim 4ten mal drücken = LED wieder aus und zurück an den Anfang, werd ich mal versuchen das ganze mit Unterprogramm zu lösen sprich call und ret benutzen, so erspart man sich Schreibarbeit und ich kann dann die Zählschleife an jeder beliebigen Stelle aufrufen. Ist auch eleganter :D

Mfg

PICture
09.09.2007, 01:26
Hallo µautonom!

Genau und for allem übersichtlicher und effizienter.

Wenn Du z.B. ein ASM Program vom Sprut mit meinem vergleichst, dann siehst Du, dass ich jedes unbedeutendes Zeichen zu vermeiden versuche, um möglichst kurzes und übersichtliches ASM Programm zu erstellen. Weil ich immer mit PADs arbeite, schreibe ich in meinen Programmen keine Kommentare (nur wenn ich sie veröffentliche).

Mit der Zeit entwickelt sich "von selbst" ein Programmstyle, wie eine Handschrift. Ich habe aber, bevor ich auf PICs umgestiegen bin, andere Prozessoren in ASM programmiert. Ich könnte auch AVRs wählen, finde aber persönlich PICs "sympatischer".

Viel Spass bei der PIC Programmierung, Du bist sicher auf dem richtigen Weg zum Erfolg! :)

MfG

µautonom
09.09.2007, 13:32
Hi PICture,

bei mir war das auch so ähnlich das ich vor nem Jahr unegfähr mit einem 80C535 gearbeitet habe (in der Schule :) ) Alles in Assembler programmiert. Das hat mir den Einstieg in die PIC porgrammierung erleichert. Ich selber finde den PIC auch sympatischer deswegen hab ich mich auch für diesen entscheiden :D:D. PAD ist ne gute Sache, wenn man viele Verzweigungen und Sprünge hat wird man irgendwann die Übersicht verlieren, da ist so ein Ablaufplan sehr hilfreich.

Danke den werd ich haben :D

Noch ne Frage, wie lange arbeitest du schon mit PICs?

Mfg

PICture
09.09.2007, 14:44
Hi µautonom!

Geschichte war im Gymnasium meine Schwäche, ich kann mir die Daten nicht merken, aber ungefähr 1,5 Jahre. Mit ASM Programmierung habe ich vor ca. 15 Jahren angefangen. :)

MfG

µautonom
09.09.2007, 17:08
Hi,
15Jahre , sind ne ganze Menge :D

Ich hab mal das ganze noch mit Unterprogranmm gemacht


w_temp EQU 0x70 ; context saving
status_temp EQU 0x71 ; context saving

INTSERV movwf w_temp ; W register retten
movf STATUS,w ; status register nach W register
movwf status_temp ; STATUS register retten

IntEnd movf status_temp,w ; STATUS register
movwf STATUS ; wieder herstellen
swapf w_temp,f
swapf w_temp,w ; W register wieder herstellen


;************************************************* ****************
;Programm
;************************************************* ****************



movlw 3
movwf 0x20 ; Speicherzelle wird die Zahl3 geladen

anf
btfsc PORTA, 0 ; Taster abfragen - Taster gedrückt -> zur Zählschleife
goto anf

;************************************************* *************

call z_schleife ; Unterprogrammm aufrufen

;************************************************* **************

t_los
btfss PORTA, 0 ;Taster abfragen - Taster los -> zum Counter
goto t_los

;************************************************* **************

call z_schleife

;************************************************* ***************

decfsz 0x20, 1 ; Counter = 3
goto anf
bsf PORTB, 0

loop
goto loop

;************************Unterprogramm************ ****************
;20000 Takte

z_schleife
movlw d'100'
movwf 0x21

S2
movlw d'200'
movwf 0x22

S22
decfsz 0x22, 1
goto S22
decfsz 0x21, 1
goto S2

return

;************************************************* *****************

end


Ich glaube das würde auch ohne den Code am Anfang funktionieren, obwohl ich gar nicht weiss wie das benutzen kann^^ Code funktioniert aber habs getestet.

Kann mir jemand eklräen was man dabei beachten muss, robotcheck hat
was von W-Register retten geschrieben, was hat es damit auf sich ? Bei sprut konnt eich nix dazu finden sowie hier im Wiki, oder bin ich blind=? :D

Mfg

Mfg

robotcheck
09.09.2007, 18:49
Hallo,

das Retten des W- und Status Registers wird hauptsächlich in der Interrupt Routine benutzt. Ich habe es aber selbst erlebt und auch bei anderen festgestellt, dass es bei Unterprogrammen, die oft aufgerufen werden, sinnvoll sein kann, diese Register zu retten. Wenn Du Dir die Zeitschleife mal anschaust, dann findest Du dort Befehle, die das W-Register überschreiben. Außerdem wird das Statusregister verändert, wenn das Zählregister auf 0 steht (Zero-Bit).

Beispiel:
Falls Du die Zeitschleife aus dem Hauptprogramm aufrufst, und vor dem CALL-Befehl einen Wert im W-Register stehen hast, den Du nach der Zeitschleife noch weiterverwenden willst, dann wird dieser ohne das Retten überschrieben. Natürlich kann man diesen Wert auch in einem anderen Register zwischenspeichern, aber das wird gerne vergessen. Rettet man diese Register, dann braucht man sich darüber keine Gedanken zu machen, denn die Werte sind nach dem UP genauso, wie davor.

Informationen dazu findest Du im Bereich "Interrupt"

http://sprut.de/electronic/pic/fallen/fallen.html#interrupt


Fazit: Das Register retten ist bei Unterprogrammen nicht notwendig. Man muss jedoch dann wissen, was nach dem Unterprogramm mit dem W-Register und dem Status-Register passiert. Deshalb hatte ich geschrieben: Es kann notwendig sein, diese Register zu retten.

Falls Du es benutzt, dann müssen die Register am Anfang des Unterprogrammes gerettet und vor dem Verlassen wieder hergestellt werden.

So, ich hoffe das war verständlich. Eventualitäten lassen sich nicht leicht erklären. :-k

PICture
09.09.2007, 18:54
Das mit dem "Register retten" bezieht sich auf ISR, was Du nicht hast.

Ich denke, das Du nicht das ganze Programm gepostet hast, da fehlt z.B. "__config" usw.

Ich habe aus Deinem Programm, alles was ich unnötig finde, entfernt. Hoffe aber, das es trotzdem funktioniert. :)

MfG


;************************************************* ****************
;Programm
;************************************************* ****************



movlw 3
movwf 0x20 ; Speicherzelle wird die Zahl3 geladen

anf
btfsc PORTA, 0 ; Taster abfragen - Taster gedrückt -> zur Zählschleife
goto anf

;************************************************* *************

;************************************************* **************

t_los
btfss PORTA, 0 ;Taster abfragen - Taster los -> zum Counter
goto t_los

;************************************************* **************

call z_schleife

;************************************************* ***************

decfsz 0x20, 1 ; Counter = 3
goto anf
bsf PORTB, 0

loop
goto loop

;************************Unterprogramm************ ****************
;20000 Takte

z_schleife
movlw d'100'
movwf 0x21

S2
movlw d'200'
movwf 0x22

S22
decfsz 0x22, 1
goto S22
decfsz 0x21, 1
goto S2

return

;************************************************* *****************

end

robotcheck
09.09.2007, 20:48
@PICture

Der Befehl call z_schleife nach dem goto anf sollte drinbleiben.

Ein Taster kann sowohl beim Drücken, als auch beim Loslassen prellen.

Bei diesem Programm könnte es sich an folgender Stelle bemerkbar machen:

Wenn die Taste zum 3ten mal gedrückt wird, dann geht die LED an, BEVOR die Taste wieder losgelassen wurde.
Ob es so ist, entscheidet jedoch der Praxis-Test.

PICture
09.09.2007, 21:16
Hallo robotcheck!

Das stimmt nicht, da das Program in der endloser Schleife "t_los" so lange bleibt, bis der Taster losgelassen wird.

MfG

robotcheck
10.09.2007, 08:25
Hallo PICture,

das ist ja auch richtig, wenn man davon ausgehen kann, dass der Taster nicht prellt.

Falls er aber doch prellt, dann wird das Programm durch Drücken des Tasters die Schleife anf verlassen und sich (bei 8MHz) innerhalb von 2 µs in der Schleife t_los befinden.

Das Prellen des Tasters ist eine Folge von Spannungsspitzen (High/Low) in einem Zeitraum von bis zu 10 ms.

In der Schleife t_los registriert der PIC also noch das Kontaktprellen aus der Schleife anf und wird diese Schleife direkt wieder verlassen. Deshalb muss die Zeitschleife auch nach anf eingefügt werden.

Es ist von den praktischen Gegebenheiten abhängig.
Vielleicht wird uns µautonom im nächsten Beitrag mitteilen, das sein Programm in Deiner Variante einwandfrei läuft. In diesem Falle prellt sein Taster beim Drücken nicht.
Vielleicht prellt der Taster auch überhaupt nicht und wir sind aufgrund der anderen Fehler im Programm nur dieser Vermutung aufgesessen. Dann kann er die Zeitschleife auch wieder ganz rausnehmen (was ich grundsätzlich nicht machen würde).

Gruß

µautonom
10.09.2007, 14:35
Hi, Leute danke erstma für die Info zu dem Thema W-register retten.

Also beim drücken prellt der Taster auf jeden Fall, wie das ganze beim loslassen asusieht weiss ich nciht werd gleich mal mal die Version von PICture testen, werde ne Rückmeldung machen.

Kam leider gestern nicht zum testen.

EDIT: Beim loslassen prellt der Taster nicht, deshalb funktioniert das Programm auch ohne die Zählschleife bei der Abfrage ob der Taster losgelassen wurde. Wenn man sich nicht sicher ist, ist das ja nicht verkehrt sicherhalbsweiser die Zeitschleife nochmal an dieser Stelle aufzurufen.


Mfg

PICture
11.09.2007, 07:04
Hallo!

@µautonom

Genau, so ist es. :)

@robotcheck

Deine Überlegungen zwecks prellen des Tasters sind richtig, aber der Sprung des Programms zum "_anf" erst nach der "z_schleife" und decrementierung des Zählers möglich ist.

Ich glaube nicht, das jemand ein Taster innerhalb von 10 ms loslassen kann oder ein Taster beim loslassen prellen kann.

Die Art der Tasterentprellung habe ich mehr praktisch als theoretisch entdeckt. Erst danach habe ich nachgedacht und festgestellt, dass es menschliche "Verzögerungsschleife" zwischen "_anf" und "t_los" ausnutzt.

Ich habe die zwei endlose Schleifen "_anf" und "t_los" direkt nacheinander und ohne nachfolgender Warteschleife schon mehrmals zum entprellen eines Tasters benutzt. Ich glaube auch nicht, dass ich besonders langsam bin und immer Glück habe. :)

MfG

robotcheck
11.09.2007, 08:15
Hallo PICture,

ich hatte nicht gemeint, dass ein Taster innerhalb von 10ms gedrückt und wieder losgelassen wird, sondern dass das Prellen bis zu 10 ms andauern kann. Auf der vorigen Seite findest Du u.a ein Bild von einem Taster, den ich mal genauer untersucht hatte. Bei diesem dauerte das Prellen bis zu 7ms. Der Taster selbst wurde natürlich einige Sekunden gedrückt gehalten.

Ich denke, jeder hat seine Erfahrungen gemacht und in der Regel gibt es viele Lösungen für ein Problem.

Weiterhin viel Erfolg O:)

PICture
11.09.2007, 08:39
Hallo robotcheck!

Natürlich! Ich bin aber darüber überzeugt, dass wir mehr tollen Sachen dank Experimentieren als theoretisches Denken haben. :)

MfG

PICture
12.11.2008, 19:21
Hi µautonom!

Sorry, dass ich so spät antworte, aber ich erst jetzt deine Frage gesehen habe. Mit PICs beschäftige ich mich ca. 2 Jahre.

MfG

µautonom
13.11.2008, 15:30
Hi PICture ,

nicht so schlimm, mittlerweile musste ich auf AVR's umsteigen. (In Mikroprozessortechnik an meiner FH wird leider nur mit AVR's gearbeitet)

Mfg
uautonom

PICture
13.11.2008, 15:56
Hi µautonom,

es ist doch egal mit welchem µC man sich beschäftigt. Man muss nur neue Befehle und die innere Struktur des µCs erlernen. Der ASM bleibt immer gleich.

Ich habe mir auch schon gedacht, dass für einige Anwendungen, wegen Geschwindigkeit AVRs besser wären. Aber mit zwei µCs gleichzeitig zu arbeiten ist mir zu kompliziert.

Viel Spass und Erfolg mit AVRs! :)

MfG