Forum: Mikrocontroller und Digitale Elektronik ATmega16 + Buzzer


von RoY (Gast)


Angehängte Dateien:

Lesenswert?

Also bevor jetzt Sachen kommen wie "Verschwendung usw", ich habe
erstens nur einen ATmega16 und einen ATmega32 und es soll nur zum
testen und rumspielen sein. Da das Programm zur übung dient habe ich es
in Assembler geschrieben...

Ich habe ein Programm geschrieben das wie ein Buzzer für  Spieler
funktionieren soll... Die Schaltung besteht aus einer Station
(Resettaster, uC, Summer und Spannungsquelle) und 3 "Buzzer" (Jeweils
1 Taster + 1 LED). Wird also der Resettaster gedrückt so ist alles
wieder aus, wird dann ein Buzzer (Taster) gedrückt so, so summt der
Summer 1-2 sec und danach leuchtet die LED beim Taster solange bis
wieder der Resettaster gedrückt wird...

Leider funtzt mein Programm nicht also es macht garnix... Es leuchtet
nix...

von Michael U. (Gast)


Lesenswert?

Hallo,

ich würde auch nicht leuchten... ;)

Mit

 ldi   Temp,00
 out   DDRB,Temp

setzt Du PortB auf Eingang.

Richtig wäre ldi Temp,$ff oder 255 oder 0b11111111

Weiter: das Du Port D nicht auf Eingang setzt, ist nur verzeihlich weil
der AVR nach dem Reset alles auf Eingang hat.

Ich kann Deine Schaltung leider so schlecht erkennen, muß mal Glaskugel
putzen gehen...

Aber: wenn Du die Taster wie üblich gegen Masse geschaltet hast, mußt
Du entweder externe PullUp-Widerstände dran habe oder Du mußt die
internen PullUps einschalte.

Also noch

ldi Temp, $FF
out PORTD, TEMP ; PullUps ein
ldi TEMP,0
out DDRD,TEMP   ; Port D als Eingang.

Weiter:


  sbis   PIND,0x00
  jmp    BUZZ1

sbis erwartet als zweiten Parameter die Bitnummer, keine Bitmaske.
es sieht zumindest irreführend aus, wenn Du das hier so als Hex-Wert
schreibst. Die Bitnummern sind 0...7
Lesbarer wäre also sbis PIND,PD0 ; für Bit 0 an Port D
Die Bitnummerierung ist in den includes auch so bereits definiert.

Gruß aus Berlin
Michael

von RoY (Gast)


Angehängte Dateien:

Lesenswert?

naja mein lauflicht hat funktioniert und ist ZIEMLICH ähnlich
aufgebaut... Siehe anhang

Was du mir jetzt da erklärt hast verstehe ich nicht ^^ aber ich werd es
mir nochmal in ruhe ansehen...

von Michael U. (Gast)


Lesenswert?

Hallo,

Lauflicht:
 ser   Temp     ; alles auf 1
 out   DDRB,Temp ; Port B ist Ausgang

Buzzer:

 ldi   Temp,00 ; alles auf 0          <-
 out   DDRB,Temp ; Port B ist Eingang <-

Der Rest waren mehr Hinweise zur Lesbarkeit des Codes.

Wenn Du in einem halben Jahr in Deinen Code schaust, wirst Du es
vermutlich besser verstehen. :)

Gruß aus Berlin
Michael

von RoY (Gast)


Angehängte Dateien:

Lesenswert?

also ich habe jetzt so einiges verändert was du mir gesagt hast jedoch
funktioniert es noch immer nicht, also jetzt sind zu beginn alle LED's
am Board an (Also würde in der Schaltung der Summer vollepulle summen),
wenn ich dann resettaster drücke assiert erstmal nix ... drücke ich
dann einen buzzer so erlicht ene LED... drücke ich dann einen anderen
buzzer passiert nix... nachdem ich dann den resettaster gedrückt habe
kann ich wieder mit einem buzzer eine LED erlichen jedoch erlicht
nichteinmal die LED die zum Buzzer gehört und dabei soll keine LED
erlichen sondern eine LED leuchten und alle anderen sollen aus sein ...

