case-Anweisung

OP #4042384
Lesenswert?

Moin,

ich arbeite gerade mit einem ATMEGA168 und möchte ein 
switch-case-Anweisung verwenden. Interessanterweise funktioniert eine 
der Anweisungen ohne Probleme, die andere, die genauso aufgebaut ist 
allerdings nicht. Hier mal der Code:

Die funktionierende Anweisung
1
void light(int x)
2
  {
3
    switch (x){
4
    
5
      case 0:
6
        PORTC |= (1<<PC5);
7
        break;
8
      case 1:
9
        PORTC &= ~(1<<PC5);
10
        break;
11
    }
12
  }

Die nicht funktionierende Anweisung
1
void led_rt(int x)
2
  {
3
    switch (x)
4
    {
5
    case 0:
6
      PORTB |= (1<<PB1);
7
      break;
8
    case 1:
9
      PORTB &= ~(1<<PB1);
10
      break;
11
    
12
    }
13
  }

Ich sehe den Unterschied (vom Aufbau her) der beiden Anweisungen nicht, 
und kann mir nicht erklären, warum es einmal funktioniert und einmal 
nicht.

Gruß
OP #4042956
Lesenswert?

Nein, ich habe beide Ports definiert. Ich hatte dies nur bei meiner 
Frage nicht mit aufgeführt.
1
DDRB |= (1<<DDB0) | (1<<DDB1);
2
DDRC |= (1<<DDC5);
Beide Ports sind nach gleichem Muster definiert.
So kann ich auch PB1 beeinflussen, nur nicht in der case-schleife.
1
PORTB &= ~(1<<PB1);
2
PORTB |= (1<<PB1);
Gast #4042975
Lesenswert?

Marco G. schrieb:
> Nein, ich habe beide Ports definiert. Ich hatte dies nur bei meiner
> Frage nicht mit aufgeführt.

LMA. Mal wieder ein unvollständiges Programm und wahrscheinlich liegt es 
an verpolter LED. Port beeinflussen heißt nicht LED leuchtet. Was heißt 
überhaupt "... es einmal funktioniert und einmal nicht".
#4042982
Lesenswert?

tastendrücker schrieb:
> jöle schrieb:
>> Was heißt
>> überhaupt "... es einmal funktioniert und einmal nicht".
>
> Na -ich denke er meint: light(x) fnktioniert und led_rt(x) nicht.

Dann einfach mal den Inhalt der beiden Funktionen vertauschen.

Ich tippe auch auf entweder einen Hardware-Fehler (LED falsch 
angeschlossen), oder eine falsche Initialisierung irgendwo in einem 
Stück Code, das man uns hier wie so oft vorenthält.
Gast #4042985
Lesenswert?

Was genau funktioniert nicht? Explodiert der Controller?

Bau einen default in die switch cases und leite von da auf eine 
Fehlerbehandlung.

Und poste den vollständigen Code! Der Fehler liegt genau da, wo du 
ihn nicht vermutest.

Und immer dieses 1 << , was soll das? Warum schreibt man nicht einfach 
Bit2 usw.?
OP #4042992
Lesenswert?

Nein die LED ist nicht verpolt, da sie außerhalb der Case-Anweisung auch 
leuchtet, wenn ich die Pins manuell setzte.

Hier mal der Code, wobei ich die Initialisierung der Ports bereits 
angegeben hatte.
1
int main(void)
2
{
3
  avr_init();
4
  lcd_init();
5
  //TSIC_INIT();
6
  light(1);
7
  
8
  lcd_clear();
9
  led_bl(1);
10

11
  
12
  
13
  
14
    while(1)
15
    {
16
    
17
    sprintf(Buffer_counter, "%d", counter);
18
    lcd_setcursor(0,1);
19
    lcd_string("Counter: ");
20

21
    
22
//          getTSicTemp(&temperature);          
23
//          temperature = ((temperature * 250L) >> 8) - 500;  
24
//          itoa(temperature, temperature_out, 10);
25
//          celsius = temperature / 10 + (float) (temperature % 10) / 10;
26
//          lcd_setcursor(3,0);
27
//          lcd_string("Temperatur");
28
//          lcd_numbers(celsius, 5, 1);
29
     _delay_ms(500);
30
//     lcd_clear();
31
     light(1);
32
     
33
     
34
     if (counter >= 100)
35
     {
36
      light(0);
37
      lcd_clear();
38
      led_bl(0);
39
      led_rt(1);
40
      
41
      counter = 0;
42
     }
43
 
44
     
45
     counter++;
46
    }
47
}

