Bedingung wird manchmal nicht wahr

Gast #589187
Lesenswert?
• ▲
▼
hallo, ich hoffe ihr könnt mir helfen.. :-)

ein tiny 13 mit 9.6 MHz steuert einen Schrittmotor an, dieser soll 
zwischen zwei positionen hin- und herfahren. das klappt soweit, 
allerdings: den richtungswechsel macht er 3 mal, das vierte mal erkennt 
er nicht und läuft immer weiter. warum?

1
volatile uint8_t dir=0, speed = 128;
2
volatile uint16_t position = 32000, stop_l=31000, stop_r=33000;
3

4

5
ISR(TIM0_COMPA_vect)
6
{
7
  const uint8_t steps[4] = {STEP_PATTERN};
8
  static uint8_t step;                                
9
  OCR0A = TCNT0 + speed;                              
10
  
11
  if(dir)
12
  {
13
    if (step < 3)
14
      step++;
15
    else 
16
      step=0;
17
      
18
    position++;
19
  }
20
  else
21
  {
22
    if (step > 0)
23
      step--;
24
    else 
25
      step = 3;
26
      
27
    position--;
28
  }
29

30
  STEPPER_PORT = (STEPPER_PORT & ~STEP_MASK) | steps[step];  
31
  
32
}

es gibt ausserdem den overflow interrupt, in dem aber nichts mit diesen 
variablen geschieht. der timer läuft mit prescaler 256

in der main ist folgendes:
1
while(1)
2
  { 
3
    sleep_mode();
4
    
5
    if(switch_closed(1<<KEY))
6
    {
7
      dir = !dir;
8
    }
9
    
10
    cli();
11
    if(position == stop_l || position == stop_r)
12
    {
13
      dir = !dir;
14
    }
15
    sei(); 
16
    
17
    
18
    
19
  }

es macht keinen unterschied, ob hier die interrupts ausgeschaltet 
werden.
manuelle richtungswechsel werden immer erkannt.

mit stop_r=32999 erkennt er schon den zweiten wechsel nicht.

ich verstehe nicht, wieso diese überprüfung fehlschlägt :-(
Gast #589202
Lesenswert?
• ▲
▼
wenn ich die bedingung auf

if(position <= stop_l || position >= stop_r)

ändere, funktioniert es natürlich. das heisst, der moment, in dem die 
bedingung war erkannt würde kommt nicht, weil die prüfung davor und 
danach stattfindet.

ahh, vielleicht in dem fall, dass der overflow-interrupt den sleep-mode 
beendet, die überprüfung stattfindet, und der schrittmotor-interrupt 
dann zweimal hintereinander auftritt. schon wird der entscheidende punkt 
überschritten.

das ist ja fies!
#589203
Lesenswert?
• ▲
▼
Ich überschaue jetzt grad auf die Schnelle nicht, was da alles 
schieflaufen kann, aber die Abfrage für den Drehrichtungswechsel würde 
ich allein aus Sicherheitsgründen eher so schreiben:
1
if(position <= stop_l || position >= stop_r)
2
    {
3
      dir = !dir;
4
    }
Abfragen auf exakte Gleichheit sind meist etwas riskant...

Was ist das mit dem "switch_closed"?

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.