Forum: Compiler & IDEs Bedingungen werden nicht korrekt ausgeführt


von Alex (Gast)


Lesenswert?

Hallo zusammen

Ich hab hier ein kleines, wahrscheinliches einfaches Problem... aber ich 
hab sicherlich grad den Tunnelblick und seh die Lösung nicht.

Zum Problem...

Ich habe ein Programm geschrieben, das alle paar Sekunden ein 
Unterprogramm aufruft... und die Anweisungen in den Funktionen KORREKT 
befolgt.

Der korrekte Durchlauf ist aber iwie nur das erste Mal gewährt, 
anschließend nicht mehr.

In Schritt 3 sollen mittels AD Wandler zwei Werte ermittelt werden. 
Einmal von ADC1 und ADC3! Diese subtrahiere ich anschließend und möchte 
das ab einer bestimmten Differenz die eine LED leuchtet oder die andere.

Nunja das erste Mal klappts, das zweite Mal nicht. Nachm Reset 
funktioniert wieder das erste Mal :(

Hier mal der Code: (GO wird in einem Timer alle paar Sekunden 
hochgezählt!

1
volatile int GO=0;
2
3
unsigned int LDR1;
4
unsigned int LDR3;
5
6
signed int LDR13;
7
8
// Funktionsprototypen
9
10
void initLDR1(void);    // Initialisierung des LDR1
11
void initLDR3(void);    // Initialisierung des LDR3
12
13
void Leuchtstaerke(void);  // Unterprogramm zur Bestimmung der Helligkeit
14
15
// Hauptprogramm===================================================================================
16
17
int main(void)
18
19
{
20
  SET_BIT(DDRD, DDD1);
21
  SET_BIT(DDRD, DDD3);
22
23
  SET_BIT(DDRB, DDB2);
24
  
25
  ADCSRA |= 0x7;    // (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
26
27
            // ADC aktivieren + Vorteiler 128 (Prescaler Selection Bits)
28
  
29
  sei();          // Interrupts aktivieren
30
    
31
  while(1)
32
  
33
  {  
34
    SET_BIT(PORTD, PD1);    // LED ausschalten, falls an
35
    SET_BIT(PORTD, PD3);    // LED ausschalten, falls an
36
37
    SET_BIT(PORTB, PB2);    // LED ausschalten, falls an
38
    
39
40
    ADCSRA &= ~(1<<ADEN);    // A/D ausschalten
41
    
42
    if (GO==1)
43
    {                        
44
      CLR_BIT(PORTB, PB2);  // LED einschalten
45
      _delay_ms(1500);
46
    }
47
48
    if (GO==2)
49
    {            
50
      initLDR1();
51
      Leuchtstaerke();
52
      LDR1=wert;
53
      initLDR3();
54
      Leuchtstaerke();
55
      LDR3=wert;
56
57
            LDR13=LDR1-LDR3;
58
    }
59
    
60
    if (GO==3)
61
    {
62
      if (LDR13>=20)
63
      {
64
      CLR_BIT(PORTD, PD1);    // LED einschalten
65
      GO=0;
66
      }
67
      
68
      if (LDR13<=-20)
69
      {
70
      CLR_BIT(PORTD, PD3);    // LED einschalten
71
      GO=0;
72
      }
73
      
74
      _delay_ms(250);
75
    }
76
77
    if (GO==4)
78
    {
79
      CLR_BIT(PORTB, PB2);    // LED einschalten
80
      _delay_ms(100);
81
      GO=0;
82
    }
83
  }      
84
}
85
86
// Initialisierung LDR1=============================================================================
87
88
void initLDR1()
89
90
{
91
  ADMUX |= 0xC1;    // (1<<REFS1) | (1<<REFS0) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (1<<MUX0)
92
93
            // 1.1V mit Externen Kondensator (REFS) + ADC1 Eingang LDR (MUX)
94
}  
95
96
// Initialisierung LDR3=============================================================================
97
98
void initLDR3()
99
100
{
101
  ADMUX |= 0xC3;    // (1<<REFS1) | (1<<REFS0) | (0<<MUX3) | (0<<MUX2) | (1<<MUX1) | (1<<MUX0)
102
103
            // 1.1V mit Externen Kondensator (REFS) + ADC3 Eingang LDR (MUX)
104
}  
105
106
// Leuchtstärkebestimmung==========================================================================
107
108
109
void Leuchtstaerke()        // ADC= (Vin*1024)/(Vref)
110
111
{
112
  int lux;  
113
  int i;
114
115
  ADCSRA |= (1<<ADEN);      // AD aktivieren
116
  ADCSRA |= (1<<ADSC);      // Konvertierung starten
117
118
  while (ADCSRA & (1<<ADSC))    // Wenn Konvertierung gestartet ist
119
    
120
  {
121
    ;  
122
  }
123
124
  lux = ADCL;            // Erst ADCL aus Register lesen
125
  lux += (ADCH<<8);        // dann ADCH, weil sonst ADC Data Register nicht geupdated wird
126
  lux=0;
127
  
128
  for (i=0; i<4; i++)
129
  
130
  {
131
    ADCSRA |= (1<<ADSC);
132
133
    while (ADCSRA & (1<<ADSC))  // Wenn Konvertierung gestartet ist
134
  
135
    {
136
      ;  
137
    }
138
139
    lux += ADCL;
140
    lux += (ADCH<<8);      // ADCH aufsummieren
141
  }
142
    
143
  ADCSRA &= ~(1<<ADEN);      // Konvertierung beenden
144
  
145
  //lux = (lux>>2);        // durch 4 teilen
146
  lux /= 4;
147
  wert = lux;
148
  i=0;            
149
}

Ich bin echt ratlos... wäre dankbar für eure Hilfe!

Grüßle Alex

von Stefan E. (sternst)


Lesenswert?

Alex schrieb:
> Nunja das erste Mal klappts, das zweite Mal nicht. Nachm Reset
> funktioniert wieder das erste Mal :(

Kein Wunder, wenn du in ADMUX immer nur Bits setzt, aber einmal gesetzte 
Bits nie wieder zurück setzt.

von Karl H. (kbuchegg)


Lesenswert?

Benutz doch die Routinen aus dem AVR-GCC-Tutorial

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

dann machst du nicht diese dummen Fehler.
Kein Grund das Rad immer wieder neu zu erfinden.

von Alex (Gast)


Lesenswert?

Wie meinst du das mit dem Zurücksetzen? sollte ich nach der Wandlung des 
ADC1 z.b. alle Bits auf 0 sezten, damit wenn der ACD3 initialisiert 
wird, keine Fehler auftreten oder verstehe ich da iwas nicht :)

von holger (Gast)


Lesenswert?

ADMUX |= 0xC1;
  ADMUX |= 0xC3;

>oder verstehe ich da iwas nicht :)

Genau, du verstehst das Oder nicht.

von Karl H. (kbuchegg)


Lesenswert?

Alex schrieb:
> Wie meinst du das mit dem Zurücksetzen?

Zurücksetzen, so wie in 'ein Bit welches auf 1 gestellt wurde auch 
wieder mal auf 0 zurücksetzen'. Denn wenn man es nicht tut, dann bleibt 
es auf immer und ewig auf 1
Wiwe zb bei dir die Bits, die die Kanalauswahl des ADC steuern.

Wobei die Frage immer noch nicht beantwortet ist, was an den Tutorial 
Routinen so schrecklich ist. Die machen das nämlich richtig

von Alex (Gast)


Lesenswert?

Doch doch ... es gibt einmal |= (1<<x) um ein Bit zu setzen und &= 
~(1<<x) um eines zu löschen :) aber wieso klappt das dann beim ersten 
mal richtig? Es müsste eigentlich auch dort schon Fehler geben oder?

von holger (Gast)


Lesenswert?

>Doch doch ... es gibt einmal |= (1<<x) um ein Bit zu setzen und &=
>~(1<<x) um eines zu löschen :)

Und warum benutzt du das dann nicht?

> aber wieso klappt das dann beim ersten
>mal richtig? Es müsste eigentlich auch dort schon Fehler geben oder?

Weil die Bits nach einem Reset alle auf 0 sind.

von Karl H. (kbuchegg)


Lesenswert?

Vielleicht haben wirs ja auch übersehen.
Also: Wo soll das den in obigen Programm sein?

Ganz konkret am Register ADMUX. Denn dort steht ja drinn welcher Kanal 
gesampelt werden soll.

von Alex (Gast)


Lesenswert?

Also hatte das ganze auch schon mit 4 wandlern gemacht und nacheinander 
von adc0-3 gewandelt. Adc0 klappt ja, adc1 natürlich auch aber bei adc2 
müsste erst doch eigentlich adc3 wandeln da ja das erste und zweite Bit 
dann schon gesetzt sind... aber er hat mir da trotzdem adc2 gewandelt. 
Das hat mich vllt auch so konfus gemacht hehe

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.