Forum: Mikrocontroller und Digitale Elektronik DCF auf INT0


von Ryan P. (ryanpolster)


Angehängte Dateien:

Lesenswert?

Ich grüße euch ihr Könner :)

Ich hoffe ihr könnt mir bei meinem Problem, welches ich im Folgendem 
näher erläutern werde, helfen.

Hardware:
µC: ATMega16 @ 1Mhz
HD44780-kompatibler LCD
DCF77-Empfänger: DCF1

Anschluss an den µC:
DCF-DATA an INT0
DCF-OUT an PC6

Software:
DCF-Library von Ulrich Radig
LCD-Library von Peter Fleury

Die LCD-Lib hat schon funktioniert. Erst jüngsten Ereignissen zur Folge 
zeigt er nichts mehr an. Da sind wir auch schon bei meinem Problem - 
mein LCD zeigt seit Nutzung von INT0 nichts mehr an (nicht die bekannten 
2 Balken, die sieht man nur kurz am Anfang, sondern wirklich garnichts).

Ich hänge noch die Libs und mein Hauptprogramm an.

Ich wäre sehr dankbar wenn sich jemand die Zeit nimmt einen Anfänger zu 
helfen. :)

LG Ryan

PS.: das Datenblatt vom ATmega16 ist unabsichtlich mit angehängt ^^

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?


von holger (Gast)


Lesenswert?

Mach das

ADC_Voltage_Initialize();

in der main() weg.
Du schaltest da einen Interrupt für den es keinen
Vektor gibt.

Bist du sicher das das ganze mit nur 1MHz Takt laufen soll?

von Ryan P. (ryanpolster)


Lesenswert?

Der Wert kam zustande als ich die DCF Abfrage über 1ms pollen wollte, 
leider erfolglos. Jetzt versuch ichs mit ext. Interrupt.
Auf welchen Wert sollte ich den mind. setzen?

von holger (Gast)


Lesenswert?

>Auf welchen Wert sollte ich den mind. setzen?

Auf den Wert mit dem dein Controller läuft?
Auf was denn sonst? Weisst du eigentlich was du tust?

F_CPU zu definieren stellt nicht die Taktfrequenz
deines Controllers ein. Du gibst damit an mit welcher
Taktfrequenz er läuft. Das kann der Compiler ja nicht raten.

von Ryan P. (ryanpolster)


Lesenswert?

Oh ja sorry hab dich missverstanden.
Der µC läuft auf 1Mhz. Nur bin ich noch nicht so sehr vertraut mit all 
dem hier. Es heißt man sollte bei den Fuses aufpassen. Die Fuse 
"SUT_CKSEL" ist auf "INTRCOSC_1MHZ_6CK_64MS". Kann ich da einfach 
"rumspielen" oder kann da was gröberes passieren?

von Ryan P. (ryanpolster)


Lesenswert?

Was für Fuses sollten für INT0 gesetzt sein? Oder gibt es da keinen 
Zusammenhang?

von holger (Gast)


Lesenswert?

>Der µC läuft auf 1Mhz. Nur bin ich noch nicht so sehr vertraut mit all
>dem hier. Es heißt man sollte bei den Fuses aufpassen.

Ja das sollte man.

> Die Fuse
>"SUT_CKSEL" ist auf "INTRCOSC_1MHZ_6CK_64MS". Kann ich da einfach
>"rumspielen" oder kann da was gröberes passieren?

Lass die erstmal so und entferne die Funktion die ich oben
genannt habe aus main(). Dann sollte dein Display wieder
was anzeigen.

von Ryan P. (ryanpolster)


Lesenswert?

Tut er leider nicht. Jetzt sind aber die zwei Balken wieder da, die 
anzeigen ob der LCD initialisiert ist oder nicht.

von Karl H. (kbuchegg)


Lesenswert?

Dann ab zur Fehlersuche. Das hatten wir ja schon mal

Beitrag "20x4 lcd zeigt immer das gleiche an"

von holger (Gast)


Lesenswert?

>Tut er leider nicht. Jetzt sind aber die zwei Balken wieder da, die
>anzeigen ob der LCD initialisiert ist oder nicht.

Stecker rausziehen, bis 10 zählen und neu reinstecken hilft nicht?

Hat das Display mit diesem Programm überhaupt schon mal
was angezeigt? Wenn nein kontrolliere alle Einstellungen noch einmal.

von holger (Gast)


Lesenswert?

@Karl Heinz

>Dann ab zur Fehlersuche. Das hatten wir ja schon mal
>
>Beitrag "20x4 lcd zeigt immer das gleiche an"

Du hättest gleich hier hin verlinken sollen;)

Beitrag "Re: 20x4 lcd zeigt immer das gleiche an"

von Karl H. (kbuchegg)


Lesenswert?

holger schrieb:
> @Karl Heinz
>
>>Dann ab zur Fehlersuche. Das hatten wir ja schon mal
>>
>>Beitrag "20x4 lcd zeigt immer das gleiche an"
>
> Du hättest gleich hier hin verlinken sollen;)

Am liebsten hätte ich auch auf einen ganz anderen Beitrag dort verlinkt.
Das hier
> Ich wäre sehr dankbar wenn sich jemand die Zeit nimmt einen
> Anfänger zu helfen.
ist jedenfalls starker Tobak.
Denn so 'Anfänger' sollte er nicht sein. Immerhin ist diese Arbeit ein 
wesentlicher Teil dessen, dass er in 2 Monaten eine Berufsbezeichnung 
führen darf.

von Ryan P. (ryanpolster)


Lesenswert?

Ich hab die Frequenz auf 8 Mhz gestellt. Die 1 Mhz brauchte ich ja, wie 
gesagt, nur für das 1ms pollen.

Jetzt hab ich mal wieder ne Anzeige auf dem LCD.
Die Zeit wird hochgezählt. Manchmal ein "bisschen" schneller als die 
gewohnte Zeit. Das Schema hab ich mal beobachtet und sieht wie folgt 
aus:

Die Zeit beginnt bei 0.
Zählt dann hoch bis 59 Sekunden.
Dann 1:09.
Dann in 10er Schritten weiter.
1:19
1:29
.
.
1:89
Dann zurück zu 1 Minute ca., diesmal im normalen Sekundentakt.
Bei 2:xx dann weiter mit 10er Schritten etc...

Will euch hier echt nicht mit nervigen Fragen löchern. Manchmal raff 
ichs einfach nicht, tut mit leid.

von Uwe S. (de0508)


Lesenswert?

Lbr Ryan Polster,

bitte poste bitte wieder das gesamte Programm.

Vielleicht liefert Die ein netter Mensch ein Testprogramm für deine 
Hardware.
Ach ja Hardware: bitte poste auch noch detail Bilder dieser.

Danke.

von Karl H. (kbuchegg)


Lesenswert?

Ryan Polster schrieb:


> Will euch hier echt nicht mit nervigen Fragen löchern. Manchmal raff
> ichs einfach nicht, tut mit leid.

Wenn am LCD der Text "ABCD" steht
und du diesen Text (beim 'A' beginnend) mit "XY" überschreibst, was 
steht dann am LCD?

richtig.

Da steht dann "XYCD".
Denn XY ist kürzer als ABCD. ABCD wird daher nicht komplett 
überschrieben.


Hinweis: Der 'Text' für 59  (von 0 Minuten und 59 Sekunden), ist länger 
als der Text 0 (von 1 Minute und 0 Sekunden)


Mach dir nicht selbst das Leben schwer
1
  sprintf( buf, "Time %02d:%02d:%02d", hh, mm, ss );
2
  lcd_puts( buf );

und gut ists.
(Und lies nach was die Formatierangaben beim printf bewirken)

buf muss natürlich groß genug sein, damit der String da auch rein passt! 
Nicht vergessen.

: Bearbeitet durch User
von Ryan P. (ryanpolster)


Lesenswert?

Wow! Faszinierend  was einem da angeboten wird. Die Textformatierung 
krieg ich ja in 10000 Zeilen Code nicht hin ^^

Jetzt mal ernsthaft, die Funktion bietet doch mehr Möglichkeiten als ich 
gedacht habe. Echt praktisch!

von Ryan P. (ryanpolster)


Lesenswert?

@Uwe S.: Sarkasmus?

von Ryan P. (ryanpolster)


Lesenswert?

Aja das wollte ich noch fragen:

was hat "TCNT1 = 65535 - (F_CPU / 1024);" zu bedeuten?

TCNT1 ist doch der Wert des 1. 16-Bit-Timers.
16 Bit = 65536.
Ich habe F_CPU = 8000000UL. Also 8000000 / 1024 = 7812,5.

TCNT1 = 57722,5? Wieso genau diese Zahl?

von Mike (Gast)


Lesenswert?

Ryan Polster schrieb:
> TCNT1 = 57722,5? Wieso genau diese Zahl?

In ein 16-Bit Register wirst du diese Zahl nie ablegen können und das 
hat zwei Gründe:

1. Der Compiler verwendet als Dezimaltrennzeichen den Punkt ("."), 
unabhängig davon, was du auf deinem Rechner eingestellt hast.

2. Register enthalten nur vorzeichenlose Integer-Zahlen. Rationale 
Zahlen kannst du also dafür vergessen.

von Karl H. (kbuchegg)


Lesenswert?

Ryan Polster schrieb:
> Aja das wollte ich noch fragen:
>
> was hat "TCNT1 = 65535 - (F_CPU / 1024);" zu bedeuten?
>
> TCNT1 ist doch der Wert des 1. 16-Bit-Timers.
> 16 Bit = 65536.
> Ich habe F_CPU = 8000000UL. Also 8000000 / 1024 = 7812,5.
>
> TCNT1 = 57722,5? Wieso genau diese Zahl?


Die 'Hauptfreuqenz' deines µC ist 8 Mhz.
Ohne besondere Vorkehrungen würde daher ein Timer in 1 Sekunde von 0 bis 
7999999 zählen (8 Mio Zählschritte).
Jetzt hast du aber besondere Vorkehrungen. Du hast einen Vorteiler von 
1024. D.h. der Timer zählt 1024 mal so langsam. In 1 Sekunde würde er 
daher von 0 bis 8000000/1024 gleich 7812 zählen.
Gut.
Jetzt willst du aber haben, dass der Timer nach 1 Sekunde seinen 
Overflow erreicht. Also muss er bei welcher Zahl mit zählen anfangen, 
damit er nach 1 Sekunde den Overflow (65535, da es ja ein 16 Bit Timer 
ist) hat? Du willst also wissen, bei welchem x der Timer anfangen muss, 
damit das zählen von x bis 65535 möglichst genau 1 Sekunde dauert, wenn 
der Timer mit 1024-tel der Taktfrequenz F_CPU zählt.

: Bearbeitet durch User
von Uwe S. (de0508)


Lesenswert?

Danke Karl Heinz für die Erläuterung.

Ergänzen möchte ich noch, dass die Formel nicht richtig ist.
1
TCNT1 = 65535 - (F_CPU / 1024);

Aus dem Datenblatt des atmega16 S.101ff

Normal Mode
1
The simplest mode of operation is the Normal mode (WGM13:0 = 0).
2
In this mode the counting direction is always up (incrementing), and no counter clear is performed.
3
The counter simply overruns when it passes its maximum 16-bit value (MAX = 0xFFFF) and then restarts from the BOTTOM (0x0000). In normal operation the Timer/Counter Overflow Flag (TOV1) will be set in the same timer clock cycle as the TCNT1 becomes zero.
4
The TOV1 Flag in this case behaves like a 17th bit, except that it is only set, not cleared. 
5
However, combined with the timer overflow interrupt that automatically clears the TOV1 Flag, the timer resolution can be increased by software.
6
There are no special cases to consider in the Normal mode, a new counter value can be written anytime.