von Michael U. (Gast)


Lesenswert?

Hallo,

.include "m16def.inc"

.def Temp   =r16
.def Delay1  =r17
.def Delay2  =r18
.def Delay3  =r19

RESET:

 ser   Temp           ; alles auf 1
 out   DDRB,Temp     ; PortB auf Ausgang
; da hängen Deine LED dran? Gegen GND oder gegen Ub?

;------------------
;BUZZER ABFRAGE
;------------------

START:

  sbis   PIND,PD0          ; skip, wenn PD0 auf 1
; Vermutung auch hier: Taster gegen GND, ok
  jmp    BUZZ1   ; nehmen wir an, der ist gedrückt, also PD0 ist 0

  sbis   PIND,PD1
  jmp    BUZZ2

  sbis   PIND,PD2
  jmp    BUZZ3

  rjmp   START

;------------------
;BUZZER 1 GEDRUECKT
;------------------

BUZZ1:   ; dann landen wir hier

  ldi  Temp,8
  out  PORTB,Temp   Bit 7 auf 1, wohl die Hupe? Gegen GND oder gegen
Ub?
; vermute gegen GND, sonst könnte sie mit PD7 auf High nicht hupen...


DLY1:

  dec    Delay1   ; etwas warten
  brne   DLY1

LED1:

  ldi    Temp,1       ; jetzt also PD0 auf 1
; wenn die LED gegen Ub hängt, geht sie jetzt aus!
  out   PORTB,Temp

xxx:
  sbis   PIND,PD3    ; ist PD3 0?
  jmp    RESET       ; ja, Taster gedrückt, also Reset

  rjmp   LED1        ; wieder nach oben, ist relativ sinnlos, weil PD0
ist ja schon 1, würde ein Sprung nach xxx reichen

Rest mal gelöscht um Platz zu sparen.

Du siehst, ohne Deinen Schaltplan kann ich nur raten, was passieren
könnte, weil ich nicht weiß, wie die LEDs angeschlossen sind...

Ich habe übrigens mal in Dein Lauflicht reingeschaut: ich nehme mal an,
es hat immer eine LED geleuchtet und diese wurde rechts bzw. links lang
geschoben?

Wenn das so ist, kann ich Dir versichern, daß Du nicht weißt, warum das
überhaupt funktioniert hat. ;-)

Gruß aus Berlin
Michael

von Ludwig W. (lordludwig)


Lesenswert?

zeig uns doch mal deine beschaltung.

außerdem setzten sich die eingänge nicht automatisch zurück wenn du
folgendes machst:

sbis   PIND,PD3
jmp    RESET

da würde ich noch ein

ldi    Temp,0
out   PORTB,Temp

in den reset einbauen.

außerdem brauchst du für das delay keine 3 register, weil immer nur ein
delay gleichzeitig läuft, wenn ich das richtig verstanden habe.

außerdem musst du in das Delay-Register auch erst mal was reinladen
bevor du es runterzählst und mit 0 vergleichst. des weiteren muss es
die der Port beim reset zurück gesetzt werden!

von RoY (Gast)


Lesenswert?

ja das ist so also eine led hat geleuchtet und wurde geschoben... warum
sollte das denn nicht so funktionieren??

einen schaltplan habe ich nicht aber die leds und die hupe werden alle
samt gegen masse geschlossen also er taster kommt an ub und gibt die
spannung weiter wenn gedrückt, die led kommt zwichen uC und masse und
soll so geschaltet werden die hupe auch, testen kann ich das alles nur
auf meinem stk500 weil ich die schaltung für die buzzeranlage noch
nicht aufgebaut habe... Auf dem stk500 soll:

Taster 0: BUZZER 1
Taster 1: BUZZER 2
Taster 2: BUZZER 3
Taster 3: RESET

LED 0: BUZZER 1
LED 1: BUZZER 2
LED 2: BUZZER 3
LED 3: HUPE

