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.
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
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?
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
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