Fazit
Das Timer1 Interrupt-Flag (TOV1) wird immer bei erreichen der 0 gesetzt.

Kurze Betrachtung der Arithmetik
65536 mod 2^16 = 0

65536 ist also kongruent 0 für uint16 Zahlen.

Man muss also dies schreiben:
1
TCNT1 = (uint16_t)(65536L - (F_CPU / 1024));

Beweisen kann man die Formel durch Induktion:
Hier der Anfang:
-----
N=0 entspricht (65536 mod 2^16)
Also läuft der Timer1 einmal "rum" und dann wird das Interrupt-Flag 
(TOV1) gesetzt.
TCNT1 = 0
-----
N=1 entspricht einem Timer1 Tick.
Dann muss TCNT1 = (uint16_t)65535 sein.
-----
von N nach N + 1 Schritten kann sich jeder selbst Überlegen.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Uwe S. schrieb:
> Danke Karl Heinz für die Erläuterung.
>
> Ergänzen möchte ich noch, dass die Formel nicht richtig ist.

Das ist korrekt.

Allerdings stört das in seinem Fall nicht wirklich.
Denn der Timer Overflow wird eingesetzt um das ausbleiben des 59. 
Sekunden Pulses zu detektieren. Wenn diese 'Sekunde' daher ein wenig 
länger dauert, dann ist das kein Beinbruch.


Aber genug. Es ist seine Abschlussarbeit, für die er die Hochschulreife, 
eine Berufsbezeichnung und den Titel 'Ing.' erhält. Ich finde dafür 
sollte er ruhig selber auch was tun. Bis jetzt wurde ihm eh fast alles 
vorgekaut. In 3 Monaten soll er im Berufsleben aufauchen und seinen Chef 
beraten, ob sie als Firma einen Auftrag bewältigen können oder nicht. 
Bis jetzt sehe ich noch nicht, wie das je gehen soll.
Ich frag mich ja immer, wieso sich die Leute für die alles 
entscheidenden Prüfungen immer Themen aussuchen, von denen sie 0 Ahnung 
haben. Persönlich finde ich das dämlich. Bei einer der wichtigen 
Prüfungen nehme ich mir doch ein Thema, von dem ich recht sicher 
annehmen kann, dass ich das auch bewältigen kann. Wenn ich in C schwach 
bin, von µC keine Ahnung habe,  bei Hardware schwimme wie ein Stein, 
dann werd ich doch einen Teufel tun und mir genau so ein Thema zur alles 
entscheidenden Prüfung aussuchen. Denn auch das gehört zum Berufsleben 
zu tun: Abzuschätzen, ob es besser ist einen Auftrag nicht anzunehmen 
weil man ihn nicht bewältigen kann.

: Bearbeitet durch User
von Uwe S. (de0508)


Lesenswert?

Hallo Karl Heinz,

ich hatte bei meiner Abschlussarbeit
ein Kryptographisches Verfahren "Elliptische Kurven" und dessen 
Implementierung auf Scheckkarten der damaligen Zeit untersucht.

Da hatte ich nur die Idee des Prof. und meine eigenen Fähigkeiten um die 
Aufgabenstellung zu lösen.

Internet - was'n dat ?

Heute haben die kleinen so die 100fache Rechenleistung.

von Nobby Nic (Gast)


Lesenswert?

Karl Heinz schrieb:
> In 3 Monaten soll er im Berufsleben aufauchen und seinen Chef
> beraten, ob sie als Firma einen Auftrag bewältigen können oder nicht.

Also bitte, welcher Chef verlässt sich denn einzig auf die Aussage eines 
Berufsanfängers? Wenn das nicht gerade eine 2-Mann Firma ist, hat der 
Berufsanfänger i.d.R. Kollegen, die ihm persönlich mal 
BRAINCON1..BRAINCON7 initialisieren ;-)

von Ryan P. (ryanpolster)


Lesenswert?

Darf man nicht mal mehr fragen?
Es tut mir leid wenn jemand denkt das ich alles zusammenkopiere und 
nicht nachdenke! Aber ich habe die ganze Materie hier dieses Jahr zum 
ersten Mal probiert & wer schreibt sich da ne LCD-Library und ne 
fehlerfreie DCF-Decodierung?
Ich bin nicht in der Lage etwas derartiges auf die Beine zu stellen.

Wenn meine Abschlussarbeit lauten würde: "DCF-Decodierung" dann würde 
ich mir selbst die Routinen schreiben, weil dafür dann die Zeit reicht.

Aber in ca. nen halben Jahr (ist ziemlich viel an Zeit verloren gegangen 
durch Bestellungen usw...) schafft das kein Anfänger.
Jedoch lerne ich hier trotzdem viel. Sogar wenn ich nur eine Zeile 
kopiere.

Meine Aufgabenstellung lautet: Tacho.
Wie ich das mache ist egal! Es ist alles toleriert.
Hauptsache ist nur das letztendlich die Daten auf dem LCD stehen.

von Ryan P. (ryanpolster)


Lesenswert?

Aber ich danke euch für eure Hilfe und "Bemühungen" :)
Für euch dürfte das ja nicht mal ansatzweise schwer sein ^^

von Karl H. (kbuchegg)


Lesenswert?

Sorry.
Aber zu meiner HTL Zeit war es noch so, dass man nach 5 Jahren 
Ausbildung eben kein Anfänger mehr war sondern es darum ging, ob man 
nach Meinung des Lehrkörpers bzw. des Vorsitzenden in der 
Abschlussprüfung genug von 'seinem Fach' versteht, dass man ihm mit Fug 
und Recht bescheinigen kann, dass er den erlernten Beruf auch 
fachgerecht ausüben kann. Das man nicht überall Spezialist ist, ist klar 
- das erwartet auch keiner. Aber hier geht es noch nicht mal um 
Spezialwissen.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Ryan Polster schrieb:
> Aber ich danke euch für eure Hilfe und "Bemühungen" :)
> Für euch dürfte das ja nicht mal ansatzweise schwer sein ^^

