Forum: Compiler & IDEs 90can128 ignoriert if Abfrage


von Schwertadler (Gast)


Angehängte Dateien:

Lesenswert?

Moin alle zusammen,
hab eine Frage bezüglich abnormalem Verhalten von einem 90can128:
Und zwar funktioniert folgender Code sagenhaft, ich kann mit den 
Ausgängen schalten und walten wie ich will.
Jedoch wird die If-Abfrage davor total ignoriert. Was ich persönlich 
jetz weniger schön find...^^
1
#include <util/delay.h>
2
3
#include <avr/io.h>
4
//#include <avr/iocanxx.h>
5
#include <avr/iocan128.h>
6
7
8
int main (void)   
9
{
10
//Setup Controller
11
12
DDRC&=~(1<<0);
13
DDRC&=~(1<<1);
14
DDRC&=~(1<<2);
15
DDRC&=~(1<<3); //Declaration Logic Inputs
16
//PORTC=(1<<PORTC0)|(1<<PORTC1)|(1<<PORTC2)|(1<<PORTC3);//Pullups Logic Input on
17
//DDRA|=(1<<2)|(1<<3)|(1<<4); //Declaration Logic Output
18
19
while(1) 
20
  { if (PINC && (1<<PC3)) //Check 
21
    {
22
      PORTA|=(1<<PA2);
23
      PORTA|=(1<<PA3);
24
      _delay_ms(50);
25
      PORTA&=~(1<<PA2);
26
      PORTA&=~(1<<PA3);
27
      PORTA&=~(1<<PA4);
28
      _delay_ms(50);
29
    }
30
    
31
  }
32
return 0;
33
}

Angehängt hab ich einen Ausschnitt der Schaltung (nicht enthalten ist 
die Spannungsversorgung, und Programierschnittstelle, die funktionieren 
ja problemlos.)
Der Optokoppler befindet sich auf einem Sokel, die Treiber ebenfalls.

zur momentanen Funktion des Programms:
Wenn Pin3 am PortC gesetzt wird, soll in die Abfrage gesprungen werden, 
die 2 LEDs (über Treiber und FETs angesteuert) blinken lässt, und eine 
LED dauerhaft ausschaltet

Das Momentane Verhalten des Programms:
Die beiden LEDs blinken unaufhörlich, eine ist dauerhaft aus, die Zeiten 
stimmen.
Allerdings blinken sie ganz egal in welchem Zustand der Eingang sich 
befindet! Selbst bei entferntem Optokoppler, (ich hab nachgemessen, der 
Pin liegt tatsächlich auf GND), läst sich der uC nicht beirren und 
springt in die Abfrage rein.

Ich bin mit meinem Latein am Ende...sieht wer etwas einen Fehler im 
Quellcode?
Sachen die ich bereits versucht hab:
Aufsplitten der DDRC-Steuerung,
bzw komplettes rausnehmen (auch das DDRA-Register hab ich Spaßes halber 
mal rausgenemooen...hat den uC/Compiler nicht gejukt...),
rumspielen mit Vergleichsoperatoren,
setzen von Ausgängen in diversen Varianten,
rausnehmen von internen Pullups der Eingänge (die sollen eigentlich im 
Originalprogramm rein) etc.

Hab ich irgendwo ein Register übersehen oder ähnliches? Allerdings wär 
mir das halt auch neu...:/

Wär sehr schön wenn mir wer helfen könnte :) Ist mir eigentlich neu das 
ein AVR so merkwürdiges Zeug macht...

Danke Im Vorraus
Schwertadler

von Peter II (Gast)


Lesenswert?

> if (PINC && (1<<PC3))

diese abfrage würde ich auch ignorieren oder zumindest anders behandln 
als du erwartest.

&& != &

von Schwertadler (Gast)


Lesenswert?

Hey Peter II,
danke für die schenelle Antwort. Manchmal sieht man echt den Wald vor 
Lauter Bäumen nicht....x.x
Es lag wirklich am Operator :/
Danke nochmal
Schwertadler

von Schwertadler (Gast)


Lesenswert?

