Forum: Compiler & IDEs Probleme mit Ausgängen


von Daniela (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich hab folgendes Problem:

ich habe ein Programm welches über LEDs die Uhrzeit ausgibt (siehe 
vorherige Foreneinträge).

Am Anfang hat alles wunderbar funktioniert, außer dass die LEDs sehr 
schwach geleuchtet haben.

In der ersten "Version" habe ich das DDRx jeweil bei jedem Ausgang 
einzeln gesetzt.
jetzt sieht es folgendermasen aus:

....
// initalisieren der Ports
void init ( void ) {
  DDRA = 0xFF;
  DDRB = 0xFF;
  DDRC = 0xFF;
  DDRD = 0xFF;
  DDRD &=~ (1 << DDD2); //Eingang
  }
....

Hat auch geholfen, also die LEDs leuchten hell (so wie ich es wollte).

ABER, die LEDs, welche am Port D hängen leuchten nicht mehr.
Ich hab schon auf verschiedene Arten Versucht das Problem zu beheben, 
z.B.
die letzten beiden Zeilen in "DDRD = 0xFB" ändern.

Ich freue mich über jeden Verbesserungsvorschlag!

von Karl H. (kbuchegg)


Lesenswert?

Daniela wrote:

> ....
> // initalisieren der Ports
> void init ( void ) {
>   DDRA = 0xFF;
>   DDRB = 0xFF;
>   DDRC = 0xFF;
>   DDRD = 0xFF;
>   DDRD &=~ (1 << DDD2); //Eingang
>   }
> ....
>

Schön, aber dein main fängt so an

int main(void)
{

init();
// Kontroll LED

  DDRD = (1 << PD5);

und damit ist deine ganze DDRD Einstellung in init() Geschichte 
geworden.

von Daniela (Gast)


Lesenswert?

versteh ich das richtig, dass es gehen müsste wenn die Zeile

  DDRD = (1 << PD5);

gelöscht wird? Die brauch ich im Prinzip auch nicht.

von Klaus F. (kfalser)


Lesenswert?

> DDRD = 0xFF;
> DDRD &=~ (1 << DDD2); //Eingang

Ich finde es überhaupt eine schlechte Idee, ein Port (und sei es auch 
nur für einen Takt) als Ausgang zu definieren und dann wieder zurück auf 
Eingang.
Wenn an dem Pin etwas hängt, dann kommt es zu einem Kurzschluss.

In der Init Routine sollen alle Pins entsprechend der Hardware von 
Anfang an richtig gesetzt werden.

von Karl H. (kbuchegg)


Lesenswert?

Daniela wrote:
> versteh ich das richtig, dass es gehen müsste wenn die Zeile
>
>   DDRD = (1 << PD5);
>
> gelöscht wird? Die brauch ich im Prinzip auch nicht.

Ich hab mir den Rest des Programmes nicht durchgesehen.
Aber wenn du hier eine Zuweisung zu DDRD machst, dann ist deine ganze 
EInstellung des DDRD Registers in init() sinnlos geworden, weil sie hier 
ja überschrieben wird.

von Daniela (Gast)


Lesenswert?

wäre dann
> DDRD &= (1 << DDD2); //Eingang
anstatt
> DDRD &=~ (1 << DDD2); //Eingang
die bessre Lösung?

Sonst habe ich nichts an den DDR-Registern geändert.

von Hmm... (Gast)


Lesenswert?

In 99.999% aller Fälle ist es nicht notwendig die Richtung eines 
Portpins im laufenden Programm zu ändern.

Das macht man genau einmal in einer Init-Routine gemäss der 
angeschlossenen Hardware und ändert dann nix mehr dran. Demnach würde 
ich Zugriff auf DDRD ausschließlich in "Init()" machen.

Du bist dir der Funktion der beiden Register "DDRD" und "PORTD" aber 
schon bewusst oder hast du den folgenden Block von irgendwo her kopiert?
1
// Kontroll LED
2
  
3
  DDRD = (1 << PD5);
4
  PORTD |= (1 << PD5);

von Daniela (Gast)


Lesenswert?

Am Anfang habe ich jede LED so "angesteuert."

Die Kontroll LED gibt es inzwischen gar nicht mehr, die hatte ich nur 
drin um zu sehen ob überhaupt was geht. Deshalb hab ich auf die beiden 
Zeilen  auch gar nicht mehr geachtet und jetzt auch komplett gelöscht.

von Hmm... (Gast)


Lesenswert?

> Am Anfang habe ich jede LED so "angesteuert."
>
> Die Kontroll LED gibt es inzwischen gar nicht mehr, die hatte ich nur
> drin um zu sehen ob überhaupt was geht. Deshalb hab ich auf die beiden
> Zeilen  auch gar nicht mehr geachtet und jetzt auch komplett gelöscht.

Gerade im Fehlerfall ist es hilfreich, den Code im Geiste noch einmal 
nach zu vollziehen und sich über die Bedeutung jeder einzelnen Zeile 
klar zu werden.


http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Zugriff_auf_IO-Ports

von Daniela (Gast)


Lesenswert?

Wäre auf jeden fall vermeidbar gewesen, aber ich bin auf dem Thema nicht 
so fit (wie man merkt), dass mir so was nur durch lesen klar wird.

von Hmm... (Gast)


Lesenswert?

> Wäre auf jeden fall vermeidbar gewesen, aber ich bin auf dem Thema nicht
> so fit (wie man merkt), dass mir so was nur durch lesen klar wird.

Deshalb der Link auf das Tutorial ;)

Wenn du dir das mal in Ruhe durch gehst und ausprobierst, kommt ganz 
sicher noch der eine oder andere 'AHA'-Effekt.

Viel Erfolg mit deiner Funkuhr ;)