Das ist noch nicht mal für einen interessierten Gymnasiasten, der am 
Wochenende programmiert, besonders schwer.
Und genau da liegt die Diskrepanz, die mich stört.

von Ryan P. (ryanpolster)


Lesenswert?

Karl Heinz, das ist durch und durch verständlich. Nur ich bitte um ein 
wenig Verständnis dass ich mit dem hier nicht so vertraut bin wie du und 
ich leichter von mir denke:"Das schaff ich nicht". Aber du hast Recht! 
Fast alle meiner Probleme konnte ich selbst lösen und hatte auch so 
meine Ideen, aber ich traute mir das irgendwie nicht zu. In diesem Sinne 
bitte ich nochmals um Entschuldigung falls ich eure Zeit verschwendet 
habe.

von Peter D. (peda)


Lesenswert?

Ryan Polster schrieb:
> Der Wert kam zustande als ich die DCF Abfrage über 1ms pollen wollte

Für DCF-77 ist ein Interrupt von 10ms optimal. Damit kriegt man alle 
Zeiten in einem Byte unter, vom 0-Bit 100ms bis zur Sync-Pause 2s.
Bei 1ms müßte man auf 16Bit aufbohren ohne den geringste Vorteil.

Einen externen Interrupt braucht man nicht.

von Ryan P. (ryanpolster)


Lesenswert?

Ok dann vertrau ich einfach auf das Wissen von Peter.
Ich verstärke das Data-Signal vom DCF mit nem bc548c + Basiswiderstand 
und geh ich wieder auf PC7 des µC. Die fallende Flanke liefert PC6.
Das Signal polle ich im 10ms Takt. Wenn das nicht hinhaut meld ich mich.

Dank dir jedenfalls :)

von Ryan P. (ryanpolster)


Lesenswert?

Ich hatte einen Hardwarefehler.
Ich gehe jetzt davon aus dass Ulrichs Lib geht. Peters Variante kann man 
ja später probieren. :)
Das DCF Modul bekommt 3V von 5,18V über 2k2 mit einem 100µ Elko, einem 
100n Kerko und einer 3,9V Z-Diode. (Die Zusatzbeschaltung wurde mir 
empfohlen)
Der PON-Pin hängt an PC6 und der DATA-Pin an INT0.
Eine Low-Current-LED hängt an PD6.(hatte keine andere)


In der ISR(DCF_INT):

PORTD |= (1<<PD6);
_delay_ms(250);
PORTD &= ~(1<<PD6);

Dann leuchtet die LED nur wenn ich meine Hand auf die Krokoklemmen der 
Versorgungsspannung halte?!

Wenn ich hingegen das in bzw. vor die ISR schreibe:

bool toggle_led = false;
ISR(DCF_INT){
toggle_led = toggle_led ^ 1;
if(toggle_led) PORTD |= (1<<PD6);
else PORTD &= ~(1<<PD6);}

Dann hat die LED anfangs ziemlich energisch geblinkt. Jetzt ist es aber 
auch soweit das sie nur mehr leuchtet wenn ich meine Hand auf der 
Versorgung habe.

Meine Frage lautet nun: Wieso?

von Uwe S. (de0508)


Lesenswert?

Lbr Ryan,

Bitte stelle Bilder und ein Schaltplan ein.

von Ryan P. (ryanpolster)


Angehängte Dateien:

Lesenswert?

Ich habe noch keinen endgültigen Schaltplan, also hab ich ein Foto 
gemacht und alles bez. DCF beschriftet.

von John (Gast)


Lesenswert?

Warum legst Du DB0...DB3 von deinem LCD auf Masse?

von Ryan P. (ryanpolster)


Lesenswert?

Der LCD funktionierte auch nicht auf Anhieb. Das war eine Initiative, 
anfangs hatte ich die garnicht verbunden. Wichtig ist, der LCD geht 
einwandfrei und somit lasse ich die so.

von spess53 (Gast)


Lesenswert?

Hi

>Der LCD funktionierte auch nicht auf Anhieb. Das war eine Initiative,
>anfangs hatte ich die garnicht verbunden. Wichtig ist, der LCD geht
>einwandfrei und somit lasse ich die so.

Daran lag es mit Sicherheit nicht. Die LCD-Controller haben interne 
Pull-Up-Widerstände. Damit ist Masse kontraproduktiv.

MfG Spess

von Ryan P. (ryanpolster)


Lesenswert?

spess53 schrieb:
> Damit ist Masse kontraproduktiv.

Sind jetzt draußen.

von John (Gast)


Lesenswert?

Die Versorgungsspannung für den DCF77 Empfänger hast Du ja gut gefiltert 
mit einem Elko und einem Folienkondensator.

Aber wo ist der
 - Abblockkondensator für den µC?
 - Pullup für /Reset
 - Vorwiderstand der LED?

von Ryan P. (ryanpolster)


Lesenswert?

1) Was für einer sollte das denn sein? Wie viel F?

2) Pullup für Reset?

3) Hab int. Pull-up an

von spess53 (Gast)


Lesenswert?

Hi

>1) Was für einer sollte das denn sein? Wie viel F?

100nF. So nah wie möglich an jedes (A)VCC/GND-Paar.

>2) Pullup für Reset?

10k nach VCC

>3) Hab int. Pull-up an

Ist kein Vorwiderstand für eine LED

MfG spess

von Ryan P. (ryanpolster)


Lesenswert?

1) Und was für ein Kondensator? Elko? Kerko?

2) Vom Reset Pin? Wozu?

3) Alles klar, die LED braucht 2mA. Also nehm ich nen 1k3.. dann fließen 
2.5mA ca durch.

von spess53 (Gast)


Lesenswert?

Hi

>1) Und was für ein Kondensator? Elko? Kerko?

Kerko.

MfG Spess

von Ryan P. (ryanpolster)


Lesenswert?