Wie gesagt die Abfrage funktioniert jetzt, allerdings verblüft mich nun 
ein weiteres Phänomen in folgendem Code:
1
int a=0;
2
3
while(1){
4
          if (!(PINC& (1<<PINC3)))//Versuch Phänomen zu Umgehen
5
    {
6
                 a=1;
7
    }
8
9
     if(a==1)//Eigentliche if Abfrage
10
            {
11
              Shiftdown();//Auszuführende Funktion 
12
              a=0;
13
            }
14
    
15
    
16
     if (a==0)//Live LED, Beweis das a==0
17
     { 
18
       PORTA|=(1<<PA4);
19
       _delay_ms(50);
20
       PORTA&=~(1<<PA4);
21
      _delay_ms(50);
22
    }
23
}
24
25
void Shiftdown() //Auszuführende Funktion (setze 2 LED mit delay, schalte danach LEDs wieder aus) 
26
  {
27
         PORTA|=(1<<PA2);
28
         _delay_ms(100);
29
         PORTA|=(1<<PA3);
30
         _delay_ms(150);
31
         PORTA&=~(1<<PA2);
32
         PORTA&=~(1<<PA3);
33
   }

Der uC verhält sich nun so:
Wenn eine If-Abfrage erfüllt ist (PinC3 gesetzt) springt er in die 
Shiftdown-Funktion erfült diese und springt dann wieder raus.
Aufgrund der While-Schleife macht der das ständig.
Entferne ich während der Abfrage die Spannung an PC3 stopt der uC die 
Ausführung dessen was in der Abfrage steht. (LED's PA2 &PA3 bleiben 
gesetzt). Ausserdem setzt er a=0, und springt zurück in die Schleife 
(die Live LED fängt an zu blinken)

Meine Frage: Wie kann man das umgehen? Und Was passiert denn überhaupt?
Ich meine normalerweise, prüft ein uC doch nur einmal wenn er in auf 
eine Abfrage stößt nicht dauerhaft, oder irr ich mich da?

Gruss Schwertadler

von Hmm (Gast)


Lesenswert?

Du drückst Dich leider etwas sehr seltsam aus, daher mag es sein, das 
ich Dich nicht recht verstehe. Aber ich versuche es mal.

>Wenn eine If-Abfrage erfüllt ist (PinC3 gesetzt) springt er in die
"if-Abfrage erfüllt"? Allenfalls kann die "Bedingung" einer 
"if-Anweisung" erfüllt sein oder nicht.

>Shiftdown-Funktion erfült diese und springt dann wieder raus.
"erfüllt"? Eine Funktion wird ausgeführt (oder auch nicht).
"springt"? Eine Funktion wird beendet, die Ausführung des Programmes an 
der Stelle nach dem Funktionsaufruf fortgesetzt.

>Aufgrund der While-Schleife macht der das ständig.
Das ist ja genau der Zweck einer while-Schleife.

>Entferne ich während der Abfrage die Spannung an PC3 stopt der uC die
"entfernen"? Welcher Pegel liegt dann an? Ist Dir klar, das Du auf 
"Null-Pegel" testest?

>Ausführung dessen was in der Abfrage steht. (LED's PA2 &PA3 bleiben
In "dieser" Abfrage wird nichts ausgeführt.

>gesetzt). Ausserdem setzt er a=0, und springt zurück in die Schleife
>(die Live LED fängt an zu blinken)


Was Du an Verhalten beschreibst ist genau das was Du da geschrieben 
hast.
Du hast nirgendwo innerhalb der Schleife eine Anweisung die a wieder 
zurück auf 1 setzt. (Abgesehen von der ersten if-Anweisung, die den 
Versuch darstellt, "daß Phänomen zu umgehen").
Wenn also die Schleife einmal durchlaufen worden ist, dann blinkt 
folgerichtig die Live-LED (meinst Du nicht eher Live-LED?).

>Ich meine normalerweise, prüft ein uC doch nur einmal wenn er in auf
>eine Abfrage stößt nicht dauerhaft,
Weder noch. Er prüft "jedesmal", wenn er im Programmablauf auf eine 
Bedingung trifft.

