mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik C -Programm, Lauflichtfehler


Autor: Manuel B. (jackson02)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

bin jetzt nach längerer Überlegung doch von Basic auf C umgestiegen. 
Nun, meiner Meinung nach ist es recht ähnlich bis auf die Formatierungen 
und die vielen Klammern ;). Nun.. mal zum eigentlichen Problem. Da ich 
ja nicht gleich großartig etwas machen kann, wollte ich mal klein 
anfangen und ein Lauflicht programmieren. Jedoch (wie man gleich am 
Quellcode sieht) eines, das nicht nur ständig am "Hochzählen" ist, 
sondern auch mal von einer Variable einen Wert abziehen soll.
Leider funktioniert das Programm dann nur noch bis zur zweiten LED.
Jetzt dachte ich, dass es vielleicht mit dem Hard-, Softwarestack 
zusammenhängen könnte. Jedoch weiß ich nicht, wie ich diesen 
initialisiere und festlege.
Bin jedoch gerne bereit mich bei einem Fehler im Programm berichtigen zu 
lassen ;)

Hier mal der Code (hab ihn jetzt mal nicht als Datei angehängt, da er 
mir nicht allzulang erscheint):
#include <avr/io.h>          // (1)
#ifndef F_CPU
#warning "F_CPU war noch nicht definiert, wird nun mit 12MHz definiert"
#endif
#define F_CPU 12000000UL
#include <util/delay.h>
#include <stdint.h>
const int8_t Zahl [7] = {
    0b00000000,    
    0b00000001,
    0b00000010,    
    0b00000100,    
    0b00001000,    
    0b00010000,
    0b00100000,    
    };

void Hochzaehlen (uint8_t i) {
        
    PORTB |= i [Zahl];
    _delay_ms (200);
}

void Runterzaehlen (uint8_t i) {
        
    PORTB &= ~i [Zahl];
    _delay_ms (200);
}
    
int main (void) {         
   DDRB  = 0xff; 
   DDRD  |= (1<<DDD0) | (1<<DDD1);
   uint8_t i;
   i = 0;
 while( 1 ) {                             // Endlosschleife
 
    if (PIND & (1<<PD0)){
    i ++;
    Hochzaehlen (i);
    if (i = 7)    i=1;
    }
    
    if (PIND & (1<<PD1)){
    i --;
    Runterzaehlen (i);
    if (i = 0) i = 7;
    }
    
    }    
   return 0;              
}



Nur noch so nebenbei. Wenn ich diesen "Abschnitt"
 if (PIND & (1<<PD1)){
    i --;
    Runterzaehlen (i);
    if (i = 0) i = 7;
    }
herausnehme, dann baut sich das Lauflicht wie gewünscht auf. --> Deshalb 
meine Vermutung mit dem HW-Stack.


NACHTRAG:
Mittlerweile funktioniert es nicht einmal mehr, wenn ich besagten 
Abschnitt entferne und sogar die void-Schleife mit "Runterzaehlen".

Mit besten Grüßen

Autor: Steffen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kriegst du das so überhaupt kompiliert?

PORTB |= i [Zahl];
und
PORTB &= ~i [Zahl];
ist doch quatsch.

Du willst schließlich den Index "i" von dem Array "Zahl" haben, also 
muss es heißen:

PORTB |= Zahl [i];
PORTB &= ~Zahl [i];


Wozu du das Element "0" im Array hast, ist mir nicht klar, wenn du hier
if (i = 7)    i=1;
i mindestens auf 1 setzt.

Viele Grüße
Steffen

Autor: Horst Hahn (horha)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
.. Beim runterzählen geht es bis auf 0..
Aber zusätzlich:
DDRD  |= (1<<DDD0) | (1<<DDD1);

Setzt doch nur Port Pin 0 uind 1 als Ausgang, Du willst aber 0 bis 6 
einschliesslich.
http://www.mikrocontroller.net/articles/AVR-GCC-Tu... 
oder
http://derjulian.net/mikrocontroller#output durch.

Autor: Frickler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Steffen schrieb:
> PORTB |= i [Zahl];
> und
> PORTB &= ~i [Zahl];
> ist doch quatsch.

Die wenigsten wissen, dass das tatsächlich korrektes und zulässiges, 
standardkonformes C ist (und absolut identisch zur "korrekten" 
Schreibweise).

Abgesehen vom formalen Aspekt hast Du natürlich Recht. Sowas macht man 
nicht, außer man schreibt Code für einen "obfuscated C Contest".

Autor: Manuel B. (jackson02)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahh..

das mit dem
"PORTB |= i [Zahl];"
funktioniert bei mir schon.
wies bei dem "PORTB &= ~ i [Zahl]" aussieht kann ich nicht sagen.
Ging ja schließlich noch nicht. ;D

Nur unten, wie du bereits erwähnt hast, mit der "0" hab ich nicht 
aufgepasst.
Das muss natürlich ne 1 sein, sonst wärs Quatsch.

Jetzt habe ich zumindest mal einen Fehler gefunden.
Ich habe in den if-Schleifen jeweils ein = vergessen.

ursprünglich: if (i = 7) i = 1;
jetzt: if (i == 7) i = 1;

nun sollte das schon mal stimmen.

Werd das Programm nach dem Mittagessen nochmal testen.

Grüßle

Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Au weh:

    if (i = 0) i = 7;
muss
    if (i == 0) i = 7;
heißen, auch an anderen Stellen!

Autor: NurEinGast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Manuel B. schrieb:
> #ifndef F_CPU
> #warning "F_CPU war noch nicht definiert, wird nun mit 12MHz definiert"
> #endif
> #define F_CPU 12000000UL

Hier wird IMMER 12MHZ definiert.
Das gehoert in den #ifdef #endif  Block verschoben


>     PORTB |= i [Zahl];

Das wurde schon weiter oben verbessert.


>    DDRD  |= (1<<DDD0) | (1<<DDD1);

Wo kommt den DDD0 DDD1 her ?
Mag stimmen - hab ich aber noch nie gesehen.

>     if (i = 7)    i=1;

Das ist keine Abfrage, sondern eine Zuweisung
Sollte   if (1 == 7 ) sein

>     if (i = 0) i = 7;

s.o.

Autor: Manuel B. (jackson02)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beitrag von  NurEinGast
"Wo kommt den DDD0 DDD1 her ?
Mag stimmen - hab ich aber noch nie gesehen."
Nach meinen Erfahrungen mit Online-Kursen und ein paar Büchern war mir 
das die sinnvollste Zuweisung. Oder wenigstens die Ersichtlichste.

So.. nun, da das mit dem "doppelten Istgleich" geändert wurde, 
funktioniert das Programm genauso wie ich es wollte.
Nur eins versteh ich trotzdem nicht. Bei dieser Zeile hier:
PORTB |= i [Zahl];
hab ich nichts geändert. Dennoch funktionierts, was sich jedoch hier mit 
einigen Meinungen widersprechen sollte. Woran könnte das liegen?

Off Topic: Kann mir jemand sagen, wie ich beispielsweise zwei Pins mit 
einer "UND" oder "ODER" Verknüpfung in einer IF Schleife realisiere.
Meine Versuche mit
if (PIND & ((1<<PD0)|(1<<PD1)))
 waren bisher leider erfolglos.

Grüßle

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Meine Versuche mit
>if (PIND & ((1<<PD0)|(1<<PD1)))
> waren bisher leider erfolglos.

Ein 'if' verlangt ein 'true' oder 'false'.

'PIND & ((1<<PD0)|(1<<PD1))' liefert aber 0,1,2 oder 3. Was soll das 
'if' damit anfangen?

MfG Spess

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ein 'if' verlangt ein 'true' oder 'false'.
Nein, nicht in C, denn 0 = false, alles <> 0 = true.

> einer "UND" oder "ODER" Verknüpfung in einer IF Schleife realisiere.
Es gibt keine IF Schleife, nur eine IF Bedingung.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.