Und Hier die avr_init():
1
void avr_init(void){
2
  
3
  //Definieren der Ausgänge
4
  DDRB |= (1<<DDB0) | (1<<DDB1);
5
  DDRC |= (1<<DDC5);
6
  
7
  //Definieren der Eingänge
8
  DDRC &= ~(1<<DDC3);
9
  DDRD &= ~(1<<DDD6);
10
  
11
  //Setzen der Pull-Ups der Eingänge
12
  PORTC = (1<<PC3);
13
  PORTD = (1<<PD6);
14
  
15
  //Setzen der Ausgangszustände
16
  PORTB |= (1<<PB0) | (1<<PB1);
17
  PORTC |= (1<<PC5);
18
}
OP #4042999
Lesenswert?

Vergessen zu kopieren. Dies steht natürlich noch vor der main:
1
#define F_CPU 1000000UL
2

3
#define Grad 0x80
4

5
#include <avr/io.h>
6
#include <util/delay.h>
7
#include <stdio.h>
8
#include "avr.h"
9
#include "lcd.h"
10
#include "tsic.h"
11

12
uint16_t temperature = 0;
13
float celsius = 0;
14
char temperature_out[10];
15
int counter = 0;
16
char Buffer_counter[5];
#4043010
Lesenswert?

Möglicher Weise hat der Compiler Probleme mit dem _ in LED_rt. Den _ 
würde ich mir hier schenken und eher ledRot schreiben oder ähnliches.

int x würde ich so auch nicht verwenden, du weißt hier nämlich nicht wie 
groß x gewählt wird und es könnte hier auch ein 32 bit Integer benutzt 
werden. Hier genügt aber ein 8 bit Integer und der ist für den AVR auch 
leichter zu behandeln. Daher ist es nicht verkehrt immer uint8_t (hier 
wird ein 8 bit unsigned Integer benutzt) und ähnliches zu benutzen.
Gast #4043027
Lesenswert?

Nur mal so, an welchem Port hast du denn das LCD angeschlossen? 
Vielleicht ist der Treiber unsauber geschrieben und lcd_init() 
überschreibt deine Port Konfiguration aus avr_init();

Ich glaube es wäre wirklich sinnvoll, uns den GESAMTEN Code zu geben, 
denn zumindest ich sehe in dem aktuellen Code den Fehler nicht.
Gast #4043046
Lesenswert?

Also mit im Nebel rumstochern ist dir nicht geholfen und uns nur Zeit 
gestohlen. Reduziere den Code auf die fehlerhaften Funktionen und teste, 
ob es dann funktioniert. Wenn Nein, dann poste hier den reduzierten Code 
hier, aber diesen inklusive Funktions- und Variablendeklaration und 
definition. Dann besteht auch die Chance, dass dir hier schnell und gut 
geholfen werden kann.
OP #4043065
Lesenswert?

Hier mal der vereinfachte Code. Die blaue LED funktioniert, nur die Rote 
nicht.

avr.h
1
#ifndef AVR_H_
2
#define AVR_H_
3

4
void avr_init(void);
5
void led_rt(uint8_t);
6
void led_bl(uint8_t);
7
void light(uint8_t);
8

9

10
#endif /* AVR_H_ */

avr.c
1
  #define F_CPU 1000000UL
2
  