Darf ich fragen, was genau an Port B hängt?

von Daniela (Gast)


Lesenswert?

ja klar darfst du da kommt das Signal vom DCF-Modul rein, du meinst doch 
den Eingangsport? Sonst sind überall LEDs oder nichts.

von Hmm... (Gast)


Lesenswert?

Dem Code nach zu urteilen hängt das DCF-Modul an PortD.2 Alle weiteren 
Pins sind Ausgänge.

Ich frage nur, weil die Ausgabe der Uhrzeit sicherlich etwas eleganter 
als über das 2 dutzend if-else Konstrukte gelöst werden kann ;) Schaut 
ein wenig nach simulierter Analog-Uhr (mit "Zeigern") aus

von Daniela (Gast)


Lesenswert?

ist es auch, war die Aufgabe.

von (prx) A. K. (prx)


Lesenswert?

Hmm... wrote:

> In 99.999% aller Fälle ist es nicht notwendig die Richtung eines
> Portpins im laufenden Programm zu ändern.

Ein paar Neuner weniger tun es auch. Beispielsweise ist das bei 
bidirektionale Protokollen wie I2C und 1-Wire, bei HD44780-LCDs mit R/W 
und für Powerdown/save-Modi erforderlich.

von Karl H. (kbuchegg)


Lesenswert?

>> etwas eleganter als über das 2 dutzend if-else Konstrukte
>> gelöst werden kann
>> Schaut ein wenig nach simulierter Analog-Uhr (mit "Zeigern") aus
> ist es auch, war die Aufgabe.

Habt ihr schon von Arrays (auf deutsch: Felder) gelernt?

von yalu (Gast)


Lesenswert?

Wenn ich das richtig verstehe, wird also von PD2 das DCF-Signal gelesen,
an PD0, PD1, PD3, PD5, PD6 und PD7 hängen die LEDs, und PD4 ist nicht
belegt.

Mit
1
  DDRD = (1 << PD5);

konfigurierst du alle PD-Pins außer PD5 als Eingang, weswegen die
angeschlossenen LEDs nicht oder nur schwach leuchten. Lass also die
Zeile weg, da die Datenrichtung in init schon für alle Ports richtig
konfiguriert wurde.

Und nimm den Raten von Klaus Falser zu Herzen und ersetze
1
  DDRD = 0xFF;
2
  DDRD &=~ (1 << DDD2); //Eingang

durch
1
  DDRD = 1<<DDD0 | 1<<DDD1 | 1<<DDD3 | 1<<DDD5 | 1<<DDD6 | 1<<DDD7;

oder
1
  DDRD = ~(1<<DDD2 | 1<<DDD4);

von Daniela (Gast)


Lesenswert?

JA es geht!!!!!

tausend mal Dank!

>Habt ihr schon von Arrays (auf deutsch: Felder) gelernt?

Gelernt schon aber können nicht.

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.