Hallo,
hier ist der Code für den Taster...
der erste Code ist ohne Timer, man kann daran schön erkennen, was Prellen ist.
Ob man die LED eingeschaltet bekommt, ist manchmal eine reine Glücksache![]()
Sorry, ich war zu faul um hier komentare zu schreiben [-XCode:.include "m8def.inc" .equ sperre = 7 ;Taster sperren .equ LED = PD7 .equ Taster = PD4 .def tmp = R16 .def status = R17 .org 0x000 rjmp reset reset: ldi tmp,HIGH(RAMEND) out SPH,tmp ldi tmp,LOW(RAMEND) out SPL,tmp sbi DDRD,LED cbi DDRD,Taster sbi PORTD,Taster sbi PORTD,LED loop: sbis PIND,Taster rjmp loop0 cbr status,(1<<sperre) rjmp loop loop0: sbrc status,sperre rjmp loop sbis PORTD,LED rjmp loop1 cbi PORTD,LED sbr status,(1<<sperre) rjmp loop loop1: sbi PORTD,LED sbr status,(1<<sperre) rjmp loop
Und jetzt nochmal das selbe nur mit Timer 0 der alle 26 mS die Taste abfragt.
Hier kann kann sich die Finger wunddrücken, kein Prellen mehr da![]()
Die 26 mS sind auch nicht kritisch, es könnten auch 100 sein, oder schafst Du das einen Taster 10 mal in der Sekunde zu drücken [-(
Achso, Du mußt natürlich noch Deine Ports und Pins anpassen, ich habe, glaube ich vergessen die in der equs oben eizutragen.
Hier habe ich alles ausreichend kommentiert.....Code:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Tasterschaltung mit einem Timer ;; ;; Quarz 10 MHz ;; ;;Der Timer hat einen prescaller von 1024 das heißt der hat eine ;; ;; Frequenz von 9,76 kHz. Da ich Ihn noch mit 1 vorlade muß er ;; ;; 254 mal durchlaufen um ein Interrupt auszulösen, das wäre etwa;; ;; 38,5 Hz bzw. 26 ms Achtung, es ist auf 10 Mhz ausgelegt, müßte;; ;; aber auch bei anderen Frequenzen klappen nur die Zeiten sind ;; ;; natürlich anders. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .include "m8def.inc" .equ time = 255 -254 ;Damit wird der Timer vorgeladen .equ sperre = 7 ;Taster sperren (Hilfsvariable) .equ LED = PD7 ;kein komentar .equ Taster = PD4 ;kein komentar .def tmp = R16 ;mein universallregister .def status = R17 ;Das ist mein Statusregister, wo später die sperre ;gespeichert wird, man sehe es sind noch 7 Bits ;für andere Zwecke frei .org 0x000 rjmp reset ;Interruptvektor reset kein komentar .org OVF0addr rjmp zeitum ;Interruptvektor für Timer0 Überlauf, hier ;spring mein Programm hin, wenn der Timer überläuft reset: ;;Stack einrichten ldi tmp,HIGH(RAMEND) out SPH,tmp ldi tmp,LOW(RAMEND) out SPL,tmp ;;Port D ist bei mir mit LED und mit einem Taster belegt ;;PD7 ist die Diode, PD4 ist der Taster sbi DDRD,LED ;kein komentar cbi DDRD,Taster ;kein komentar sbi PORTD,Taster;Pullup am Taster sbi PORTD,LED ;Da ich meine LED gegen VCC geschaltet habe ;mache ich sie hier aus ;;Timer Register werden belegt ;;Ich nehme hier den Timer 0 ldi tmp,(1<<CS02) | (1<<CS00) ;prescaller ist 1024 out TCCR0,tmp ;Register TCCR0 ist für den Prescaller zuständig ldi tmp,(1<<TOIE0);Hier werden Interrupts nach Timer0 Überlauf eingeschaltet out TIMSK,tmp ;Register TIMSK ist dafür zuständig ldi tmp,time ;Hier wird der Timer vorgeladen und zwar mit 255-254 out TCNT0,tmp ; Er läuft 254 mal durch bevor ein Interrupt auftritt sei ;mein Lieblingsfehler, na was den Interrupts allgemein zulassen loop: ;meine Hauptschleife rjmp loop ;Hier herscht totale langeweile ;;Die Routine wird abgearbeitet wenn ein Interrupt stattgefunden hat zeitum: push tmp ;Rette universallregister, hier ziemlich sinnlos ;aber Ordnung muß sein in tmp,SREG ;rette Statusregister, sehe eine Zeile höher push tmp ;sehe eine Zeile höher sbis PIND,Taster ;Überspringe nächste Zeile, wenn PIND HIGH ist ;also nicht gedrückt rjmp zeitum0 ;sonst springe nach zeitum0 cbr status,(1<<sperre) ;Lösche meine Sperre (Bit 7 im Register status) rjmp zeitum2 ;Springe nach zeitum2 zeitum0: sbrc status,sperre ;Überspringe nächste Zeile, wenn Sperre nicht gesetzt ist rjmp zeitum2 ;Springe nach zeitum2 sbis PORTD,LED ;Überspringe nächste Zeile, wenn LED gesetzt(aus) ist rjmp zeitum1 ;springe nach zeitum1 cbi PORTD,LED ;Schalte LED ein sbr status,(1<<sperre) ;setze Sperre(Bit 7 im Register status) rjmp zeitum2 ;Springe nach zeitum2 zeitum1: sbi PORTD,LED ;Schalte LED aus sbr status,(1<<sperre) ;setze Sperre(Bit 7 im Register status) zeitum2: ldi tmp,time ;Hier war der Fehler und zwar muß out TCNT0,tmp ; der Timer neugeladen werden(genauso wie im reset) pop tmp ;Stelle SREG wieder her out SREG,tmp ;sehe eine Zeile höher pop tmp ;Stelle universallregister wieder her reti ;die Interrupt Routine wird verlassen, und ;es wird weiter im Hauptprogramm gearbeitet
achso, ich hatte gerade 10 MHz Quarz drauf, es müßte aber mit anderen Frequenzen auch klappen.
Wenn Du noch fragen hast, dann frag.
Sollte jemand weitere Anregungen haben, würde ich mich sehr freuen
Gruß Sebastian







Zitieren
Lesezeichen