Zahlenschloss mit mega8 problem

Gast #2055198
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 ;)
Angehängte Dateien:
Gast #2055214
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...
Moderator (Firma: Titel) Persönliche Seite #2055364
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.
#2055648
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
Gast #2056925
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...
#2056983
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
Gast #2056986
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]
#2057005
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
Gast #2057024
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.
Gast #2057070
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...
#2057120
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
#2057231
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren