Forum: Mikrocontroller und Digitale Elektronik C -Programm, Lauflichtfehler


von Manuel B. (jackson02)


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):
1
#include <avr/io.h>          // (1)
2
#ifndef F_CPU
3
#warning "F_CPU war noch nicht definiert, wird nun mit 12MHz definiert"
4
#endif
5
#define F_CPU 12000000UL
6
#include <util/delay.h>
7
#include <stdint.h>
8
const int8_t Zahl [7] = {
9
    0b00000000,    
10
    0b00000001,
11
    0b00000010,    
12
    0b00000100,    
13
    0b00001000,    
14
    0b00010000,
15
    0b00100000,    
16
    };
17
18
void Hochzaehlen (uint8_t i) {
19
        
20
    PORTB |= i [Zahl];
21
    _delay_ms (200);
22
}
23
24
void Runterzaehlen (uint8_t i) {
25
        
26
    PORTB &= ~i [Zahl];
27
    _delay_ms (200);
28
}
29
    
30
int main (void) {         
31
   DDRB  = 0xff; 
32
   DDRD  |= (1<<DDD0) | (1<<DDD1);
33
   uint8_t i;
34
   i = 0;
35
 while( 1 ) {                             // Endlosschleife
36
 
37
    if (PIND & (1<<PD0)){
38
    i ++;
39
    Hochzaehlen (i);
40
    if (i = 7)    i=1;
41
    }
42
    
43
    if (PIND & (1<<PD1)){
44
    i --;
45
    Runterzaehlen (i);
46
    if (i = 0) i = 7;
47
    }
48
    
49
    }    
50
   return 0;              
51
}



Nur noch so nebenbei. Wenn ich diesen "Abschnitt"
1
 if (PIND & (1<<PD1)){
2
    i --;
3
    Runterzaehlen (i);
4
    if (i = 0) i = 7;
5
    }
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

von Steffen (Gast)


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

von Horst H. (horha)


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-Tutorial#Zugriff_auf_IO-Ports 
oder
http://derjulian.net/mikrocontroller#output durch.

von Frickler (Gast)


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".

von Manuel B. (jackson02)


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

von eProfi (Gast)


Lesenswert?

Au weh:

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

von NurEinGast (Gast)


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.

von Manuel B. (jackson02)


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:
1
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
1
if (PIND & ((1<<PD0)|(1<<PD1)))
 waren bisher leider erfolglos.

Grüßle

von spess53 (Gast)


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

von MWS (Gast)


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.

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.