Forum: Mikrocontroller und Digitale Elektronik Wie setze ich Ausgänge mit einer for-Schleife?


von stephan b. (stu)


Lesenswert?

Hallo zusammen,
ich schreibe gerade ein kleines Programm für ein Projekt in der 
Technikerschule. Und zwar muss ich mit einem Atmega32 8 Analoge Eingänge 
abfragen. Das ist auch kein Problem. Ich habe in einer for-Schleife 
einen AnalogDigitalwandler aufgerufen der den Wert des jeweiligen 
Eingang in ein Array "Fach[]" schreibt. Jetzt möchte ich in einer 
weiteren for-Schleife die Ausgänge in Port D setzen wenn der Wert 
innerhalb einer Toleranz liegt. Also wenn Fach[1] kleiner 800 und größer 
500 dann setze PortD 1. Der Code sieht bisher so aus:
1
void ADC_init(void)
2
{
3
  uint16_t result;
4
  
5
  ADMUX = (1<<REFS1) | (1<<REFS1);    
6
  ADCSRA = (1<<ADPS1) | (1<<ADPS0);    
7
  ADCSRA |= (1<<ADEN);          
8
  
9
  ADCSRA |= (1<<ADSC);          
10
  while(ADCSRA & (1<<ADSC)){}        
11
  result = ADCW;              
12
}
13
14
uint16_t ADC_Read (uint8_t channel)
15
{
16
  ADMUX = (ADMUX & ~(0x1f)) | (channel & 0x1f);
17
  ADCSRA |= (1<<ADSC);          
18
  while (ADCSRA & (1<<ADSC)){}      
19
  return ADCW;              
20
}
21
22
int main(void)
23
{
24
  int i;
25
  uint16_t Fach[8];
26
  for (i=0; i<7; i++)
27
  {  
28
    ADC_Read(i);
29
    Fach[i] = ADCW;
30
  }  
31
  
32
  for (i=0; i<7; i++)
33
  {
34
    if (Fach[i] < 800)
35
    {
36
      if (Fach[i] > 500 )
37
      {
38
        PORTC |= (1<<PD[i]);
39
      }
40
    } 
41
    else
42
    {
43
      PORTC &= ~(1<<PD[i]);
44
    }
45
  }
46
}
Ich müsste jetzt wissen wie der Syntax ist um PortD[i] zu setzen. So 
nimmt AVR-Studio das Programm nicht an.

Schonmal danke im voraus.

von Coder (Gast)


Lesenswert?

1. Wenn Du schon Port C setzen kannst, warum du das nicht auf Port D 
übertragen.

2. Was ist PortD[]  ?

3. Quellcode unvollständig

von Karl H. (kbuchegg)


Lesenswert?

stephan blaha schrieb:


> Ich müsste jetzt wissen wie der Syntax ist um PortD[i] zu setzen.

Du kannst nicht PortD[i] setzen.

Aber du kannst einen Ausgang setzen, indem du mit einem Bitmuster 
veroderst. Das Bitmuster sagt aus, welcher/welche Pins zu setzen sind. 
Dieses Bitmuster kannst du allerdings entsprechend aus i ableiten.

von Karl H. (kbuchegg)


Lesenswert?

1
   if (Fach[i] < 800)
2
    {
3
      if (Fach[i] > 500 )
4
      {
5
        PORTC |= (1<<PD[i]);
6
      }
7
    } 
8
    else
9
    {
10
      PORTC &= ~(1<<PD[i]);
11
    }

da fehlt ein else Zweig. Was soll passieren wenn dein Fach[i] kleiner 
als 500 ist.

Alternativ (und besser ist es allerdings) wenn du in diesem Fall deine 
Beschreibung wörtlich nimmst:
> Also wenn Fach[1] kleiner 800 und größer 500 dann
denn dann sparst du dir einen else Zweig und kannst den daher auch nicht 
vergessen.
1
  if (Fach[i] > 500 && Fach[i] < 800)
2
    PORTC |= (1 << i );
3
  else
4
    PORTC &= ~( 1 << i );

von stephan b. (stu)


Lesenswert?

1
  for (i=0; i<7; i++)
2
  {
3
    if (Fach[i] < 800)
4
    {
5
      if (Fach[i] > 500 )
6
      {
7
        PORTC |= (1<<PD[i]); //Hier habe ich wohl zu schnell geändert
8
      }
9
    } 
10
    else
11
    {
12
      PORTC &= ~(1<<PD[i]); //ursprünglich sollte Port C gesetzt werden
13
    }
14
  }
Ich wollte aber ungern für jeden Ausgang eine If Bedingung machen in der 
ich das einzelne Bit setze bzw. Rücksetze. ich finde es in einer for 
Schleife eleganter und vor allem weniger arbeit. Wenn es allerdings nur 
so geht werde ich wohl für jeden Eingang eine If Anweisung schreiben 
müssen.
Trotzdem danke

von Alex (Gast)


Lesenswert?

1
for (i=0; i<7; i++)
2
{
3
   PORTC = (PORTC && ~(1<<i)) || (((int)Fach[i] > 500 && Fach[i] < 800) << i);
4
}

von Karl H. (kbuchegg)


Lesenswert?

stephan blaha schrieb:

> ich finde es in einer for
> Schleife eleganter und vor allem weniger arbeit. Wenn es allerdings nur
> so geht werde ich wohl für jeden Eingang eine If Anweisung schreiben
> müssen.

Schau dir mal den 2.ten Teil meiner 2.ten Antwort GENAU an.

von Krapao (Gast)


Lesenswert?

1
  uint8_t zustand = PORTC;
2
  for (i=0; i<7; i++)
3
  {
4
    if ( Fach[i] < 800 )
5
    {
6
      if ( Fach[i] > 500 ) 
7
      {
8
        zustand |= (1<<i);
9
      }
10
    } 
11
    else
12
    {
13
      zustand &= ~(1<<i);
14
    }
15
  }
16
  PORTC = zustand; // Einmaliges Setzen

Von der Programmlogik her halte ich deinen Code für nicht durchdacht, 
denn er hat eine logische Lücke für Fach[] <= 500.

Welchen Wert bekommt der Portpin dann zugewiesen? Ich habe das mal so 
gemacht wie du es geschrieben hast, nämlich

Fach[] <= 500                Pin in PORTC unverändert lassen
Fach[] > 500 && Fach[] < 800 Pin in PORTC setzen
Fach[] >= 800                Pin in PORTC löschen

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.