Autor
|
Thema: Taster als Schalter via AVR (Gelesen 152320 mal)
|
|
Fabeulous
Gast
|
Okay verstanden! Aber ich habe jetzt ja garkeine FET's mehr. Ist das bei den neuen Transistoren genauso?
|
|
|
Gespeichert
|
|
|
|
|
Fabeulous
Gast
|
Okay nun verstehe ich Danke!
So ich wusel mich gerade mal durch die Programmierung in Assembler... Ich habe mir dazu das Tutorial von Microcontroller.net durchgelesen. Nun bin ich bei der Tasterentrepellung hängen geblieben. Das bräuchte ich ja ziemlich sicher um das ganze zu realisieren. Nur leuchten mir manche sachen noch nicht so richtig ein: .include "m8def.inc" .def key_old  = r3 .def key_now  = r4 .def temp1   = r17 .def temp2   = r18 .equ key_pin  = PIND .equ key_port = PORTD .equ key_ddr  = DDRD .equ led_port = PORTB .equ led_ddr  = DDRB .equ LED    = 0    ldi temp1, 1<<LED    out led_ddr, temp1     ; den Led Port auf Ausgang    ldi temp1, $00       ; den Key Port auf Eingang schalten    out key_ddr, temp1    ldi temp1, $FF       ; die Pullup Widerstände aktivieren    out key_port, temp1    mov key_old, temp1     ; bisher war kein Taster gedrückt loop:    in  key_now, key_pin    ; den jetzigen Zustand der Taster holen    mov temp1, key_now     ; und in temp1 sichern    eor key_now, key_old    ; mit dem vorhergehenden Zustand XOR    mov key_old, temp1     ; und den jetzigen Zustand für den nächsten                  ; Schleifendurchlauf als alten Zustand merken    breq loop          ; Das Ergebnis des XOR auswerten:                  ; wenn keine Taste gedrückt war -> neuer Schleifendurchlauf    and temp1, key_now     ; War das ein 1->0 Übergang, wurde der Taster also                  ; gedrückt (in key_now steht das Ergebnis vom XOR)    brne loop          ;    ldi temp1, $FF       ; ein bisschen warten ... wait1:    ldi temp2, $FF wait2:    dec temp2    brne wait2    dec temp1    brne wait1                  ; ... und nachsehen, ob die Taste immer noch gedrückt ist    in  temp1, key_pin    and temp1, key_now    brne loop    in  temp1, led_port    ; den Zustand der LED umdrehen    com temp1    out led_port, temp1    jmp loop
Könnt ihr mir sagen was folgendes bedeutet: "1<<LED", Und bedeutet das Dollar Zeichen ("$") bei diesen(ldi temp1, $00) oder anderen Befehlen das selbe wie "0x"? Also das die darauf folgende Zahl als Hex Zahl interpretiert wird? Ich vermute das einfach mal weil es auf dem guten alten Apple 2 6502 Prozessor dies bedeutete...
So ich werde mich dann mal noch ein bischen dadurch wühlen. @Stukka: könntest du deinen Quelltext den du mal (für das Taster als Schalter Projekt)gemacht hast ins Forum stellen oder mir schicken? Vorrausgesetzt du bist damit einverstanden!?
EDIT: So ich habe mich nochmal ein bischen durch den QUelltext gewuselt, und soweit ich das verstanden habe ist der obige ja quasi genau das was ich brauche oder? Natürlich ist das da oben nur für LED's gedacht aber das sind ja nur die "Variabelnamen". Also eigentlich sollte das funktionieren?!
|
|
« Letzte Änderung: Juni 18, 2007, 15:43:21 von Fabeulous »
|
Gespeichert
|
|
|
|
Stukaa
Wakü-Poseidon

Karma: +2/-0
Offline
Geschlecht: 
Beiträge: 414
+_ö
|
den code kannst du wahrscheinlich schon benutzen, ich hab ihn nicht getestet.. wenn ich den quelltext behalten wollte, würde ich hier nicht so damit rumprollen aber ich glaube in deinem fall wäre mein Quelltext zu kompliziert für dich, nimm den 3. code im link: http://www.mikrocontroller.net...utorial:_Tasten ist quasi fertig, du musst nur die definitionen an die ports anpassen die du verwenden willst, diese routine ist die grundlage meiner software..
bei diesem code gilt dann immer ein gesetztes bit in einem port, zb. portB für ein bit in einem anderen port, also zb. portA.. mit meinem Code kann eine änderung an portB für änderungen an allem sorgen, daher ist mein code länger..
ldi temp1,1<<Led
oben wurde mit ".equ LED=0" LED als null bestimmt.. er setzt nun also das LSB des Registers temp1 auf 1.
$ und 0x steht beides für hex 0b ist binary
EDIT: naja also wenn sich die routine die du geposted hast als zuverlässig erweist, wäre sie sogar besser als die die ich hab, da diese einen timer braucht, der dann ja belegt ist..
|
|
« Letzte Änderung: Juni 18, 2007, 16:43:59 von Stukaa »
|
Gespeichert
|
digitall Oo
|
|
|
Fabeulous
Gast
|
Aber braucht die dritte von oben auf der Seite die du genannt hast nicht auch einen Timer?
EDIT: Okay Sorry komando zurück: Ich hab den 4ten Quelltext erwischt...
|
|
« Letzte Änderung: Juni 18, 2007, 23:27:19 von Fabeulous »
|
Gespeichert
|
|
|
|
|
Fabeulous
Gast
|
Öhm ich denke er meint folgenden Code .include "m8def.inc" .def iwr0   = r1 .def iwr1   = r2 .def key_old  = r3 .def key_state = r4 .def key_press = r5 .def temp1   = r17 .equ key_pin  = PIND .equ key_port = PORTD .equ key_ddr  = DDRD .def leds   = r16 .equ led_port = PORTB .equ led_ddr  = DDRB .org 0x0000   rjmp  init .org OVF0addr   rjmp  timer_overflow0 timer_overflow0:        ; Timer Overflow Interrupt   push  r0         ; temporäre Register sichern   in   r0, SREG   push  r0   push  iwr0   push  iwr1 get8key:            ;/old   state   iwr1   iwr0   mov   iwr0, key_old   ;00110011 10101010      00110011   in   key_old, key_pin  ;11110000   eor   iwr0, key_old   ;               11000011   com   key_old      ;00001111   mov   iwr1, key_state  ;          10101010   or   key_state, iwr0  ;     11101011   and   iwr0, key_old   ;               00000011   eor   key_state, iwr0  ;     11101000   and   iwr1, iwr0     ;          00000010   or   key_press, iwr1  ; gedrückte Taste merken ; ;   pop   iwr1        ; Register wiederherstellen   pop   iwr0   pop   r0   out   SREG, r0   pop   r0   reti init:   ldi   temp1, LOW(RAMEND)   ; Stackpointer initialisieren   out   SPL, temp1   ldi   temp1, HIGH(RAMEND)   out   SPH, temp1   ldi   temp1, 0xFF   out   led_ddr, temp1   ldi   temp1, 0xFF      ; Tasten sind auf Eingang   out   key_port, temp1    ; Pullup Widerstände ein   ldi   temp1, 1<<CS02 | 1<<CS00  ; Timer mit Vorteiler 1024   out   TCCR0, temp1   ldi   temp1, 1<<TOIE0      ; Timer Overflow Interrupt einrichten   out   TIMSK, temp1   clr   key_old        ; die Register für die Tastenauswertung im   clr   key_state       ; Timer Interrupt initialisieren   clr   key_press   sei               ; und los gehts: Timer frei   ldi   leds, 0xFF   out   led_port, leds main:   cli               ;   mov   temp1, key_press    ; Einen ev. Tastendruck merken und ...   clr   key_press       ; Tastendruck zurücksetzen   sei   cpi   temp1, 0        ; Tastendruck auswerten. Wenn eine von 8 Tasten   breq   main          ; gedrückt worden wäre, wäre ein entsprechendes                   ; Bit in key_press gesetzt gewesen   eor   leds, temp1      ; Die zur Taste gehörende Led umschalten   out   led_port, leds   rjmp   main
Der beinhaltet kein wait dinger... das was du erwischt hast ist der zweite Quelltext von oben! Na ja ich werde also meinen korigierten post nochmal korigieren müssen.. also wenn ich das richtig verstanden habe wird bei diesem Code auch ein Timer(der nullte) benutzt. So ich hoffe ich hab den Code jetzt richtig verstanden un interpretiert, wenn nciht dann schreit laut und gebt mir eins auf den Deckel! 
Jetzt zu meiner eigenltichen Frage: Laut dem Code da oben wird ja der Port B des AVR's als "Ausgang" deklariert und Pin D des AVR's als "Eingang". Also Pin D registriert die Tastendrücke und Port B gibt die Tastendrücke letztendlich an die Relais aus... Ich denke das habe ich soweit verstanden. Vorrausgesetzt das ist richtig was ich da gerade behaupte...
So mein Problem ist nun, dass man vom Pin D auch noch alle 8 Pins "benutzen" kann... Beim Port B geht dies aber doch nicht. Also ich meine da habe ich ja nur 6 Pins zur Verfügung weil die anderen beiden vom Anschluss des Quarzes belegt sind. Muss ich nun auch den Port C mitbenutzen oder lässt sich das Quarz auch an anderen Pins betreiben.
Das Quarz weglassen wäre natürlich auch eine Methode. Nur habe ich mir ein meinem kreativem Hohenflug überlegt, dass ich den AVR später noch mit einer seriellen Schnittstelle ausstatten will, um die Tastimpulse quasi auch Softwäreseitig vom PC auslösen zu können. Wobei mir da gerade auffällt das mir dann ja wieder zwei Pins fehlen welche für den Anschluss der seriellen Schnittstelle drauf gehen?!
So ich fasse die Fragen nochmal zusammen:  - woher bekomme ich noch zwei Ausgabe Ports? - woher bekomme ich noch zwei Ports zur Tastereingabe wenn ich die serielle Schnitsstelle einbauen will?
Kann man überhaupt den Port C unterschiedlich deklarieren. Also so das z.b. PC0 und PC1 Tasteringänge sind und PC2 und PC3 Ausgänge? Wenn ichd as machen würde dann wäre der "Programmieraufwand" aber nochmal ein bischen höher richtig?!
Ich hatte auch gerade noch einen anderen einfall. Ich hab ja nicht soviel Ahnung davon aber ich schreibe einfach mal drauf los: Könnte man das nicht mit zwei AVRS regeln?! Einer ist für die Taster und Relais Ansteuerung zuständig. Dieser bekommt kein Quarz und benutzt daher den internen Schwingkreis. Somit hat er auch genügend Pins für alle Ein und Ausgabeoperationen...
Der zweite AVR ist für die serielle Schnittstelle zuständig. Dieser bekommt deswegen natürlich auch ein Quarz.
Mein Gedanke ist dabei das man nun 8 Ausgänge des zweiten AVR'S an die Tastereingänge des ersten anschließt. Nun kann an den Tastereingängen des ersten AVR's entweder durch den Druck eines Tasters oder durch den zweiten AVR ein Flankenwechsel erreicht werden...
So ich hoffe ich hab das einigermaßen verständlich erklärt. War das jetzt müll was ich da geschrieben habe oder ist das so reintheoretisch möglich?
Wenn das bodenloser Unsinn ist dann tuts mir leid. Ich hab ja quasi keien Erfahrung mit dem Ding! Vielen Dank!
|
|
« Letzte Änderung: Juni 19, 2007, 01:20:32 von Fabeulous »
|
Gespeichert
|
|
|
|
Stukaa
Wakü-Poseidon

