Forum: Mikrocontroller und Digitale Elektronik Brauche Hilfe für Quiz-Buzzer


von Moritz M. (Gast)


Lesenswert?

Hallo,

Ich bin gerade an einem kleinen (und meinem ersten) AVR-Projekt: Ein 
Buzzer für eine Quizshow; ich meine die großen runden Knöpfe, wo man 
draufdrückt wenn man die Antwort weiß (So wie 
http://www.timebike.de/Bilder_Timebike/buzzer.jpg also). Es ist alles 
schon fertig, ich habe nur noch ein paar Probleme mit dem Assembler-Code 
und der µC-Beschaltung (ATTINY13).

Das ganze soll wiefolgt ablaufen:
Jemand drückt einen von 2 Buzzern (gegen VCC?!), die entsprechende LED 
(gg. GND?!) und der Summer (auch GND?!) werden eingeschaltet, der Summer 
geht nach 2 Sekunden aus, während die LED weiterleuchtet, bis der 
Reset-Taster (auch VCC?!) gedrückt wird.

Erstmal hier der bisherige Code:
1
.INCLUDE "tn13def.inc"
2
; 1. Buzzer = BZR1 = PB2
3
; 2. Buzzer = BZR2 = PB1
4
; 1. Lampe = LED1 = PB5
5
; 2. Lampe = LED2 = PB4
6
; Summer = SMR = PB3
7
; Reset-Knopf = RST = PB0
8
; X = 100000000?!
9
10
11
main:
12
 ldi r16, 0                                    ; leere r16
13
 ldi r17, 0                                    ; leere r17
14
 ldi r18, 0xff
15
 ldi r18, (0<<PB2) | (0<<PB1) | (0<<PB0)
16
 out DDRB, r18                                 ; setze DDR
17
 ldi r18, 0xff
18
 ldi r18, (0<<PB5) | (0<<PB4) | (0<<PB3)
19
 out PORTB, r18                                ; setze PORTB
20
 in r17, PINB                                  ; BZR1 auslesen
21
;!!! breq e17                                      ; weiter, wenn nicht gedrückt
22
 rjmp b1p                                      ; wenn gedrückt, gehe zu b1p.
23
 in r17, PINB                                  ; BZR2 auslesen
24
;!!! breq r17                                      ; weiter, wenn nicht gedrückt
25
 rjmp b2p                                      ; wenn gedrückt, gehe zu b2p.
26
 rjmp main                                     ; gehe zu main.
27
28
b1p:
29
 ldi r18, (1<<PB5) | (1<<PB3)
30
 out PORTB, r18                                ; schalte LED1 und SMR an.
31
 ;loop?!
32
  nop                                          ; warten
33
 ldi r18, (0<<PB3)
34
 out PORTB, r18                                ; schalte SMR aus.
35
 loop1r:
36
  in r17, PINB                                 ; RST auslesen
37
;!!!  breq r17                                     ; weiter, wenn nicht gedrückt
38
  rjmp main                                    ; wenn gedrückt, gehe zu main.
39
  rjmp loop1r                                  ; gehe zu loop1r
40
41
b2p:
42
 ldi r18, (1<<PB4) | (1<<PB3)
43
 out PORTB, r18                                ; schalte LED2 und SMR an.
44
 ldi r16, 1                                    ; setze r16 = X.
45
 ;loop?
46
  nop                                          ; warten
47
 ldi r18, (0<<PB3)
48
 out PORTB, r18                                ; schalte SMR aus.
49
 loop2r:
50
  in r17, PINB                                 ; RST auslesen
51
;!!!  breq r17 ;///                                     ; weiter, wenn nicht gedrückt
52
  rjmp main                                    ; wenn gedrückt, gehe zu main.
53
  rjmp loop2r                                  ; gehe zu loop2r

Meine Fragen jetzt:
1. Stimmt die Beschaltung und die Richtungen in DDRB und PORTB
2. wie kann ich bei "///" nur ein bestimmtes Bit auslesen
3. Warum meldet AVR Studio bei den breq-Zeilen ("!!!") einen Fehler (r17 
sei keine Konstante)? Wenn r17 eine Konstante sein müsste, was wäre der 
Sinn an breq? Oder habe ich einen falschen Befehl erwischt?
4. Wie kann ich 2 Sekunden warten oder "nop" tun?

Ich bin gerade bei Linux (nicht bei Windows mit AVR Studio) und kann 
deshalb die genaue Fehlerausgabe nicht posten, werde das aber auf Wunsch 
später noch nachholen.

Ich bitte um schnelle Antworten, das Projekt sollte nach Möglichkeit 
morgen fertig sein.

Liebe Grüße,
Moritz M.

von Michael M. (eos400dman)


Lesenswert?

Moritz M. schrieb:
> Meine Fragen jetzt:
> 1. Stimmt die Beschaltung und die Richtungen in DDRB und PORTB
Ich würde die Schalter gegen GND machen. Dann kannst du die internen 
Pullupwiderstände des AVRs benutzen
> 2. wie kann ich bei "///" nur ein bestimmtes Bit auslesen?
Zum Beispiel so:
sbrc r16, 0
rjmp bit 0 gesetzt
rjmp bit 0 nicht gesetzt
> 3. Warum meldet AVR Studio bei den breq-Zeilen ("!!!") einen Fehler (r17
> sei keine Konstante)? Wenn r17 eine Konstante sein müsste, was wäre der
> Sinn an breq? Oder habe ich einen falschen Befehl erwischt?
Du musst zuvor einen Vergleich durchführen zum Beispiel so
cpi r16, 100
breq wenn_r16_gleich_100
> 4. Wie kann ich 2 Sekunden warten oder "nop" tun?
Diese Programm sollte dir helfen:
http://www.home.unix-ag.org/tjabo/avr/AVRdelayloop.html

Gruß Michael

von Moritz M. (Gast)


Lesenswert?

Vielen herzlichen Dank für die schnelle und gute Antwort, Michael!
Damit bin ich sehr viel weiter gekommen!

Was ich allerdings noch nicht ganz verstehe, ist, wann in DDRB oder 
PORTB jeweils eine 1 bzw. eine 0 gesetzt werden muss. Stimmt mein Ansatz 
an dieser Stelle? Und wenn ich die Schalter gegen GND schalte, muss ich 
dann in PORTB das Bit umdrehen oder was muss ich da machen?

von Michael M. (eos400dman)


Lesenswert?

Für deine Lampen und den Summer musst du das Bit in DDR setzen, damit 
der Pin als Ausgang arbeitet. Jetzt kannst du mit dem PORT Register ein 
und aus schalten. Wenn das jeweilige DDR Bit Null ist ist der Pin ein 
Eingang, jetzt kannst du mit dem PORT Register die Pull-Ups ein- und 
ausschalten. Du musst aber darauf achten das der AVR den Strom deiner 
Lampen und des Summers packt.

Gruß Michael

von Herr M. (herrmueller)


Angehängte Dateien:

Lesenswert?

Hallo,
es tut mir leid, wenn ich mich hier einmische, aber wenn das Projekt 
morgen fertig sein soll, dann wird das knapp.
Ich weiss nicht, ob Du die Grundlagen bis dahin alle intus hast. Deshalb 
biete ich Dir einen Vorschlag, der bei mir so funktioniert, und den Du 
übernehmen kannst, und Du lernst dann später alles zu verstehen, und 
bleibst hoffentlich auch danach noch bei der Sache.

Bei meinem Programm alles gegen GND (ist dann auch einfacher zu 
verdrahten). Als Reset Taste nutze ich den Controller-Reset, der alles 
wieder auf Anfang setzt.

PB0/1  = Buzzer 1/2
PB2/3  = LED 1/2
PB4 = Summer (<30mA)
(PB5) RESET = Taste      wie gesagt, alles gegen GND

ATtiny13    9.6Mhz /8  (Lieferzustand)

Viel Spass


herrmueller

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.