zu 2) ich mein ich mach doch einen Reset beim Programmieren am Board 
oder nicht?

von Ryan P. (ryanpolster)


Lesenswert?

Oh, der ist dafür dar dass kein unerwünschter Reset kommt. Danke.

von Ryan P. (ryanpolster)


Angehängte Dateien:

Lesenswert?

Hab jetzt einen 100nF Abblockkondensator zw. Vcc & GND des µC.
10k Pullup bei Reset gegen VCC.
Vorwiderstand der LED ist jetzt auch drin.

Und ich habe einen Taster eingelötet. Wenn ich ihn drücke soll eine 
andere Anzeige auf dem LCD angezeigt werden. Er tastet eine Variable und 
die frag ich ab.
1
bool ButtonPressed = false;
2
if(PINC & (1<<PC0)) ButtonPressed = ButtonPressed ^ 1;
3
4
if(ButtonPressed) schreib irgendwas auf das LCD
5
else schreib etwas anderes auf das LCD

Nur wechselt die Anzeige als würde ich dauernd auf den Taster drücken. 
Kann mir das mal jemand erklären?


Zur Anzeige des DCF-Signals:

Ich habe eine Variable gefunden flags.dcf_rx die ich einfach auf dem LCD 
anzeigen lasse. Die LED lasse ich zusätzlich drinnen.
Das komische ist jetzt das das Modul erst "arbeitet" wenn ich mit meiner 
Hand die Versorgung berühre. Und dann kann ich praktisch dcf_rx mit 
Berührungen "schalten". Wieso ist das so?

Im Anhang noch meine Schaltung.

von Ryan P. (ryanpolster)


Lesenswert?

Wenn ich auf den Taster drücke dann bleibt die Anzeige kurz stehen. 
Läuft aber kurz darauf wieder im Sekundentakt Anzeige A B A B A B.

Ich bin ratlos :S

von Ryan P. (ryanpolster)


Lesenswert?

Hat nicht irgendwer schon mal so ein ähnliches Problem oder vielleicht 
die Antwort parat? :)

von Uwe (Gast)


Lesenswert?

Ryan,

das liegt sicherlich daran, dass eine Antwort Ja ist und keiner in 
deinem Kopf sitzt!

Was denkst du eigentlich von uns?
Woher sollen wir alle die selben Info haben, wenn niemand sieht was du 
da machst?

Also IMMER alles Veröffentlichen und nur dann kann ein netter Mensch 
sich deiner annehmen.

von Ryan P. (ryanpolster)


Angehängte Dateien:

Lesenswert?

Aber ich hab doch alles an Infos dazu geschrieben. Falls ich was 
ausgelassen habe tut es mir leid.
Ich binde mein Projekt im Anhang ein.

von Karl H. (kbuchegg)


Lesenswert?

Ein Eingang, der mit nichts verbunden ist (und genau die Situation hast 
du, wenn du einfach nur einen Taster gegen Vcc anlötest und der nicht 
gedrückt ist), ist NICHT automatisch 0!

Ein offener eingang ist hochohmig genug, dass er sich jedes 
elektromagnetische Feld aus der Umgebung einfängt. Und davon haben wir 
in unserer täglichen Umgebung mehr als genug. Radio, TV, Handy, 
Staubsauger, die 230V Leitungen in der Wand, dein PC, Laptop, sonstige 
Schaltnetzteile, du selbst wirkst als Antenne, ...


D.h. Eingänge an denen ein Taster hängt benötigen einen Pullup oder 
Pulldown Widerstand, der für einen gesicherten Pegel sorgt, wenn der 
Taster nicht gedrückt ist.
Auf einem AVR schliesst man Taster normalerweise so an, dass sie nach 
Masse durchschalten und nicht nach Vcc. Denn dann kann man die im AVR 
eingebauten Pullup Widerstände benutzen, die man nur freischalten muss. 
Dann hat man Taster mit an Board, die je nachdem ob sie gedrückt sind 
oder nicht, definiert entweder eine 0 oder eine 1 am Portpin ergeben. 1 
== Taster nicht gedrückt, 0 == Taster gedrückt. Das man damit die 
intuitive Logik umdreht, wonach ein gedrückter Taster eine 1 ergibt, ist 
völlig egal, denn im Programm ist das einfach nur eine Negierung an 
geeigneter Stelle. Das ist nichts wovor man sich fürchten muss und 
letzten Endes ist es nur eine Konvention ob eine gedrückte Taste eine 1 
oder eine 0 ergibt. Nur dass eben die 0 den Vorteil hat, dass man den 
kompletten Tastenanschluss mit AVR Bordmitteln einwandfrei ausführen 
kann und abgesehen vom Taster keinerlei zusätzliche externe Beschaltung 
braucht.

AVR-Tutorial: IO-Grundlagen
AVR-GCC-Tutorial

: Bearbeitet durch User
von Ryan P. (ryanpolster)


Lesenswert?

Ich habe jetzt das DDR auf Eingang.
Folgendes im Code geschrieben:
1
PORTD |= (1<<PD5); // Pull-Up Widerstände an
2
bool b = (PIND & (1<<PD5));
3
if(b) ButtonPressed = ButtonPressed ^ 1;
4
5
if(ButtonPressed) Anzeige A
6
else Anzeige B

da müsste doch b solange '0' sein bis ich den Taster betätige. Diese '1' 
toggelt ButtonPressed und die Anzeige sollte wechseln pro Knopfdruck.

Aber die Anzeige wechselt manchmal auch wenn ich nur mit dem Finger 
näher komme. Hab ich immer noch was vergessen? :/

von Karl H. (kbuchegg)


Lesenswert?

Ryan Polster schrieb:
> Ich habe jetzt das DDR auf Eingang.
> Folgendes im Code geschrieben:
>
1
> PORTD |= (1<<PD5); // Pull-Up Widerstände an
2
> bool b = (PIND & (1<<PD5));
3
> if(b) ButtonPressed = ButtonPressed ^ 1;
4
> 
5
> if(ButtonPressed) Anzeige A
6
> else Anzeige B
7
>
>
> da müsste doch b solange '0' sein