Karma: +2/-0
Offline
Geschlecht: 
Beiträge: 414
+_ö
|
erstmal @reisi: natürlich ist es nicht so schön wenn der AVR beim warten einfach nur idelt, statt das ganze nebenbei per timer zu regeln..
allerdings ist es mir persönlich lieber, mal ein wenig zu ideln, da ich sowieso max 5% des programmspeichers benutze, und somit die verschenkte zeit quasi zu vernachlässigen ist, als einen wertvollen PWM ausgang mit einem timer zu vergeuden..
das mag natürlich von der anwendung abhängen..
@Fabeulous
ja den code meine ich, und ich meinte, wie gesagt, dass es teilweise evtl sogar vielleicht besser sein könnte mit waits zu arbeiten.. natürlich abhängig von der anwendung
allerdings, der code verwendet timer 0
@pins: ja das ist richtig wie du das siehst, allerdings würde man korrekterweise wohl sagen, dass _port_D der eingang, und portB der ausgang ist.. naja das nur am rande..
wenn du tatsächlich mit quartz und serieller schnittstelle arbeiten willst, bleibt dir nirgendwo ein kompletter 8pin port frei: PortD, pin 0+1 sind für die serielle übertragung da, PortB 6+7 für den Quartz, das kann man auch nicht ändern
und PortC hat lediglich 5pins, da der 6. , reset, reserviert ist.
mit dem codegerüst, das ich um den code von oben gestückelt habe, kannst du für jeden einzelnen der eingabe pins verschiedene ausgaben auslösen.. das problem ist nur dass der eingabe port in jedem fall an alle taster angeschlossen werden muss..
"mein" code würde es wohl auch ermöglichen, den halben eingangsport für die ausgabe zu verwenden, ich bin mir sicher das die entprellroutine das verkraftet  allerdings hättest du ja dann keine 8 kanäle mehr
die variante für eine serielle schnittstelle mit einem 2. µC ist sicher machbar.. vielleicht sogar nicht schlecht.. der avr ohne quartz würde dann port D und B als 8 Bit verfügbar haben.. eine kommunikation würde dann über die I2C oder auch TWI schnittstelle stattfinden können ( PortC, Pin4+5).. das wäre zwar ein wenig komplizierter zu programmieren, aber sicher, einfach um was zum basteln zu haben wärs ja schon ganz cool..
ich persönlich würde dann evtl eher auf einen Mega16 umsteigen.. aber man muss sich ja nicht immer vor herausforderungen drücken.. speziell da du die 8'er jetzt erstmal hast..
|
|
|
Gespeichert
|
digitall Oo
|
|
|
Fabeulous
Gast
|
So erstmal danke! Gut ich denke dann werde ich das so machen wie ich das da beschrieben habe... Zu der Kommunikation über die I2C und TWI Schnittstelle? Ist das ebsser so oder könnte man das auch so machen wie ich das als erstes beschrieben habe?
P.S.: Die Sachen sind heute von reichelt gekommen... Wen es interessiert hier was zum gucken!
|
|
|
Gespeichert
|
|
|
|
Reisi
Lötkolbenfreak

