Forum: Mikrocontroller und Digitale Elektronik While Schleife Abbruchbedingung wird nicht wie geplant ausgeführt


von Chris T. (chris0086)


Lesenswert?

Hallo Leute,
ich habe ein Problem mit einer Whileschleife in der solange gewartet 
wird bis entweder ein timeout stattfindet, ODER Daten empfangen wurden.

Die While Schleife wird aber erst nach dem Timeout verlassen, ich sehe 
den Fehler nicht :(

Der Systic wird jede Sekunde um eins erhöht.
Sobald ein string mit Master_send_command gesendet wird schicke ich dann 
die Antwort über die serielle Schnittstelle und u_r_c ist nichtmehr 0.
Jetzt müsste die While Schleife eigentlich sofort verlassen werden, wird 
sie aber erst nach 3 Sekunden... dann geht erst die LED an

Sieht jemand einen Fehler?
1
ISR(USART_RXC_vect)
2
{
3
  
4
  
5
  uint8_t i;
6
  if(uart_transmit_progress)
7
  {
8
    uart_r_array[u_rx_start] = UDR;
9
    uart_back_read=1;
10
11
    //u_rx_start++;
12
    
13
  }
14
  else
15
  {
16
17
18
    //USART_Transmit(receive_string[i]);
19
    //USART_Transmit(i);
20
    i = u_rx_start;
21
    u_receive_string[i] = UDR;
22
    //lcd_putc(i);
23
    // Sendstring: 01 10 01 00 01 04 00 00 30 18
24
    if (i==5)
25
        {
26
          receive_max = u_receive_string[i] +6;
27
          
28
          //if((u_receive_string[i] & 0x10 )== 0x10)
29
30
        }
31
32
    if(i == receive_max)
33
    {
34
      u_rx_start=0;
35
      
36
      u_r_c = receive_max;
37
      //USART_Transmit('Z');
38
39
    }
40
    else
41
    {
42
43
      i++;
44
      u_rx_start = i;
45
    }
46
  }
47
}
48
49
50
ISR(TIMER1_COMPA_vect)
51
{
52
  systic++;
53
  //LED3_C;
54
}
55
56
int main(void)
57
{
58
59
60
  //LED-Ausgänge konfigurieren
61
  DDRA |= (1<<DDA7) | (1<<DDA6) | (1<<DDA5);
62
63
64
  //USART initialisieren
65
66
  TRANSMIT_CONF; // Transmit Pin als Ausgang
67
  //USART0
68
  UBRRH = UBRR_VAL_UART >> 8;
69
  UBRRL = UBRR_VAL_UART& 0xFF;
70
71
  //USART0
72
  UCSRB |= (1<<TXEN);                // UART TX einschalten
73
  UCSRB |= (1<<RXEN);
74
  UCSRB |= (1<<RXCIE);
75
  UCSRB |= (1<<TXCIE);
76
  UCSRC |= (1<<URSEL)|(1<<UCSZ0)| (1<<UCSZ1) | (1<<UPM1);    // Asynchron 8N1 even
77
78
  
79
  
80
  //Timer initialisieren
81
  
82
  //Systemtic
83
  TCCR1B |= (1<<WGM12);
84
  TCCR1B |= (1<< CS12)|(1<< CS10); //CPU/1024
85
  TIMSK |= (1<<OCIE1A);      //Compare match
86
  OCR1A = 8000;          // 1 Sekunde
87
  
88
  sei();
89
90
91
92
93
  while(1)
94
  {
95
    if(u_r_c != 0) //Es wurden Daten empfangen
96
    {
97
98
99
100
      uart_putc((uint8_t) u_r_c);
101
      u_r_c = 0;
102
      LED3_OFF ;
103
    }
104
    if(systic)
105
    {
106
      Master_send_command(current_controller,48,0);
107
      LED3_OFF;
108
// HIER DIE WHILE SCHLEIFE
109
      while((systic<=3) && !(u_r_c ) );  
110
      if(systic >= 3) // Gerät hat nicht geantwortet
111
      {
112
        
113
      }
114
      if(u_r_c != 0)    //Gerät hat geantwortet
115
      {
116
        
117
        uint16_t acceleration_sensor = 0;
118
        if(u_receive_string[1] == 48)    //Slaveantwort mit Sensorinformationen  
119
        {
120
          if(u_receive_string[6] != 0)
121
          {
122
            LED3_ON;
123
          }
124
          else              //kein Sensor hat ausgelöst
125
          {
126
            
127
          }
128
        }
129
        u_r_c = 0;
130
      }
131
      current_controller++;
132
      systic = 0;
133
    }
134
    //Alle controller ausgelesen, jetzt schauen ob ein Panel geschaltet werden muss und das tun
135
    if(current_controller>SLAVE_CONTROLLER)
136
    {
137
      current_controller = 1;
138
      uint8_t controller;
139
      uint8_t feld;
140
      feldgetroffen = 0;          //36 = Feld2 controller 4
141
      feld = (feldgetroffen>>4);
142
      controller = (feldgetroffen &= 0x0F);
143
      //uart_putc(30);
144
      //uart_putc(feld);
145
      //uart_putc(controller);
146
      if(feld != 0)              // es wurde wirklich ein Feld getroffen
147
      {
148
        if(controller !=0)          //Slavecontroller einstellen
149
        {
150
          Master_send_command(controller,(feld |= (1<<4) ),colour_1);
151
        }
152
        else                //Mastercontroller einstellen
153
        {
154
          switch_color((colour_1>>16),(colour_1>>8),(colour_1>>0),feld);
155
        }
156
        
157
      }
158
      //LED3_OFF;
159
      
160
    }
161
    
162
  }
163
}

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Chris T. schrieb:
> Sieht jemand einen Fehler?

Das fehlt erstmal die Deklaration deiner Variablen. Ohne die gesehen zu 
haben, vermute ich mal, das es der alte Fehler ist, Flags oder 
Variablen, die in ISRs und dem Hauptprogramm benutzt werden, nicht als 
'volatile' zu erklären.
Du spart übrigens nichts, wenn du statt kryptischer Zeichenketten wie 
'u_r_c' z.B. 'Receive_Complete' oder so schreibst. Lesen tut sichs aber 
besser - tust du bei anderen Variablen ja auch.

von Oliver S. (oliverso)


Lesenswert?

Chris T. schrieb:
> u_r_c = 0;

Oliver

von Chris T. (chris0086)


Lesenswert?

Danke an die Hilfe, es läuft jetzt. Der Fehler war ganz woanders...

von Stefan F. (Gast)


Lesenswert?

> Der Fehler war ganz woanders...

Nett wäre es, die Lösung des Rätsels hier zu veröffentlichen.

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.