Nein.

Sag mal liest du auch, was ich dir schreibe?

> Auf einem AVR schliesst man Taster normalerweise so an, dass sie
> nach Masse durchschalten und nicht nach Vcc. Denn dann kann man
> die im AVR eingebauten Pullup Widerstände benutzen, die man nur
> freischalten muss. Dann hat man Taster mit an Board, die je nachdem
> ob sie gedrückt sind oder nicht, definiert entweder eine 0 oder
> eine 1 am Portpin ergeben.
> 1 == Taster nicht gedrückt, 0 == Taster gedrückt.

bzw. die Tutorien. Und zwar ganz speziell die Tutorien!

: Bearbeitet durch User
von Ryan P. (ryanpolster)


Lesenswert?

Ich glaub ich hab vergessen zu erwähnen das ich den Taster auf GND 
gelötet hab ^^

von Ryan P. (ryanpolster)


Lesenswert?

Tut mir leid wenn ich etwas nicht versteh. Aber mein Problem ist das ich 
nicht weiß was ich nicht versteh und ich glaube du weißt das ganz genau.

Also bitte ich dich mir meine Fehler aufzuweisen und daraus lern ich es 
dann endlich.

Übrigens danke dass du deine wertvolle Zeit opferst um mir Hilfe zu 
leisten :)

von Ryan P. (ryanpolster)


Lesenswert?

Der Taster ist als Schliesser verbaut und gegen GND geschalten.

Also wenn ich ihn drücke wird '0' zum µC durchgeschalten.
Ansonsten ist der Pin '1'.

Dann sind doch im Programm folgende zwei Möglichkeiten geboten:
1
bool b = (PIND & (1<<PD5));
2
if(!b) ButtonPressed = ButtonPressed ^ 1;
Da ist b immer '1' und wenn ich drücke '0'.
Also frage ich "b negiert" ab.

oder
1
bool b = !(PIND & (1<<PD5));
2
if(b) ButtonPressed = ButtonPressed ^ 1;
Da speichere ich die Variable schon negiert und frage normal ab.

Aber keines von beiden funktioniert und ich versteh beim besten Willen 
nicht wieso.

von Uwe S. (de0508)


Lesenswert?

Lbr Ryan,

Karl-Heinz ist ein toller Tutor und Du solltest Versuchen die Links vor 
weiteren Post zu lesen und zu verstehen.

Ich will jetzt auch nicht die Lösung direkt hinschreiben, da dir noch 
einiges an Basiswissen fehlt.

Hee da waren wir alle mal - Kopfhoch !
Und lies einfach die gesamte nächste Woche die TUTs durch und lese Dir 
evtl. Themen und Fragen dazu hier im Forum nach.

Das wird schon. Viel Erfolg.

von Ryan P. (ryanpolster)


Lesenswert?

Die Sache ist die:
Für die Fertigstellung des Projektes ist noch viel Zeit.
Aber ich muss morgen zu Mittag meinem Lehrer den derzeitigen Stand 
schicken. Ich möchte nur noch dass das geht bis Abgabe und den DCF werde 
ich mich noch widmen.

Mein Problem: Alle meine Versuche gehen ins nichts, sprich die Anzeige 
wechselt immer noch.
Ich liste sie mal auf:
1
PORTD |= (1<<PD5); // Pull-Up Widerstände an
2
//1
3
if(!(PIND & (1<<PD5))) ButtonPressed ^= 1;
4
5
//2
6
if((~PIND & (1<<PD5))) ButtonPressed ^= 1;
7
8
//3
9
if((PIND & ~(1<<PD5))) ButtonPressed ^= 1;

zu 1)
1
PIND = 0b00100000
2
1<<5 = 0b00100000
Logisch UND: eine '1' wenn ich den Taster nicht drücke, eine '0' wenn 
ich ihn drücke, also die Abfrage lautet: if(!x)

zu 2)
1
~PIND = 0b11011111
2
1<<5 = 0b00100000
Logisch UND: eine '0' wenn ich den Taster nicht drücke, eine '1' wenn 
ich ihn drücke, also die Abfrage lautet: if(x)

zu 3)
1
PIND = 0b00100000
2
~(1<<5) = 0b11011111
Logisch UND: eine '0' wenn ich den Taster nicht drücke, eine '1' wenn 
ich ihn drücke, also die Abfrage lautet: if(x)

Falls ich einen Fehler in meinen Überlegungen habe dann weist mich bitte 
darauf hin, sonst hab ich keine Chance den Fehler zu finden.

von Ryan P. (ryanpolster)


Lesenswert?

Taster auf GND + int. Pull-Up-R
1
bool ButtonPressed = false;
2
3
DDRD = 0x00; //Taster(PD5) als Eingang
4
PORTD |= (1<<PD5) //int. Pull-Up-R
5
6
if(!(PIND & (1<<PD5))) ButtonPressed ^= 1;
7
// PIND = 0b00100000 wegen Pull-Up
8
// Wenn ich den Taster drücke ist PIND = 0b00000000
9
// somit ist der if-Ausdruck '1' wenn ich nicht drücke
10
// weil 1 & 1 = 1
11
// und '0' wenn ich drücke
12
// weil 0 & 1 = 0
13
// in der if dann noch ne Negation damit dieses "verkehrte" Verhalten
14
// wieder umgedreht wird

Also, Taster nicht gedrückt: if(!1) = if(0) = kein Toggeln
      Taster       gedrückt: if(!0) = if(1) =      Toggeln

Aber das geht auch nicht. Leute, ich weiß echt nicht mehr weiter. Diese 
Überlegung hab ich jetzt schon x-mal gemacht und komme immer wieder zu 
diesem Resultat.
Hab jetzt auch den Inhalt der Links "gescant" und nicht "geskimt".