Wie gesagt das ganze soll wie bei einer fernsehsendung funktionieren:
Bei Taster 0,1,2 soll jeweils die Hupe 1-2 sec hupen und danach soll
die passende LED leuchten is Taster 3 gedrückt wird.

von Michael U. (Gast)


Lesenswert?

Hallo,

@Ludwig Wagner:

er geht an mehreren Stellen davon aus, daß bestimmte Zustände und
Registerinhalte "so sind, wie sie sind". ;)

Darauf wollte ich ihn möglichst stoßen, daß er das erkennt.

Wenn Du in sein Lauflicht schaust (und ich keine Tomaten auf den Augen
habe), wirst Du vermutlich sehen, welche Voraussetzung ihm da geholfen
hat.
Wenn man 0b11111111 in ein Register lädt und ausgibt, kann man es
eigentlich stundenlang im Kreis schieben und es bleiben lauter Einsen.
Nur weil ....  geht es.
Vielleicht weiß er das aber auch und ich irre mich.

Was die Fehler angeht: die habe ich genauso gemacht, ist nur länger her
als es Atmels gibt und im Internet fragen konnte ich mangels desselben
auch nicht.

Ich will ihn auch in keiner Weise ärgern, aber etwas nachdenken hat
noch nie geschadet. :)

Gruß aus Berlin
Michael

von Ludwig W. (lordludwig)


Lesenswert?

ich will auch ned ärgern, sondern helfen :)

aber alles fertig hinklatschen will ichs auch ned, sonst lernt mans
nie...

von RoY (Gast)


Lesenswert?

Wenn man 0b11111111 in ein Register lädt und ausgibt,

<-- was genau ist das für ein wert??

Und dass mein lauflicht funktioniert ist weil ich das programm aus
mehereren anderen programmen zusammen gesetzt habe, auch das delay ding
habe ich aus einem anderen programm und ich habe ehrlich gesagt kA was
da passiert... Deswegen wende ich mich ja an euch weil bisjetzt alles
so geklappt hat und jetzt geht nix mehr ...

von RoY (Gast)


Lesenswert?

ich schätze dieser wert bedeuetet binär 11111111 also alles an jedoch
weiss ich es nicht weil ich assembler eigentlich nur vom midicom kenne
da schreibt man einfach 1111b , 0Fh oder 16 deswegen kommt mir diese
0b11111111 sehr kurios vor ...

von RoY (Gast)


Lesenswert?

>> aber alles fertig hinklatschen will ichs auch ned, sonst lernt mans
nie...

da hast du wohl recht aber wenn du mir genau sagen könntest wo der
fehler iegt würde es mir mehr helfen als wenn ich jetzt stundenlang auf
einen code schaue der in meinen augen korrekt ist ...  ;)

von Michael U. (Gast)


Lesenswert?

Hallo,

hat sich gerade ünerschnitten, Dein Posting.

Also: Taster an Ub und gibt die Spannung weiter...

wenn das so ist:

  sbis   PIND,PD1 ; Überspringe den nächsten Befehl, wenn das Bit
gesetzt, also auf 1, High ist

  jmp    BUZZ2   -> hierlang also, wenn das Bit 0, Low ist, das
widerspricht Deiner Beschreibung ,daß der Taster Ub durchschaltet, dann
müßte der gedrückte Taster High, also 1 erzeugen, und der Spring zu
BUZZ2 würde NICHT stattfinden.

Der Taster dürfte also, wie es üblich ist zwischen Pin und Masse
liegen...

Dazu kommt gleich eine Frage: das AVR-Pin ist Eingang, der Taster ist
nicht gedrückt, also offen.
Was hat der Eingang dann für einen Pegel? Er hängt ja dann in der Luft
und ist nirgens angeschlossen.

LED: Du schreibst eine 1 in den Port und eine LED geht aus (zumindest
nach Deiner letzten Beschreibung).
Eine 1 heißt ja, der Port schaltet gegen Ub. Wenn die LED gegen Masse
liegen würde, müßte sie aber angehen.
Gegen Ub hätte sie dann an beiden Enden Ub und damit 0V Differenz zum
leuchten...

