Forum: Mikrocontroller und Digitale Elektronik Zahlenschloss mit mega8 problem


von Florian (Gast)


Angehängte Dateien:

Lesenswert?

moin,

habe nen hoffentlich kleines problem...

und zwar bastel ich grad an einem zahlenschloss mit hilfe eines mega8´s.
im angehängten schaltplan sieht man die Pinne für die tastatur an PD0 - 
PD7, wobei nur PD0,PD1,PD2,PD4 benutzt werden da ich es erstmal mit nem 
BCD-Dekodierschalter gemacht habe der mit nem Taster (PC3) bestätigt 
wird. PD3 hab ich versaut der hat keinen kontakt mehr zum board ;)

so jetzt zum Problem.

ich gebe die 4 zahlen richtig(!) ein, und die LEDs blinken auch bei 
tastendruck... so eigentlich müsste nach dem 4. tastendruck die grüne 
LED angehen und das relais ansprechen, jedoch geht die rote an... das 
heißt ja eig. das die codeeingabe nicht funktioniert nur wo liegt da der 
fehler?

habe auch schon versucht den code als 0 0 0 0 zu machen, jedoch kommt 
der gleiche fehler...

Im anhang ist einmal der Schaltplan und das Programm ;)

Hoffe ihr könnt mir helfen ;)

von ich (Gast)


Lesenswert?

Nur mit der APS Datei kann man nicht viel anfangen, eine *.c Datei wäre 
hilfreich. Kann es sein dass die rote LED nach einem reset angesteuert 
wird? Das wird der Controller nämlich tun wenn du versuchst das Relais 
an zu steuern.
Schau dir mal die Polung deiner Freilaufdiode an...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Florian schrieb:
> Im anhang ist einmal der Schaltplan und das Programm ;)
Ähm... tut das Ding wirklich?
Der Quarz ist sehr eigenwillig beschaltet und seine Kondensatoren sind 
um 3 Zehnerpotenzen zu groß... :-o

Mit ein wenig Glück läuft dein uC mit dem internen Oszillator, dann tut 
diese seltsame Beschaltung nicht weh.

Und ein Blockkondensator zwischen Vcc und GND am uC ist eigentlich auch 
kein unnötiger Luxus.

Du könntest im Schaltplan Symbole für Vcc und GND nehmen (so wie alle 
anderen auch). Such mal in der Supply Library vom EAGLE.

von Jan S. (jan_s)


Lesenswert?

1.) Quarz total falsch beschaltet
2.) Wenn Du da wirklich einen 7806 drinne hast und sonst nichts, dann 
bist Du nicht gerade net zum AVR... ;-)

von ka-long (Gast)


Lesenswert?

Hi,

1. Quarz falsch angeschlossen (muss zwischen XTAL1 und XTAL2)
2. Caps für den Quarz zu groß (22pF nicht 22nF)
3. D1 ist sicher ne Freilaufdiode -> ist falsch run

BR
ka-long

von Daniel H. (Firma: keine) (commander)


Lesenswert?

D1 ist auch falsch herum drin, in der Form überbrückt sie das Relais...

von Florian (Gast)


Lesenswert?

1) diode hab ich aber richtig rum drin ist mir hinterher auch 
aufgefallen ^^
2) die beschaltung vom quarz und so hab ich im netz gefunden
3) festspannungsregler ist 7805 ;)

von Karl H. (kbuchegg)


Lesenswert?

Florian schrieb:
> 1) diode hab ich aber richtig rum drin ist mir hinterher auch
> aufgefallen ^^

OK. Ist eine reine Frage des Einbaus

> 2) die beschaltung vom quarz und so hab ich im netz gefunden

Kann ich mir nicht vorstellen.
So wird der Quarz nicht funktionieren. Solange du ihn nicht aktivierst, 
spielt es allerdings keine Rolle :-)