Ist es ein syntaktischer Fehler?
Habe ich irgendwas nicht verstanden? Wenn ja, was? ^^
Bitte helft mir.

von Uwe S. (de0508)


Lesenswert?

Tipp - über eine Frage:

wie oft wird
1
if(!(PIND & (1<<PD5))) ButtonPressed ^= 1;
 in der Sekunde ausgeführt ?

von Ryan P. (ryanpolster)


Lesenswert?

Also bekommt der zu viele Tastendrücke? 8000000/s.
Hm, das macht Sinn.
Das müsste doch mit nem kurzen delay wieder weg gehen.
Das wollte ich ohnehin im Anschluss machen, weil ich noch ein Problem 
wegen dem Entprellen bekommen werde.

von Uwe S. (de0508)


Lesenswert?

Hallo,

nein Delays sind immer schlecht, zur Tastenentprellung siehe den Code 
von PeDa.

Hier ist etwas Hilfe für deine Fragestellung - aber keine 
Tastenentprellung - sondern nur eine Flankenerkennung.
1
#define TEST_PIN() as ( (PIND ^ pd5_signal) & (1<<PD5) )
2
3
uint8_t pd5_signal = 0xff;
4
5
if ( TEST_PIN() ) {
6
  pd5_signal ^= 0xff;
7
8
  if ( pd5_signal & (1<<PD5) ) {
9
  // PD5 steigende Flanke, 0-->1
10
  } else {
11
  // PD5 fallende Flanke, 1-->0
12
  }
13
}

Aufgabe: bitte verstehe und erkläre diesen Code.

: Bearbeitet durch User
von Ryan P. (ryanpolster)


Lesenswert?

Also mit nem delay gings, wenn ich den Taster etwas länger halte.
Aber das Ganze geht wieder in das altbekannte Wechseln der Anzeige über 
nachdem ich das an Code dazugeschrieben habe:
1
if(flags.dcf_rx) PORTD |= (1<<PD6);
2
else PORTD &= (1<<PD6);

An PD6 hängt die LED. Die will ich einfach nur an sehen wenn dcf_rx = 1 
ist.
Wieso stört das?
Ich habe das DDRD auf:
1
DDRD = 0x00 | (1<<PD6); //Led=O, Rest=I

in der if: Wenn dcf_rx=1 ist dann ist der PP-Ausgang auf 1 --> LED 
leuchtet
           Wenn dcf_rx=0 ist dann ist der PP-Ausgang auf 0 --> kein 
Leuchten

von Ryan P. (ryanpolster)


Lesenswert?

@Uwe S.

Ich hab lange gebraucht aber jetzt weiß ichs ohne zu sagen 
"Flankenerkennung".

Das erklären? Ok, aber bitte schlag mich nicht ^^

Das Stück Code zerlegt den Impuls an PD5 seperat in steigende und 
fallende Flanke. Ablauf:

pd5_signal = 1111 1111
PIND = 0000 0000

###Start###

pd5_signal = 0000 0000
PIND = 0000 0000
nichts passiert

Sobald ich jetzt PD5 betätige:

pd5_signal = 0000 0000
PIND = 0010 0000

wird die if()-Funktion ausgeführt und in der "kleineren" if() findet die 
tatsächliche Erkennung statt.
Als ich den Knopf gedrückt habe war ich im if-Rumpf, kurz darauf (je 
nachdem wie lange der Impuls ist) dann im else-Rumpf der kleineren 
if()-Funktion.

von Ryan P. (ryanpolster)


Lesenswert?

Ein einfaches "Stimmt" oder "Stimmt nicht" reicht schon ^^

von Uwe S. (Gast)


Lesenswert?

Lbr Ryan,

schaue bitte noch mal auf mein Programmstück und spiele dann nochmal 
Computer:
der Startwert von pd5_signal ist 0xff und
ein aktiver Pegel ist =0, also =1 ist inaktiv !
Du bist auf einem guten Weg.

von Ryan P. (ryanpolster)


Lesenswert?

also ist jeder Port von Anfang an 0b1111 1111 und wenn ich einen Pin 
"einschalte" dann ist er zB.: 0b1110 1111?

von Ryan P. (ryanpolster)


Lesenswert?

und bez. Startwert:

Ryan Polster schrieb:
> pd5_signal = 1111 1111
> PIND = 0000 0000
>
> ###Start###
>
> pd5_signal = 0000 0000
> PIND = 0000 0000

is doch 0xFF :)

von Uwe S. (Gast)


Lesenswert?

Hi,

es ist WE und ich bin am schalfen gehen:

pd5_signal ist ein Marker für das Eingangssignal.
Das Bit 5 ist mit 1 besetzt, da dies der inaktive zustand ist.

Scheibe Dir, z.B auf Karaopapier, Spaltenweise alle Zustände des PortsB 
und der Variable hin.
Zustand N=0 wären dann die Startwerte.
Zustand N=1 in der nächsten Zeile eine Änderung am PortB und der neue 
Variablewert auf.
und so machst Du immer weiter.

ich bin gespannt.

von Ryan P. (ryanpolster)


Lesenswert?

........A            B
N |    PIND     pd5_signal    XOR    AND  (A&!B)
-----------------------------------------------
0 |  0010 0000  1111 1111  0000 0000  0     -
1 |  0000 0000  1111 1111  0010 0000  1    1>0
2 |  0000 0000  0000 0000  1101 1111  0     -
3 |  0010 0000  0000 0000  1111 1111  1    0>1
4 |  0010 0000  1111 1111  0000 0000  0     -
5 |  0000 0000  1111 1111  0010 0000  1    1>0
6 |  0000 0000  0000 0000  1101 1111  0     -
7 |  0010 0000  0000 0000  1111 1111  1    0>1
. |      .          .          .      .     .
. |      .          .          .      .     .

Wenn die erste UND-Verknüpfung '1' ergibt, wird pd5_signal komplett 
binär invertiert.

Zu erwähnen wäre noch dass man auf pd5_signal tatsächlich das Signal von 
PD5 erkennt.