Ich kenne das STK500 nicht, ich habe nur das alte STK200 hier.
Da liegen LEDs und Taster gegen Masse.
Das sollte aber in der Beschreibung Deines STK500 drinstehen.

Ich bin also vorerst etwas verwirrt. :)

Zum Lauflicht:

LEDL: ; Du springst hier zum ersten mal rein

  out    PORTB,Temp ; welchen Wert enthält Temp hier?
  rol    Temp       ; und welchen Wert enthält Temp jetzt?

:-)

Gruß aus Berlin
Michael

von Michael U. (Gast)


Lesenswert?

Hallo,

der Assembler ist ja nur ein Übersetzungswerkzeug.
Die Syntax legt der Hersteller desselben halt fest.

Der AVR-Assembler von Atmel kennt
0b11100011 für Binär

0x0F oder $0F für Hex (er nimmt beides)

123 für Dezimal

012 für Oktal (mit führender Null!)
letzteres ist eine böse Falle, wenn man zur besseren Lesbarkeit zum
Beispiel folgendes schreibt:

 .db 122    ; kommen alles 3-Stellige Dezimalzahlen!!!
 .db 546
 .db 012    ; weil es so schöner aussieht
 .db 008

Gibt beim vorletzten einen falschen Wert und beim letzten eine
Fehlermeldung.

Gruß aus Berlin
Michael

von RoY (Gast)


Lesenswert?

boah voll kompliziert ... lass ieber mal das lauflicht weg das funtzt...
also laut beschreibung:

LED leuchtet wenn 1 am ausgang des uC's
Wenn taster NICHT gedrückt --> 1 am eingang des uC's

Ich jedoch möchte dass meine LED leuchtet wenn 1 am ausgang
und 1 am eingang wenn taster gedrückt ... (so soll es später in der
schaltung aussehen)

von Ludwig W. (lordludwig)


Lesenswert?

hat dein eingang einen externen pulldown? sonst können evtl. leitungen
schöne antennen sein und weitere fehler hervorrufen.

Wie schaltest du eig. den summer und die LED's? Hoffentlich doch über
transistoren, oder?

von RoY (Gast)


Lesenswert?

darüber wollte ich mir gedanken machen wenn mein programm funktioniert
... Aber ich glaube transistoren wären ne gute lösung... Welcher
eingang meinst du?? ich habe wie gesagt noch keine schaltung gbaut...

von Ludwig W. (lordludwig)


Lesenswert?

als eingang meine ich die eingänge an denen die taster angeschlossen
sind. Aber du hast recht, erst mal sollte dein programm funktionieren
(wozu aber pulldowns aber auch beitragen könnten...)

wie ist denn jetzt im moment der stand deines codes? ich blicke hier
langsam nimmer durch mit dem lauflicht ect.

Bleiben wir doch alle erst mal HIER beim buzzer... also am besten
nochmal den code posten, wie er im moment ist, dann kann ich dir auch
beispiele geben wo du was verbessern musst...

von RoY (Gast)


Angehängte Dateien:

Lesenswert?

ok hier ist der momentane code (nach einigen verbesserungen aus diesem
forum)

von Michael U. (Gast)


Lesenswert?

Hallo,

ok, also LED gegen Masse und Taster gegen Masse.
Taster gegen Masse ist üblich.
Warum?
Ganz einfach: wenn der Taster nicht gedrückt ist, muß ja trotzdem ein
sinnvolles Potential am PIN des AVR liegen. Das wird mit einem
Widerstand gegen den anderen Spannungspol gemacht.

Am Verbindungspunkt Taster-Widerstand liegt der AVR-Eingang.
1. Variante: +Ub - Widerstand - Taster - Masse
wenn der Taster offen ist, hat der AVR über den Widerstand
High-Potential, also liest eine 1
wenn der Taster geschlossen wird, hat er über den Taster Low-Potential,
liest also eine 0
Der Widerstand verhindert einen Kurzschluß beim Drücken und sorgt
dafür, daß der Pin bei offenen Taster ein eindeutiges Potential hat.