Karma: +2/-0
Offline
Beiträge: 190
|
erstmal @reisi: natürlich ist es nicht so schön wenn der AVR beim warten einfach nur idelt, statt das ganze nebenbei per timer zu regeln..
allerdings ist es mir persönlich lieber, mal ein wenig zu ideln, da ich sowieso max 5% des programmspeichers benutze, und somit die verschenkte zeit quasi zu vernachlässigen ist, als einen wertvollen PWM ausgang mit einem timer zu vergeuden.. Also erst mal idelt der µC da nicht, und zum anderen wird der Timer nicht vergeudet. Man kann problemlos mit einem Timer eine (bzw. bei manchen auch mehrere) PWM und eine Tasterentprellung gleichzeitig nutzten. Normalerweise braucht man doch fast immer einen Timer, dann kann man den Code für die Tastenentprellung auch problemlos mit da rein schreiben.
Und zum Rest: Der Atmega8 hat in der DIL Version 23 frei programierbare I/Os (man kann jeden I/O unabhängig von anderen als In- oder Output nutzen), 2 gehen fürn Quarz, 2 für RS232 und 1 fürn Reset drauf, also bleiben noch 18 I/Os übrig. Für 8 Taster und 8 Relais reicht das doch vollkommen aus, bleiben sogar noch 2 I/Os übrig. Wenn man noch mehr möchte könnte man z.B. auch noch die Taster mit einen Widerstandsnetzwerk an einen AD-Wandler legen, dadurch hätte man wieder ein paar Ausgänge frei. (Für einen 4fach Variante würde damit z.B. auch ein 8pin Attiny 15 reichen) Prinzipiell bräuchte man für diese Anwendung auch gar keinen Quarz, dafür würde der interne Oszillator auch ausreichen, für eine Erweiterung mit der Seriellen Schnittstelle ist der aber zu ungenau, da ist ein Quarz dann widerrum Pflicht.
|
|
|
Gespeichert
|
|
|
|
|
Reisi
Lötkolbenfreak