Der Taster wird in den Schritten 1 & 5 gedrückt und in 3 & 7 wird er 
losgelassen.

Und wie schon gesagt, das Stück Code teilt einen Impuls in steigende und 
fallende Flanke.

Kann das sein das du absichtlich dieses Beispiel genommen hast, damit 
ich meinen offensichtlichen Grundlagenfehler verstehe?

: Bearbeitet durch User
von Uwe S. (de0508)


Lesenswert?

Hallo Ryan,

zu Deiner Frage, um deine Lernkurve zu beschleunigen und dass Du deinen 
Code besser - auch ohne µC - testen kannst.

Deshalb programmiert man auch kleiner Module - Funktionseinheiten -, die 
man eigenständig testen kann.

Nun wäre der Einbau in dein Programm angedacht und gleichzeitige 
Auslagerung von Funktionseinheiten in Unterprogramme und 
Unterfunktionen.

Gemeint ist das, wie in den LCD Routinen, nur hier im kleineren.

: Bearbeitet durch User
von Uwe S. (de0508)


Lesenswert?

Hallo,

und Du solltest Dich nun Fragen, wie man diese Stück Programm [1]
1
if(!(PIND & (1<<PD5))) ButtonPressed ^= 1;
mit deinem neuen Wissen verbessern könnte.

Link
[1] Beitrag "Re: DCF auf INT0"

: Bearbeitet durch User
von Ryan P. (ryanpolster)


Lesenswert?

Nett, danke dass du mir hilfst mein Wissen zu erweitern :)

Ich werde mich mit der PeDa Entprellung schon noch beschäftigen, aber 
momentan gibt es wichtigeres, in dem Fall das DCF-Modul.

Da hätt ich folgende Frage: Wenn ich eine 2,1V-LED + 1k an '+' des DCF 
anschliesse, dann müsste das Modul doch 3V bekommen und die LED müsste 
aufleuchten sobald ich Daten empfange, sprich ich müsste sie im 
Sekundentakt blinken sehen, mal kurz und mal kürzer. Tut sie aber nicht. 
Also meine Frage ist jetzt: zieht das Modul nur Strom wenn es empfängt 
oder immer?

von John (Gast)


Angehängte Dateien:

Lesenswert?

Ryan Polster schrieb:
> Wenn ich eine 2,1V-LED + 1k an '+' des DCF
> anschliesse, dann müsste das Modul doch 3V bekommen

Ich glaube nicht, dass eine 2,1V-LED + 1kΩ ausreichen um dein DCF-Modul 
zu versorgen. Du solltest es schon an eine Spannungsversorgung 
anschließen.

Was für ein DCF-Modul hast Du?
Zeichne mal einen Schaltplan.

Noch was zu deinen Lötstellen: die sind furchtbar.
Du solltest schon auf saubere Lötstellen achten. So baust Du Dir nur 
unnötig Fehler ein, die Du suchen musst.
 - Was für ein Lötkolben verwendest Du?
 - Was für eine Lötspitze?
 - Mit welcher Temperatur lötest Du?
 - Welches Lötzinn verwendest Du?
Etwas ist ziemlich daneben.
Schau Dir mal das Bild im Anhang an.

Gruß
John

von Ryan P. (ryanpolster)


Lesenswert?

Und eine Frage hab ich dann noch:

bei
1
#define TEST_PIN() as ( (PIND ^ pd5_signal) & (1<<PD5) )
ist TEST_PIN() ja variabel, je nachdem ob gedrückt ist oder nicht.
Das würde doch der Präprozessor konstant als '0' definieren, oder irre 
ich mich da?

von Ryan P. (ryanpolster)


Lesenswert?

Ok, selbsstverständlich kommt auch ne Versorgungsspannung drauf. Und 
zwar 5,18V.

Ich muss sagen ich habe auch nicht besonders viel Wert auf das Aussehen 
gelegt.

Ich habe das DCF1. Im Internet eher bekannt als "Das Pollin Modul" (Was 
is Pollin eigentlich?)

Einen von einem Geschäft das direkt vis-á-vis meines Hauses liegt. Er 
kostete 11€.

Die Spitze hab ich vor kurzem erneuert.

Die Temperatur ist nirgends direkt ersichtlich, evtl im Datenblatt des 
Kolbens welches man sicher leicht im Internet findet ^^
Aber definitiv über 220° :D

Lötzinn: so eines mit 40% Flußmittel.

Tut ja nichts zur Sache, solange ich mit dem Equip el. Verbindungen 
hinbekomme passts ja. Durchmessen tu ich es auch gleich nach dem Löten 
um die Fehlersuche zu verkürzen

Auf Anfrage kann ich dir natürlich auch genauere Infos über mein Lötzeug 
geben :)

: Bearbeitet durch User
von John (Gast)


Lesenswert?

Ryan Polster schrieb:
> Ich habe das DCF1. Im Internet eher bekannt als "Das Pollin Modul"
> (Was is Pollin eigentlich?)

Pollin ist ein Händler:
http://www.pollin.de/shop/dt/NTQ5OTgxOTk-/Bausaetze_Module/Module/DCF_Empfangsmodul_DCF1.html

Hier im Forum gibt es viele Beiträge über das Pollin-DCF-Modul. Mit der 
Suchfunktion wirst Du einiges finden. Schau da mal rein.

von Ryan P. (ryanpolster)


Lesenswert?

Ich hab da schon nen Blick darauf geworfen.
Was kannst du mir über dieses Modul sagen? :)

von John (Gast)


Lesenswert?

Ryan Polster schrieb:
> Ich hab da schon nen Blick darauf geworfen.
> Was kannst du mir über dieses Modul sagen? :)

"Ich lebe nach der Devise: Lieber fünf Mal nachgefragt
als einmal nachgedacht."
[Die Känguru-Chroniken: Ansichten eines vorlauten Beuteltiers
 von Marc-Uwe Kling]

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.