PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : If-Anweisung



1udo1
19.01.2009, 23:56
Hallo,


in AVR Studio setze ich PINA auf HIGH. Die Abfrage if ( i != 0 ) ergibt doch eine "1", also wahr. Jetzt muss demnach Funktion test() angesprungen werden. Im Simulator wird PINA mit "1" angezeigt. Warum wird der Funktionsaufruf test() übersprungen? Bin neu in C. Fehlt irgendwo ein { oder ; oder sonst was? Nach der if-Abfrage springt der Befehlszähler sofort auf PORTB +=akku;

Danke meinen Helfern.

Udo



#include <avr\io.h>

uint8_t i, akku=9;


int main( void )
{

while(1)

{
// Funkion test1 aufrufen, wenn Bit 0 in Register PINA gesetzt (1) ist


i = PINA; // Inhalt in Arbeitsvariable
i = i & 0x01; // alle Bits bis auf Bit 0 ausblenden (logisches und)
// falls das Bit gesetzt war, hat i den Inhalt 1

if ( i != 0 ) // Ergebnis ungleich 0 (wahr)?
{
int test1(); // dann muss Bit 0 in i gesetzt sein -> Funktion aufrufen
}
akku+=1;

PORTB +=akku;
.................................................. ..................

Hier geht es weiter in der While-Schleife

// FUNKTIONEN test1() und weitere


int test1();
{

PORTB=0x55;
}

return 0 ;

markusj
20.01.2009, 00:50
Kann es sein, dass du den Pin erst auf High setzt, nachdem das Programm bereits i initialisiert hat?
Oder überschreibt möglicherweise die Tatsache, dass das DDRA nach einem Reset erst einmal auf Input steht, deinen manuell gesetzten Wert?
Am einfachsten wäre es wohl, wenn du den entsprechenden Anschluss (im Programm) auf Ausgang und "1" setzt ...

mfG
Markus

PS: Wenn du den Wert von PINA0 haben möchtest, nimm doch die entsprechende Konstante anstelle von 0x01, damit bist du auch abgesichert für den Fall, dass der Pinwert mal nicht mit dem Bit korrespondiert (gibts das überhaupt?)

1udo1
20.01.2009, 01:44
็Hallo Markus,

ich habe, deinem Vorschlag zur Folge, vor der Anweisung i=PINA den PINA0 auf HIGH gesetzt. Trotzdem wird die Funktion test() übersprungen.

Also:

PINA|= (1<<PA0);
i = PINA; // Inhalt in Arbeitsvariable
i = i & 0x01; // alle Bits bis auf Bit 0 ausblenden (logisches und)

if ( i != 0 ) // Ergebnis ungleich 0 (wahr)?
{
extern test1(); // dann muss Bit 0 in i gesetzt sein -> Funktion aufrufen
}

Das sieht wohl nach einem kapitalen Anfängerfehler aus, oder? Ich weiß aber nicht, was an diesen Anweisungen falsch sein könnte.


Udo

Jaecko
20.01.2009, 07:50
Also das hier:


PINA|= (1<<PA0);

dürfte nix bringen. Soweit ich weiss, kann man von PINx nur lesen.
Zum Schreiben gibts PORTx und DDRx.
Also zum "High" setzen gibts 2 Möglichkeiten:

Als Input, mit aktivem Pull-Up:


DDRA &= ~(1 << PA0);
PORTA |= (1 << PA0);


Als Output:


DDRA |= (1 << PA0);
PORTA |= (1 << PA0);



Du kannst ja mal nach "i = PINA;" den Wert von i ausgeben lassen, ob da auch wirklich was drinsteht.

sast
20.01.2009, 08:18
Guten Morgen 1udo1

mir sind erst mal zwei Sachen sofort ins Auge gefallen die mich zweifeln lassen, dass dein Code überhaupt kompiliert wurde. Zumindest nicht ohne dir irgendetwas mitzuteilen.
Irgendwie stimmen die öffnenden und schließenden Klammern nicht so recht überein.

Deine Funktion test1() hat als Rückgabewert einen int, den du aber erst außerhalb der Funktion setzt. Ich verstehe auch nicht wieso du die Funktion innnerhalb der main deklarieren willst. Muss gleich mal ausprobieren was mein Kompiler dazu sagt.

Irgendwie weiß man gar nicht wo deine main() aufhört. Da wird das Helfen schwer. Ich gehe mal davon aus, dass du nur Ausschnitte kopiert hast.

Nimm doch mal die Deklaration oder sogar die ganze Definition von test1() vor die main und ruf dann einfach mit x=test(); auf. Wenn du keinen Rückgabewert brauchst kann die Funktion auch void test1(void) sein. Dann sieht dein Aufruf test1(); auch wieder besser aus.

Wie gut sind denn deine C Kenntnisse?

Man sollte auch alle Warnungen beachten. Das spart so manche Überraschung bei der Ausführung

sast

thewulf00
20.01.2009, 08:43
Alles nötige wurde schon angesprochen, ich ergänze und fasse zusammen:
- int test() macht nur über dem Hauptprogramm Sinn, im Hauptprogramm nur "x = test();" aufrufen.
- Bitte code-Tags benutzen, damit man den Code besser lesen kann.
- Die Klammern überprüfen oder das ganze Programm posten.
- Warnungen des Compilers lesen!
- Die Zeile "PINA|= (1<<PA0);" ist quatsch.
- Was Jaecko gesagt hat, passt leider nicht zum Thema, muss aber trotzdem beachtet werden!
- PortB muss erst als Ausgang definiert werden.

PicNick
20.01.2009, 09:40
if ( i != 0 )
{
int test1(); //Das ist eigentlich nur eine definition und kein Code
}

cipher
20.01.2009, 09:41
Hi!

Du schreibst:


if ( i != 0 ) // Ergebnis ungleich 0 (wahr)?
{
int test1(); // dann muss Bit 0 in i gesetzt sein -> Funktion aufrufen
}


Das "int" beim Funktionsaufruf von test1() ist falsch. Nimm das mal weg. Mit


int test1();

deklarierst Du eine Funktion. Ich weiss jetzt allerdings nicht, ob das irgendwo zwischendrin C-konform ist. Ich denke mal, dass es daran liegen könnte.


Viele Grüße,

Markus

sast
20.01.2009, 10:00
so hab es mal getestet, weil es mir keine Ruhe gelassen hat und ein int test2(); in die main() getippt. Wie zu erwarten war kam bei mir folgende Warnung: "warning: function declaration isn't a prototype"

Wenn du wissen willst ob er überhaupt in die if springt, kannst du den Inhalt deiner test1 Funktion einfach mal an die Stelle des Funktionsaufrufes setzen.

Besser von klein nach groß probieren, als hinterher abspecken zu müssen. Da baut man sich sonst bloß noch neue Fehler ein.

Du solltest dich da vorher mal genauer mit Funktionen -Deklaration, Definition und Aufruf- beschäftigen. Sonst kommt ganz schnell was anderes raus als man geplant hat.

Und nochmal der Hinweis mit den Warnungen. Das kann man nicht oft genug sagen.

sast

1udo1
20.01.2009, 11:51
Hallo und DANKE an meine Tutoren,

für meine Kollegen Anfänger poste ich das Programm, wie es meine Helfer vorgeschlagen haben. Es wird dem einen oder anderen eine Hilfestellung sein, um sich in C langsam vorzutasten.

Kann mir vorstellen, dass es nicht unbedingt geschickter Code ist, aber er funktioniert.

Noch eine Frage an die Fachleute:

Wird der Variablen x ein Wert zugewiesen?


x = test1(); // dann muss Bit 0 in i gesetzt sein -> Funktion

Bin mir nicht sicher, weil im Klammerausdruck von test() kein Parameter drin steht. Stimmt das?

Bitte habt Nachsehen, ich blicke noch nicht so durch!

Also hier der Code, der funktioniert


// Port einlesen mit Prüfung des Zustandes von Portbits IF-ANWEISUNG

// Januar 2009 o.k.

// Tastenkombinationen
// << links unten, { ALT-GR und 7, } ALT-GR und 0, [ ALT-GR und 8, ] ALT-GR und 9,
// ~ ALT-GR und *, | ALT-GR und Pfeil unten links,

#include <avr\io.h>

uint8_t i, x, akku, c_akku,b;


int test1()
{
c_akku +=1;

PORTC = c_akku;

return 0 ;

}

int main( void )
{
DDRA = 0xff; // R24 Ausgang
DDRB = 0xff; // R24 Ausgang
DDRC = 0xff; // R24 Ausgang

while(1)
{
// Funkion test1 aufrufen, wenn Bit 0 in Register PINA gesetzt (1) ist

i = PINA; // R18 Inhalt in Arbeitsvariable

// PORTA0 wird nur gelesen, wenn DDRA als Ausgang definiert ist; wird der PORTA0 auf
//HIGH gesetzt, dann wird automatisch das Bit PINA0 gesetzt

i = i & 0x01; // alle Bits bis auf Bit 0 ausblenden (logisches und)
// falls das Bit gesetzt war, hat i den Inhalt 1

if ( i != 0 ) // Ergebnis ungleich 0 (wahr)?
{
x = test1(); // dann muss Bit 0 in i gesetzt sein -> Funktion aufrufen
}
akku+=2;
PORTB =akku;
} // Ende while-Schleife
}

Jaecko
20.01.2009, 12:11
Ob der Variable mit "x = test1();" was übergeben wird, hängt davon ab, ob sie einen Rückgabewert hat oder nicht (void). In den Klammern muss dazu nix stehen.

In dem von dir genannten Programm ist der Rückgabewert aber immer 0 (return 0);

sast
20.01.2009, 12:37
nur damit dir das klar ist, das "x" war nur ein Platzhalter für einen Variablennamen in meiner Erklärung. Du kannst die Zuweisung auch weglassen. Dann brauchst du aber auch keinen Rückgabewert für die Funktion vorzusehen. Deshalb der Vorschlag von mir mit void f(void)

Zu deiner Frage bezüglich x und den Parametern (Übergabeparameter) sag ich nochmal, lies mal ein bisschen in C Tutorials über Funktionen.

http://openbook.galileocomputing.de/c_von_a_bis_z/c_011_002.htm#RxxobKap011002040027691F03218C

hab ich gerade zufällig gefunden

Viel Spass beim lernen und gewöhne dir an den Code etwas mehr zu formatieren. zB durch einrücken mit tab

sast

1udo1
20.01.2009, 13:57
Hallo sast,

ich wälze mich durch die Literatur von C -- und das dauert. Danke für deinen Link!! Der fehlte mir noch. Habe nach einem solchen Link gesucht.

Eure Tipps haben mich wieder ein Stück weiter gebracht.

Eine Sache habe ich aber mit dem Setzen von DDRA0 noch nicht geschnallt:

Ich habe DDRA0 auf Ausgang gesetzt. Wenn PORTA0 ein HIGH sieht, wird PINA0 auf High gesetzt. Alles o.k.

Wenn aber DDRA0 auf Eingang gesetzt wird und man legt hardwaremässig 5V an PORTA0 , dann liest der PINA0 diesen Zustand nicht ein, oder? Im Simulator kann man das sehen. Somit reagiert doch mein Programm nicht auf einen HIGH-Pegel an PORTA0. Oder bin ich da auf dem falschen Dampfer?
Ich will doch diesen PORTA0 überwachen, was von aussen reinkommt.

sast
20.01.2009, 14:17
Wenn du den Port als Input setzt und ihn mit VCC auf 5V ziehst, kannst du so oft 5V anlegen wie du willst, da ändert sich nichts. Nicht destotrotz kannst du die ganze Zeit den Pegel des Ports auslesen. Bringt bloß nicht viel.

Wenn du in dieser Konstellation eine Änderung haben willst, musst du den Eingang auf Masse ziehen. Oder du setzt den Port auf 0 und legst über einen Schalter 5V an.

Wie rum du das machst ist Geschmackssache und manchmal auch durch die Schnittstellenbeschreibung vorgegeben. Ich persönlich versuche es immer so hinzubekommen, dass über den 0V Pegel ausgelöst wird.

Wenn du Probleme mit Eingang oder Ausgang setzen hast, dann poste lieber deinen geänderten Code damit wir dir bei eventuellen Fehlern helfen können. Aber denke bitte ans Formatieren sonst hat keiner Lust sich da immer wieder die Augen zu überanstrengen.

Hoffe das mit den Pegeln war verständlich genug

sast