von Schwertadler (Gast)


Lesenswert?

> "if-Abfrage erfüllt"? Allenfalls kann die "Bedingung" einer
> "if-Anweisung" erfüllt sein oder nicht.
Ja sry, da hab ich mich ein wenig zu kompliziert ausgedrükt. x.x Ich 
mein wirklich die Bedingung.

>"erfüllt"? Eine Funktion wird ausgeführt (oder auch nicht).
>"springt"? Eine Funktion wird beendet, die Ausführung des Programmes an
>der Stelle nach dem Funktionsaufruf fortgesetzt.
genau das Mein ich mit springt zurück, die Funktion wird beendet, und 
das programm springt zurück in die if abfrage, um dort weiter Zumachen 
wo er aufgehört hat.

>"entfernen"? Welcher Pegel liegt dann an? Ist Dir klar, das Du auf
>"Null-Pegel" testest?
Auch hier muss ich mich nochmal entschuldigen. Ich meinte wenn ich 
Spannung auf PC3 gebe (bedeutet die erste abfrage im code ist nicht mehr 
erfüllt).

>In "dieser" Abfrage wird nichts ausgeführt.
Hier muss ich dir leider widersprechen.
1
     if(a==1)//Eigentliche if Abfrage
2
            {
3
              Shiftdown();//Auszuführende Funktion 
4
              a=0;
5
            }
Hier wird auf jedenfall etwas ausgeführt, ich versteh jedoch nicht wiso 
die ausführung nicht komplett ist.

>Du hast nirgendwo innerhalb der Schleife eine Anweisung die a wieder
>zurück auf 1 setzt. (Abgesehen von der ersten if-Anweisung, die den
>Versuch darstellt, "daß Phänomen zu umgehen").
>Wenn also die Schleife einmal durchlaufen worden ist, dann blinkt
>folgerichtig die Live-LED (meinst Du nicht eher Live-LED?).
Stimmt auffallend, genau das soll ja auch passieren, denn die Funktion 
dieser LED ist das der UC mir rückmeldung gibt: a) ich Lebe noch(bin 
nicht abgestürzt)
b) mein Programm ist gerade in der Dauerschleife, ich führe keine 
Funktion aus.

Der Kern des Ganzen Problems ist, wie du richtig bemerkt hast Hmm, das 
ich von einer Funktion erwarte das sie vollständig ausgeführt wird, 
bevor das Programm weiterläuft.
Aber genau das Passiert hier nicht. Stattdessen hängt es ganz stark 
davon ab wann die Bedingung von
1
     if(a==1)//Eigentliche if Abfrage
2
            {
3
              Shiftdown();//Auszuführende Funktion 
4
              a=0;
5
            }
nicht mehr erfüllt ist. Wenn ich dafür sorge das die Bedingung im 
Falschen Moment auflöse (Spannung auf PC3 gebe) dann bleiben die LEDs 
die durch meine Funktion gesteuert werden an, und das Program läuft dann 
wieder in der Schleife ab.
Mich verwirrt auch das die Funktion abgebrochen wird obwohl ich dort 
kein return oder sonstiges eingebe.

Genau das meinte ich auch als ich schrieb
>>Ich meine normalerweise, prüft ein uC doch nur einmal wenn er in auf
>>eine Abfrage stößt nicht dauerhaft,
>Weder noch. Er prüft "jedesmal", wenn er im Programmablauf auf eine
>Bedingung trifft.
Das der uC bis zum nächsten Schleifendurchlauf wartet, bis er die 
Bedinungen erneut abfragt ist mir klar. Genau das verwirrt mich ja, denn 
hier scheint beides Parrallel abzulaufen.
Oder was gibt es denn sonst für gründe das Funktionen nicht vollständig 
ausgeführt werden?

von Stefan E. (sternst)


Lesenswert?

Die Funktion wird nicht abgebrochen. Vermutlich sind die LEDs gegen VCC 
angeschlossen, funktionieren also mit inverser Logik.

von Schwertadler (Gast)


Lesenswert?