3
  #include <avr/io.h>                  //einbinden der Bibliothek 'io.h'
4
  #include <util/delay.h>                //einbinden der Bibliothek 'delay.h'
5
 
6
  
7
 
8
  void avr_init(void){
9
  
10
  //Definieren der Ausgänge
11
  DDRB |= (1<<DDB0) | (1<<DDB1);
12
  DDRC |= (1<<DDC5);
13
  
14
  //Definieren der Eingänge
15
  DDRC &= ~(1<<DDC3);
16
  DDRD &= ~(1<<DDD6);
17
  
18
  //Setzen der Pull-Ups der Eingänge
19
  PORTC = (1<<PC3);
20
  PORTD = (1<<PD6);
21
  
22
  //Setzen der Ausgangszustände
23
  PORTB |= (1<<PB0) | (1<<PB1);
24
  PORTC |= (1<<PC5);
25

26
  
27
  
28
  }
29
  
30
  void led_rt(uint8_t x)
31
  {
32
    switch (x)
33
    {
34
    case 0:
35
      PORTB |= (1<<PB1);
36
      break;
37
    case 1:
38
      PORTB &= ~(1<<PB1);
39
      break;
40
    
41
    }
42
  }
43
  
44
  void led_bl(uint8_t x)
45
  {
46
    switch (x)
47
    {
48
    case 0:
49
      PORTB |= (1<<PB0);
50
      break;
51
    case 1:
52
      PORTB &= ~(1<<PB0);
53
      break;
54
    
55
    }
56
  }
57
  
58
  void light(uint8_t x)
59
  {
60
    switch (x){
61
    
62
      case 0:
63
        PORTC |= (1<<PC5);
64
        break;
65
      case 1:
66
        PORTC &= ~(1<<PC5);
67
        break;
68
    }
69
  }

main.c
1
define F_CPU 1000000UL
2

3

4
#include <avr/io.h>
5
#include <util/delay.h>
6
#include "avr.h"
7

8

9

10
int counter = 0;
11

12

13
int main(void)
14
{
15
  avr_init();
16
  
17
  led_bl(1);
18
  led_rt(0);
19

20
  
21
  
22
  
23
    while(1)
24
    {
25
 
26
   counter++;
27

28
     if (counter >= 100)
29
     {
30
      
31
      lcd_clear();
32
      led_bl(0);
33
      led_rt(1);
34
      
35
      counter = 0;
36
     }
37

38
     
39
     _delay_ms(500);
40
     
41
    }
42
}
#4043090
Lesenswert?

Mal abgesehen vom LCD-Code sehe ich hier keinen Fehler. Gib dem Switch 
für die rote LED mal eine default-funktion, sowas wie
1
default:
2
PORTB |= (1<<PB0);
3
_delay_ms(500);
4
PORTB &= ~(1<<PB0);
5
_delay_ms(250);
6
PORTB |= (1<<PB0);
7
_delay_ms(250);
8
PORTB &= ~(1<<PB0);
9
_delay_ms(250);
10
PORTB |= (1<<PB0);
11
_delay_ms(250);
12
PORTB &= ~(1<<PB0);
13
_delay_ms(250);
14
PORTB |= (1<<PB0);
15
_delay_ms(250);
16
PORTB &= ~(1<<PB0);
17
_delay_ms(250);
18
PORTB |= (1<<PB0);
19
_delay_ms(500);
20
PORTB &= ~(1<<PB0);
21
break;
#4043103
Lesenswert?

Marco G. schrieb:
> So jetzt mal die Zeile rausgenommen und neu kompiliert. Hat sich nichts
> am Verhalten der LED geändert.

Dreh mal die 0 und 1 bei den LED-Funktionen in main rum, so dass die 
LEDs genau andersrum leuchten müss(t)en wie vorher. Wenn nicht, dann 
programmierst du seit Stunden immer das Programm von gestern in den 
Controller, oder deine Hardware ist nicht das, was du von ihr erwartest.

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