Bedingungen werden nicht korrekt ausgeführt

Gast #1965332
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
Gast #1965541
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 :)
#1965641
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
Gast #1965647
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?
Gast #1965660
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.
Gast #1965672
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren