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
intmain(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
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
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
Wie gesagt die Abfrage funktioniert jetzt, allerdings verblüft mich nun
ein weiteres Phänomen in folgendem Code:
1
inta=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
voidShiftdown()//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
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.
> "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?
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^^
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.
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?