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 ^^
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?
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?
>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.
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?
>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.
>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.
@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"
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.
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.
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.
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.
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!
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?
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.
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.
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.
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.
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.
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 ;-)
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.
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.
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.
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.
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.
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 :)
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?
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.
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
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?
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
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.
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
boolButtonPressed=false;
2
if(PINC&(1<<PC0))ButtonPressed=ButtonPressed^1;
3
4
if(ButtonPressed)schreibirgendwasaufdasLCD
5
elseschreibetwasanderesaufdasLCD
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.
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
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.
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-GrundlagenAVR-GCC-Tutorial
Ich habe jetzt das DDR auf Eingang.
Folgendes im Code geschrieben:
1
PORTD|=(1<<PD5);// Pull-Up Widerstände an
2
boolb=(PIND&(1<<PD5));
3
if(b)ButtonPressed=ButtonPressed^1;
4
5
if(ButtonPressed)AnzeigeA
6
elseAnzeigeB
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? :/
Ryan Polster schrieb:> Ich habe jetzt das DDR auf Eingang.> Folgendes im Code geschrieben:>
1
>PORTD|=(1<<PD5);// Pull-Up Widerstände an
2
>boolb=(PIND&(1<<PD5));
3
>if(b)ButtonPressed=ButtonPressed^1;
4
>
5
>if(ButtonPressed)AnzeigeA
6
>elseAnzeigeB
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!
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 :)
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
boolb=(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
boolb=!(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.
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.
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.
// 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.
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.
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) )
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
elsePORTD&=(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
@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.
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.
und bez. Startwert:
Ryan Polster schrieb:
> pd5_signal = 1111 1111> PIND = 0000 0000>> ###Start###>> pd5_signal = 0000 0000> PIND = 0000 0000
is doch 0xFF :)
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.
........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?
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.
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?
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
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 :)
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]