Nope, die LEDs werden indirekt Gesteuert über MosFETs (siehe Schaltplan 
erster Post vom Thread).
Ausserdem wird hab ich ja gesagt das bevor die Funktion abgeschlossen 
ist die Ausgänge gesetz werden.
Es Passiert aber beides, mal sind die Pins 1 und mal null, wenn der uC 
in der Hauptschleife ist. (Was ja laut Programcode ausgeschlossen ist)

Ich hab hier diese hübsche Funktion gefunden, erste versuche sehen 
vielversprechend aus.
http://www.rn-wissen.de/index.php/Taster-Abfrage_in_C#taster
Die Anweisungen was bei welchem Tastendruck zu Tun ist, kommt in die 
switch-case im Hauptprogramm.
Gruss^^

von Hmm (Gast)


Lesenswert?

Ich fürchte so wird das nichts. Das ist ein dermaüßenes Kauderwelsch und 
durcheinander, das ich nicht verstehe, was nun das Problem eigentlich 
ist.

>>In "dieser" Abfrage wird nichts ausgeführt.
>Hier muss ich dir leider widersprechen.
Mach ruhig. Richtger wird es dadurch auch nicht.
1
     if(a==1)//Eigentliche if Abfrage
2
            {
3
              Shiftdown();//Auszuführende Funktion 
4
              a=0;
5
            }
>Hier wird auf jedenfall etwas ausgeführt, ich versteh jedoch nicht wiso
>die ausführung nicht komplett ist.
Schon. Aber nicht in der "Abfrage". Will man das Wort nun unbedingt 
verwenden, dann ist eine Abfrage Teil des Tests einer Bedingung, aber 
nicht der abhängigen Anweisung.
Eine if-Anweisung besteht aber aus mehreren Teilen. Nämlich einer 
Bedingung und einer abhängigen Anweisungen; der von der Bedingung 
abhängigen Anweisung.

>>"entfernen"? Welcher Pegel liegt dann an? Ist Dir klar, das Du auf
>>"Null-Pegel" testest?
>Auch hier muss ich mich nochmal entschuldigen. Ich meinte wenn ich
>Spannung auf PC3 gebe (bedeutet die erste abfrage im code ist nicht mehr
>erfüllt).
Du hast "immer" eine Spannung an einem Pin. Du kannst garnicht eine 
Spannung wegnehmen. Wenn Du einen Draht entfernst, dann ergibt das 
dennoch (sog. floatendes) Potential.


>Mich verwirrt auch das die Funktion abgebrochen wird obwohl ich dort
>kein return oder sonstiges eingebe.
Du solltest mal ein C-Buch lesen. Eine void-Funktion braucht nicht 
notwendigerweise eine "return"-Anweisung.

>Das der uC bis zum nächsten Schleifendurchlauf wartet, bis er die
>Bedinungen erneut abfragt ist mir klar.
Nein. Er "wartet" nicht. Er führt andere Anweisungen aus.

So nun hast Du einen anderen Code gefunden ehe Du überhaupt gelernt hast 
diesen zu verstehen und Dich verständlich darüber und das Problem 
auszudrücken.
Nicht sehr sinnvoll.

von Malte S. (maltest)


Lesenswert?

Also parallel führt der uc garantiert nichts aus. Wenn Shiftdown() 
wirklich mittendrin abbricht, dann weil der Controller resettet. Du 
treibst doch den Aufwand mit MOSFETs samt Treiber nicht, um die LEDs mit 
12V zu versorgen, sondern Kupplung und Schaltung. Induktive Lasten? Wie 
sieht es mit Freilaufdioden aus?
Wie stabil ist die Versorgung? Schlägt der BOD zu?
Ich sehe 100n C5 an AREF, vermisse aber Abblock-Cs an den 
(A)VCC/GND-Pärchen. Gibt es die im geheimen Teil der Schaltung?
Was ist das für eine RESET-Beschaltung? R1 gehört nicht als 
Serienwiderstand da hin, sondern als Pullup, dürfen aber auch 10k sein. 
C4 gehört zwischen RESET und GND und eher so Größenordnung 100n.
Ist der Pullup an PC3 aktiviert?

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.