Karma: +2/-0
Offline
Beiträge: 190
|
also wenn ich den µC nur wegen PWM benutze, dann brauche ich keinen anderen timer..
und wie willst du denn den Timer x gleichzeitig als timer und pwm benutzen? du brauchst dann doch schon ganz andere einstellungen im TCCRx oder wie oder wat? willst du zwischendurch die einstellungen verändern? das würde sich doch im ergebnis der pwm niederschlagen!? Mal ein kleines Beispiel: Man initialisierst Timer1 so, dass der eine 20kHz PWM erzeugt. Der Dutycycle wird z.B. in der Main Schleife über das Compare Register eingestellt. Für eine Tasterenprellung würde ich in der Initialisierung zusätzlich noch den Overflow Interrupt aktivieren (falls der nicht sowieso schon für was anderes verwendet wird). Dadurch würde eben alle 50µs ein Interrupt ausgelöst und in der ISR kommt dann die Routine zur Entprellung mit rein.
Ich kann schon mal ein Beispiel geben, ist allerdings in C, aber ich denk zum Verständniss reichts aus:
uint8_t SW_timer = 20; //SW Timer, womit nur alle 1ms abgefragt ist uint8_t Taster1_timer = 0; //SW Timer fürs entprellen
if(SW_timer == 0) //falls 1ms erreicht, { SW_timer = 20; //Timer rücksetzten und anschließend if(Taster1_timer == 0) //Taster abfragen { if(/*Taster1 gedrückt*/) //falls Taster gedrückt { Taster1_timer = 20; //Timer setzten, so dass Taster für 20ms nicht //abgefragt wird und anschließend ... //Gewünschte Aktion ausführen } } else Taster1_timer--; //falls Timer != 0, um 1 dekrementieren, //und damit die erneute Abfrage verhindern } else SW_timer--; //Timer dekrementieren um nur alle 1ms //abzufragen Im Prinzip ists ganz einfach. Die Taster werden so pi mal daumen im 1ms Takt abgefragt. Ist irgendein (oder auch mehrere) Taster gedrückt, wird die gewünschte Aktion ausgeführt und über einen Softwaretimer wird dafür gesorgt, dass dieser Taster für 20-100ms (je nachdem wie lange der Taster prellt) nicht abgefragt wird. Irgendwelche Zustände zwischenzuspeichern ist bei Tastern eigentlich nicht notwendig, außer es gibt Fehlauslösungen durch irgendwelche Störungen.
und die sache mit dem AD wandler hört sich ja ganz nett an.. aber man muss ja nicht gleich mit der tür ins haus fallen.. ich kann mir dazu zwar in etwa vorstellen, wie das ganze theroetisch geht.. aber praktisch wirds dann wohl komplizierter
So schlimm ist das gar nicht, bei 4 Tastern sind das 5 Widerstände, und auch programiertechnisch hält sich das in C mit Hilfe von switch case in Grenzen. In Assambler artet das allerdings in Tipparbeit aus.
|
|
« Letzte Änderung: Juni 19, 2007, 20:06:14 von Reisi »
|
Gespeichert
|
|
|
|
|
Fabeulous
Gast
|
So um mich mla wieder zu melden... Also die klamotten von reichelt sind heute angekommen... Habe natürlich direkt begonnen udn anch eine rhalben stunde gemerkt das ich antürlich was veregssen habe... Undzwar hab ich anstelle des 4,7kohm iwderstandes für den isp einen 47 n kerko bestellt... na ja ist natürlich ein bischen lahm gelaufen aber dann muss ich halt nochmal was bestellen...
Währenddessen habe ich mit stukka auch über meine Problemlösung dikstuiert und wir haben quasi beschlossen und für gut befunden das meine vorgeschlagene lösung zwar nicht die eleganteste aber die einfachste lösung ist... In einem anflug von kreativem arbeitswahn habe ich diese hochentwickelte computersimulation erstellt...

ich finde sie sehr schön nebenbei gesagt... So wie bereits gesagt ahbe ich vor zwei atmels zu verbauen... Atmel A: ...hat keinen Quarz und benutzt den internet Schwingkreis wodurch ich an allen Ports 8 Pins frei hab(außer Port C natürlich) ...reagiert auf eventuelle Flankenwechsel an seinen Eingängen welche durch eventuelle Taster oder auch den zweiten Atmel ausgelöst werden können ...setzt die ausgänge und schaltet somit die Relais Atmel B: ...kommuniziert per serieller Verbdingun mit dem PC ...kann die Eingänge von Atmel B genauso wie die Taster schalten
So ich hoffe ich habe das ausreichend und vor allem verständlich beschrieben... Ich werde mich jetzt mal daran machen vernünftige Schaltpläne per PC erstellen zu können weil ich euch nciht nocheinmal so eine hochentwickelte Computersimulation antun will... Also bis später 
EDIT: Sorry für die rechtschriebfehler... erst wollte ich sie wegmachen aber dann habe ich mir gedacht das es schon irgendwo sehenswert ist wieviele Rechtschriebfehler ein Mensch in so einem kurzem Text machen kann! Ich gelobe Besserung fürs nächste mal!
|
|
|
Gespeichert
|
|
|
|
|