if Abfrage in main() ignoriert?

OP #2109665
Lesenswert?

Hallo alle zusammen :)!

Also ich steh hier einfach total am Schlauch.
Bin gerade dabei ein Programm häppchenweiße zu debuggen.
Aus reinen Testzwecken schaltet man mal da mal da ein LED ein oder aus.
Funktioniert auch alles so weit.

Es geht um die Anweisung. Ich weiß ein wenig aus dem Zusammenhang 
gerissen, der restl. Code befindet sich im Anhang.

Es handelt sich um die Zeile.
1
if(Second==5) PORTC ^= (1<<PC1);

Das komische ist wenn ich es in der ISR ausführe alles funktioniert.
1
ISR (TIMER1_OVF_vect)
2
{static uint8_t _20_ms=0;
3
 _20_ms++;
4

5
if (_20_ms == 50)
6
  {
7
   Second++;
8
   _20_ms = 0;
9
   if(Second==5) PORTC ^= (1<<PC1);
10
  }
11
}

Also so funktioniert es.
Jemand eine Idee?

Mfg JTR
Angehängte Dateien:
Gast #2109782
Lesenswert?

if(Second==5) PORTC ^= (1<<PC1);

Weil du diese Abfrage in deine Main machst.... und wenn deine ISR 
schneller ist und die Sekunden schon auf 6 hat bevor die bedinung 
getestet wird , kanns halt nicht funktionieren....also mach lieber

if(Second>4) PORTC ^= (1<<PC1);
#2110042
Lesenswert?

Wenn die Abfrage in main() steht, wird eine ganze Sekunde lang 
getoggelt. Erst ab der Sekunde 6 wird nicht mehr getoggelt. Wenn nur 1x 
getoggelt werden soll (das macht ja die ISR), dass musst Du in der ISR 
ein globales Flag setzen und dieses in main() nach Bearbeitung wieder 
löschen.

in der ISR:
if(Sekunde==5) tuwas=1;

in main():
if(tuwas){
  tuwas=0;
  PORTC ^= (1<<PC1);
}

tschuessle
Bernhard
OP #2110650
Lesenswert?

Danke für eure Antworten!

Ich denke, dass da irgendwo das richtige dabei sein wird :)!
Leider komm ich erst wieder am Montag zum testen, werde berichten.

@Läubi:
Hab wohl den upload der .c Datei vermasselt. Beim testen wurde natürlich 
nur an einer Stelle getoggelt.

@Henry:
Der Controller läuft mit 8Mhz. Ich glaub nicht, dass er bei so einem 
popeligen Programm nicht ein mal die main() durchrattern kann.

@Bernhard:
Das hört sich schon sehr vielversprechend an. Aber, dass jedes Mal eine 
gerade Zahl getoggelt wird?

Danke! Allen ein schönes WE :)!

MfG
#2113610
Lesenswert?

Diese Berechnung

        OCR1A_tmp = Tick_P_el_tmp / Divisor_P_el + P_Offset;

ergibt 1000

d.h. diese while Schleife hier

        while(!(OCR1A==OCR1A_tmp))
        {
          if(OCR1A < OCR1A_tmp) OCR1A++;
          if(OCR1A > OCR1A_tmp) OCR1A--;
          set_sleep_mode(SLEEP_MODE_IDLE);
                sleep_mode();
        } // While end

(wenn überhaupt der Timer interrupt den µC aus dem Sleep Mode rausholt 
was ich nicht kontrolliert habe), dauert bei 20 ms INterrup Frequenz wie 
lange, damit sie den Wert von OCR1A von Initial 1999 auf 1000 reduziert 
hat?

Dann kommen hinten nach noch mal 20 ms Wartezeit

->
Es ist ziemlich unwahrscheinlich, dass du hier

  if(Second==5)

die Variable Second genau mit dem Wert 5 erwischt. Die wird da schon 
wesentlich weiter sein. (DIe müsste da schon so im Bereich um die 20 
haben)


Was soll das ganze eigentlich sein? Was hat es da mit dem Sleep Mode auf 
sich, wozu die ganzen Wartereien?

Ich kann mir nicht helfen. Das ganze sieht für mich nach "von hinten 
durch die Brust ins Auge" Programmierung aus.
#2113954
Lesenswert?

1
ISR (TIMER1_OVF_vect)  // ISR for counting the time with 16-Bit Timer1; Overflow every 20ms
2
{static uint8_t _20_ms=0;
3

4
 _20_ms++;
5

6
if (_20_ms == 50)
7
  {
8
   Second++;
9
   _20_ms = 0;
10
   PORTC ^= (1<<PC0);
11
  }
12
}

Du setzt jedes mal wenn du in die ISR kommst deinen Wert von _20_ms auf 
Null. Dann geht er ja schon nie in die if Abfrage in deiner ISR.
Wie sollte dann Second jemals 5 werden?
#2113968
Lesenswert?

ups stimmt sorry 1tes Semester....
Nehm alles zurück und behaupte das gegenteil

Kann das aber sein das du 2 mal deinen Timer initialisierst? Bzw. dir 
deine Funktion implizit deklarierst?
Ein Prototyp gehört nicht unbedingt in die main
1
.....
2
// Prototypen
3