http://www.mikrocontroller.net/articles/AVR-Tutorial:_Equipment#Quarz_statt_Quarzoszillator

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Florian schrieb:
> 2) die beschaltung ... hab ich im netz gefunden
Sieh dir da besser mal das Datenblatt an. Da sind zwar evtl. auch Fehler 
drin, aber garantiert keine solche bösen...  :-o

von Christian D. (chris83)


Lesenswert?

Zu den oben schon genannten Fehler kommt noch das fehlende Programm 
hinzu :)

von Peter D. (peda)


Lesenswert?

[Hellseher-Gen ein]
Deine Entprellroutine taugt nix.
[Hellseher-Gen aus]

Ein *.aps enthält nix lesbares.
Das Programm ist die Datei *.c


Peter

von Florian (Gast)


Lesenswert?

das programm packe ich morgen nach... bin am laptop da hab ich das 
programm nicht drauf ...

von Florian (Gast)


Angehängte Dateien:

Lesenswert?

so hier der C-Code ;)

von Norbert (Gast)


Lesenswert?

>> int code[3];

...

>> (code[0]==0)&&(code[1]==1)&&(code[2]==2)&&(code[3]==3)


Du hast dein Array zu 33% überstrapaziert ;-)

von R. M. (rmax)


Lesenswert?

Du inkludierst util/delay.h ohne vorher F_CPU zu definieren, d.H. die 
Delay-Routinen gehen wahrscheinlich von der falschen (zu niedrigen) 
Taktfrequenz aus und machen Dir damit die Entprellung kaputt.

von Florian (Gast)


Lesenswert?

bin jetzt grad bisschen überfordert mit den antworten... (sind noch 
nicht ganz so weit in der schule)...

könnt ihr mir auch sagen wie ich das lösen kann??

okay die CPU definieren aber warum ich das datenfeld überstrapaziert hab 
frage ich mich...

von Sven L. (svenl)


Lesenswert?

Du legst ein Array mit drei Elementen an:
1
int code[3];

Und greifst dann auf 4 (!) Elemente dieses Arrays zu:
1
if ((code[0]==0)&&(code[1]==1)&&(code[2]==2)&&(code[3]==3))

Da liest Du also über den Speicher des Arrays hinaus. Das Ergebnis wird 
ein undefinierbares Verhalten Deines Programms sein, in Deinem Falle 
eben, dass der Code immer falsch ist.

Ein Array "int code[3]" hat eben nur die Element-Indizes von 0-2, 
nämlich eben genau diese DREI Elemente. Alles klar?

Gruß!

Sven

von Norbert (Gast)


Lesenswert?

Florian schrieb:
> bin jetzt grad bisschen überfordert mit den antworten... (sind noch
> nicht ganz so weit in der schule)...
>
> könnt ihr mir auch sagen wie ich das lösen kann??
>
> okay die CPU definieren aber warum ich das datenfeld überstrapaziert hab
> frage ich mich...

Wenn Du ein Array anlegst

int code[3]

dann enthält es drei Elemente nämlich code[0],code[1] und code[2]
Du brauchst aber vier Stück, also:

int code[4];    // code[0] .. code[3]

von Norbert (Gast)


Lesenswert?

Ja ja, da haben wir es wieder...

Geschwindigkeit ist Alles! ;-)

von Sven L. (svenl)


Lesenswert?

Passiert halt....

Der Threadersteller sollte sich aber auch Gedanken über 
Kommentierung/Beschreibung seines Quelltextes machen sowie sich per 
#define evtl. günstige Makros anlegen.

Die PIN/PORT-Zuweisungen machen den Code jedenfalls schlecht lesbar.

Das Konstrukt hier is übrigens immer wahr:
1
        if (PINC | 0x08)
2
        {
3
          i++;
4
          PORTC=0x00;
5
        }

Wenn Du das Bit 0x08 in der Variable PINC prüfen möchtest, so solltest 
Du den Ausdruck so formulieren:
1
if (PINC & 0x08)

Gruß!

Sven

von Johannes (Gast)