2.Variante: +Ub - Taster - Widerstand -Masse
wenn der Taster offen ist, hat der AVR über den Widerstand
Low-Potential, also liest eine 0
wenn der Taster geschlossen wird, hat er über den Taster
High-Potential, liest also eine 1

Das wäre die Version, die Du willst.
Kannst Du machen.
Macht man selten, weil der AVR interne Widerstände zwischen Pin und Ub
hat, die man einschalten kann (Datenblatt, I/O-Beschreibung).

Die 1. Variante spart also unter Umständen etliche Widerstände ein,
deshalb wird meist diese benutzt.

Letztlich ist es im Programm ja nur der Unterschied zwischen
sbis Port,Bit
und
sbic Port,Bit
ob ich bei 0 oder bei 1 springe...

Zu dem, was Ludwig Wagner schrieb:
Du verläßt Dich an mehreren Stellen darauf, das irgendwas bestimmtes in
einem Register oder Port drinsteht.

Um nach dem Start alle LEDs auszubekommen, muß im PortD alles auf 0
sein.
Das schreibst Du aber beim Initialisieren Deines Programms nirgends
rein, Du hoffst nur, daß es so ist.

Wenn Du in Deinem Programm irgendwann nach Reset springst, ist im PortD
aber das gespeichert, was Du zuletzt reingeschrieben hast und das ist
durchaus nicht 0.

Gruß aus Berlin
Michael

von Ludwig W. (lordludwig)


Lesenswert?

ich könnte dir das programm jetzt natürlich in 2 minuten richtig
schreiben, wenn du das willst, aber ich glaube da währe dir nicht
worklich geholfen.

Ich würde dir empfehlen erst mal das tutorial komplett mehrere male
durchzulesen oder sogar abzuarbeiten.

da steht eigentlich schon fast alles zu eingängen und ausgängen ect.
drinn was du hier wissen musst.

http://www.mikrocontroller.net/tutorial/

Wenn du mir verrätst wie die schaltung im moment aufbaut ist kann ich
dir ja mal ne .hex geben die du programmierst, dann sehen wir ob es
überhaupt funktioniert.

wenn ja dann können wir uns den korrekten Code zusammen erarbeiten,
denn du sollst nicht nen code reinschreiben und fertig, sondern ihn
auch verstehen.

wenn du willst auch über ICQ, geht dann denk ich schneller zum
erklähren!

von RoY (Gast)


Lesenswert?

jo also das mit dem tutorial ist so ne sache... ich habe es bereits
mehrere malen durchgelesen aber ich verstehe vieles nicht und glaube
dass ich am meisten lerne wnn ich das was ich haben möchte ans laufen
bekommen weil ich dann weiss ie es geht und es immer wieder so benutzen
kann aber einen text lesen den ich nicht verstehe wird mir wohl nicht
soderlich helfen... das mit ICQ ist ne gute idee.. meine nummer ist:
315-712-977 ich kann dich gerne heute noch annehmen aber ich würde den
"unterricht" lieber auf morgen verschieben weil heute eht nix mehr in
meinen kopf...

von Ludwig W. (lordludwig)


Lesenswert?

hab dich mal hinzugefügt, mal schaun wann ich morgen da bin, hab im
moment ned so viel zeit, aber das wird sich schon irgendwie ergeben =D

von RoY (Gast)


Lesenswert?

kk alles klar ... ich habe auch recht wenig zeit weil ich im
abschlussjahr bin für den techniker in der kommunikations elektronik
... deswegen auch das atmel zeugs. Ich muss für mein projekt Atmel in
assembler programmieren können und damit dann eine blackbox
programmieren die wir in einer gruppe zusammen bauen... Aber erstmal
wäre es gut wenn ich "einfache" sachen hinkriegen ;)

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.