4
// Timer1 Initialization (ICP & PWM)
5
void Timer1_init(void);
6

7
// Timer1 Initialization
8
Timer1_init();
Gast #2113975
Lesenswert?

@ Hans W.

Lieber Hans,

das soll jetzt so ein kleiner Scherz unter Informatikern sein.

Du schriebst:

>Nehm alles zurück und behaupte das gegenteil

Das stimmt leider auch nicht so ganz.
Denn das Gegenteil von "jedesmal" ist eines von "niemals", "einmal" und 
"einige Male".
Eine static Variable wird aber genau "einmal" initialisiert.

Ich hoffe, Du findest das so lustig wie ich.
OP #2114034
Lesenswert?

Karl Heinz Buchegger schrieb:
> (wenn überhaupt der Timer interrupt den µC aus dem Sleep Mode rausholt
> was ich nicht kontrolliert habe)

kommt raus :)

> dauert bei 20 ms INterrup Frequenz wie
> lange, damit sie den Wert von OCR1A von Initial 1999 auf 1000 reduziert
> hat? DIe müsste da schon so im Bereich um die 20 haben)
>
Jo, 20s dürfte es dauern. Also alle 20ms ein Schritt weiter. 20ms*1000 = 
20 000ms = 20s. Daran hab ich wie immer nicht gedacht und wird auch des 
Rätslslösung sein. Ich verneige mich :)!


> Was soll das ganze eigentlich sein? Was hat es da mit dem Sleep Mode auf
> sich, wozu die ganzen Wartereien?
> Ich kann mir nicht helfen. Das ganze sieht für mich nach "von hinten
> durch die Brust ins Auge" Programmierung aus.

Ja, mag wohl so ausschauen. Wie bereits erwähnt handelt es sich um einen 
kleinen Ausschnit eines Programms. Quasi um gewisse Funktionen zu 
testen. Wenn man sein ganzes Prog. testen will und iwas nicht 
funktioniert wird, das eine endlose Sucherei.

Es geht darum die Position eines Servos langsam zu verändern.

Kennst du eine besser Methode (garantiert sogar) :D ;)!

Danke soweit!

MfG


ps: @guru: Ich habe gelacht :D! freaky
#2114814
Lesenswert?

Julian Schild schrieb:

> Es geht darum die Position eines Servos langsam zu verändern.
>
> Kennst du eine besser Methode (garantiert sogar) :D ;)!

1 Timer macht die Servoansteuerung. Ich hab jetzt nicht auf deine 
Taktfrequenz geachtet, aber der Timer 1 müsste normalerweise hinkommen.

Ein 2.ter Timer gibt einen Basistakt vor. In dessen ISR wird der OCR 
Wert für den Servo-Timer verändert, so dass er sich seiner Zielvorgabe 
annähert.
Sleep Mode braucht da kein Mensch dazu.

Hauptschleife
1
   while( 1 )
2
   {
3
     ServoSoll = 0;               // Zielvorgabe: Servo ganz nach links
4

5
     _delay_ms( 10000 );          // etwas warten (währenddessen verfährt
6
                                  // die Timer ISR das Servo
7

8
     ServoSoll = ServoMaximum;    // Zielvorgabe: Servo ganz nach rechts
9

10
     _delay_ms( 10000 );          // und wieder: das Servo fahren lassen
11
   }

Die Verfahr-ISR
Aufgabe: Wenn die Servo Istposition nicht mit der ServoSollposition 
übereinstimmt, dann für den Servo-Timer den OCR Wert nachstellen
1
ISR( .... )    // zb Overflow vom Timer 2
2
{
3
  if( OCR1A < ServoSoll )
4
    OCR1A++;
5

6
  else if( OCR1A > ServoSoll )
7
    OCR1A--;
8
}

Und dann natürlich noch den Timer 1, der so konfiguriert wird, dass er 
ganz alleine das Servosignal erzeugt, welches mit OCR1A beeinflusst 
werden kann.


Voila: Die komplette Servoansteuerung und Nachführung erledigen die 
Timer ganz von alleine bzw. mit einer ISR. In der Hauptschleife muss man 
nur noch die ServoSoll-Position zuweisen und das Servo fährt dann diese 
Position langsam an.

Hmm. Gerade noch mal drüber nachgedacht. Man könnte wahrscheinlich das 
ganze auch so regeln, dass der Timer 1 beides übernimmt. Er generiert 
sowohl die Servosignale (per Hardware) als er sich auch darum kümmert, 
dass die Servo Istposition an die Soll Position herangeführt wird (in 
einer ISR)
OP #2115051
Lesenswert?

Das ist, wie immer, eine gute Idee.

Dafür muss ich aber sogar den 3. Timer verwenden :D!

Denn der 1. 8 Bit Timer (Timer 0) zählt Pulse (fmax = 4kHz).
Das Ergebnis nach 50s ist dann ausschalggebend für die Servoposition.

Das der Timer1 (16Bit) bereits die Servoansteuerung übernimmt sieht man 
eh, außerdem übernimmt er auch noch die Funktion einer "Uhr".

Gefällt mir sehr gut, den Code schlanker zu machen und dafür auf die 
Hardware auslagern :)!

Danke Karl!! :)

MfG

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