Lesenswert?

Das soll heißen wenn du ein Array der größe 3 anlegst, enthält es 3 
Werte.
Nachdem man bei 0 das zählen anfängt, kannst du nur 0, 1 und 2 einlesen.

Wenn du in dein letztes Feld schreibst, landest du irgendwo in einem 
Uninitialisiertem Bereich.

Du musst also aus deinem

int code[3];

ein

int code[4]machen.

von Florian (Gast)


Lesenswert?

asooo...ich war der meinung das ich wenn ich int code[3] mache, dass 
dann von 0-3 deklariert werden... naja wird verbessert...

aber warum ist dies so:
Das Konstrukt hier is übrigens immer wahr:
1
        if (PINC | 0x08)
2
        {
3
          i++;
4
          PORTC=0x00;
5
        }

es soll ja der taster gedrückt werden und beim loslassen, wird i 
erhöht...

von Sven L. (svenl)


Lesenswert?

Wenn Du darauf prüfen willst, ob ein Bit nicht gesetzt ist, dann geht 
das so:
1
if (PINC & ~(0x08))

Die Tilde "~" ist der sogenannte Komplementäroperator. Er bedeutet das 
bitweise Gegenteil (Komplement) des nachfolgenden Ausdrucks.

In diesem Falle deklarieren wir das Bit 0x08 mit der bloßen Angabe des 
Wertes als "Bit 0x08 gesetzt, alle anderen Bits sind 0". Wird nun der 
Komplementäroperator auf diesen Ausdruck angewandt, so werden alle Bits 
invertiert, sprich: Alle Bits sind 1, aber das Bit 0x08 ist null.

Dieses "Komplementärergebnis" verUNDEN wird mit dem UND-Operator (&) mit 
der Variable. Mit der Folge, dass im Ergebnis alle Bits übernommen 
werden, aber das angegebene Bit 0x08 definitiv 0 ist. 0 und 0 = 0, 
ebenso wie 1 & 0 = 0.

Präge Dir mal folgende Kurzschreibweisen ein:
1
// Bit 0x08 setzen (1)
2
PORTA &= 0x08;
3
4
// Bit 0x08 löschen (0)
5
PORTA &= ~(0x08);

Die Klammern sind dabei nicht unbedingt nötig, aber erhöhen die 
Lesbarkeit enorm. Außerdem kann man so den Term "0x08" beliebig 
erweitern...zum Beispiel mit einer Maske verODERN oder so.

Diese Schreibweise sind Kurzschreibweisen. PORTA &= 0x08 ist das gleiche 
wie PORTA = PORTA & 0x08.

Ebenso gibt es den Operator |=, welcher dem ODER-Equivalent zu eben 
genanntem Beispiel entspricht.

Siehe Kernighan/Ritchie - The C Programming Language (2nd Edition), 
Verlag Prentice Hall, ISBN 0-13-110362-8 , Seiten 48-51.

Ich empfehle Dir das Buch im englischsprachigen Original. Die deutsche 
Übersetzung liest sich nicht so gut.

Gruß!

Sven

von R. M. (rmax)


Lesenswert?

Sven L. schrieb:
> Wenn Du darauf prüfen willst, ob ein Bit nicht gesetzt ist, dann geht
> das so:
>
1
> if (PINC & ~(0x08))
2
>

Damit prüfst Du nicht, ob ein bestimmtes Bit nicht gesetzt ist, sondern 
ob von allen anderen Bits eines oder mehrere gesetzt sind. Das 
nicht-gesetzt sein eines bestimmten Bits prüft man z.B. so:
1
if (~PINC & 0x08)

> Präge Dir mal folgende Kurzschreibweisen ein:

... die aber ein Bit setzen bzw. löschen und nicht auf gesetzt-sein oder 
gelöscht-sein prüfen.

> [c]
> // Bit 0x08 setzen (1)
> PORTA &= 0x08;

Falscher Operator, muß |= sein.

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.