Hallo,
ich bin "Neuling" im Bereich µC Programmierung mit C.
Ich programmiere schon seit längerem im Bereich Objective-C (iOS), aber
wie mir scheint gibt's in diesem Bereich so einige Sachen, welche anders
sind...
Zum Beispiel habe ich mit folgendem Code meine Probleme, genauer gesagt
mit dem IF Statement nach dem 1. IF.
Im Simulator klappts, dann auf dem STK600 mit ATmega2560 nicht mehr -
entweder habe ich einen Denkfehler oder das Board / MCU ist kaputt...???
Hier der Code:
#include <avr/io.h>
#include "stdint.h"
volatile uint8_t counter;
int main(void)
{
DDRB = 0b00000010;
PORTB = (1 << PB1);
while(1)
{
if(PORTB & (1 << PB1))
{
if(counter < 5) // dieses if wird vom Board nicht "erkannt"
{
PORTB &= ~(1 << PB0);
counter++;
}
else
{
PORTB |= (1 << PB0);
}
}
else
{
PORTB |= (1 << PB0);
counter = 0;
}
}
}
Gibts bei den IF Statements hier in C mehr zu beachten bzw.
Besonderheiten?
Vielen Dank schon mal im Vorraus!
Grüße,
Alex
PS: Ich "lerne" mit dem AVR-GCC-Tutorial hier von Mikrocontroller.net.
Hallo Alex,
beschreibe doch bitte erst einmal welche Reaktion du von dem Programm
erwartest. Dass es im Simulator funktioniert könnte vielleicht daran
liegen, dass du es dort Schritt für Schritt durchgehst, es auf dem Board
dann aber alles viel schneller abläuft.
Gruß
André
Alexander F. schrieb:> Im Simulator klappts, dann auf dem STK600 mit ATmega2560 nicht mehr -> entweder habe ich einen Denkfehler oder das Board / MCU ist kaputt...???
Die Klammern sind nicht richtig eingerückt. Kein Wunder, dass das zu
Unklarheiten führt.
Hallo André,
ein Eingang gibt ein permanentes Signal zum einschalten, ein Motor wird
aktiviert - dieser liefert Impulse zurück welche der µC zählen und nach
X Impulsen den Motor wieder deaktivieren soll.
Gruß,
Alex
... schrieb:> Die Klammern sind nicht richtig eingerückt.
Kann es aufgrund des Einrückens bzw. der Klammern zu fehlern führen???
if(1 == 1) {
}
else {
}
ODER
if(1 == 1) {
} else {
}
ODER
if(1 == 1)
{
}
else
{
}
macht das in dieser Sprache einen unterschied?
Alexander F. schrieb:> sorry, sollte natürlich PINB heissen...
PB1 wird als Ausgang definiert. Dieser wird vor der while-Schleife auf
HIGH gesetzt und danach nie mehr angefasst. Demzufolge ist diese
if-Abfrage sinnlos. Insbesondere wird nie der zugehörige else-Zweig
erreicht und damit wird auch counter auch nie auf 0 zurückgesetzt.
Alexander F. schrieb:> Kann es aufgrund des Einrückens bzw. der Klammern zu fehlern führen???
Nein, nicht in C, wohl aber zu fehlendem Durchblick, der dann wiederum
zu Fehlern führt. Oder die Forenleser so verwirrt, dass sie sich
weigern, sich dem eigentlichen Thema zu widmen.
Tipp fürs Posten: TABs sind hier sehr unpraktisch.
Woran erkennst du, dass das if nicht erkannt wird?
Der µC ist so schnell, dass schon beim ersten Impuls bis 5 gezählt wird.
Und die Zeit ist zu kurz, dass da irgend etwas sinnvolles am Motor
passiert.
DirkB schrieb:> Woran erkennst du, dass das if nicht erkannt wird?
Ich hatte vorhin eine LED als Ausgang geschalten und diese sollte, nach
Betätigung eines Tasters und herunterzählen von ca. 1000 Schritten
deaktiviert werden...
Es passierte nichts, die LED ging nicht aus. (In der IF Abfrage hatte
ich PINB verwendet)
Vielleicht hatte ich heute einfach nur "den Wald vor lauter Bäumen nicht
gesehen" oder das STK600 bzw. die MCU ist defekt... gg
Wie und wo hast Du counter deklariert? Bitte immer den exakten Code (mit
Copy+Paste) posten, sonst versäumst Du die Zeit allfälliger Foren-Helfer
mit unnötigen Tippfehlern
>herunterzählen von ca. 1000 Schritten
Wo sind denn diese 1000 Schritte zu sehen / zu finden?
1
if(counter<5)
2
{
3
PORTB|=(1<<PB0);
4
counter++;
5
}
6
else
7
{
8
PORTB&=~(1<<PB0);
9
}
Der counter wird schneller auf 5 gezählt, als Dein Auge den LED-Blitz
mitkriegen kann!
Alexander F. schrieb:> Naja die LED sollte komplett erlischen
Also in meinen eigentlichen Code sollte der Motor stoppen... in dem
Beispielcode hier wollt ich auf das IF Statement bezug nehmen.
Hier würde es ja tatsächlich nur kurz blitzen.
Alexander F. schrieb:> Ich hatte vorhin eine LED als Ausgang geschalten und diese sollte, nach> Betätigung eines Tasters und herunterzählen von ca. 1000 Schritten> deaktiviert werden...> Es passierte nichts, die LED ging nicht aus. (In der IF Abfrage hatte> ich PINB verwendet)
1000 Schritte? Mit einem uint8_t?
Nach dem Upload auf das STK600 sind seltsamerweise alle Pins am PORTA
(Ausgang) aktiv. Wenn ich dann PD1 betätige und wieder los lasse
schaltet sich die LED kurz aus (wahrscheinlich die 10000 schritte lang).
Entferne ich nun das IF Statment "if(stepCounter < MOTORSTEPS)" und
ersetze es mit einem einfachen "PORTA |= (1 << PA0);" dann läuft alles
normal, d.h. die LED an PA0 ist von Anfang an aus und wird erst bei
Betätigung PD1 aktiv...
Was ist hier falsch?
Was genau hängt bei dir am PD1?
Dir ist bewusst, dass der Eingangspin vom STK600 mit Taster so
funktioniert, dass er bei NICHT gedrücktem Taster eine 1 liefert (Bit
ist gesetzt) und bei gedrücktem Taster dieses Bit eine 0 liefert.
Will man also etwas tun, wenn ein Taster gedrückt ist, dann lautet die
Abfrage
if( !(PIND & (1 << PIND1) ) { // Taster PD1 ist gedrückt
Karl Heinz Buchegger schrieb:> Dir ist bewusst, dass der Eingangspin vom STK600 mit Taster so> funktioniert, dass er bei NICHT gedrücktem Taster eine 1 liefert (Bit> ist gesetzt) und bei gedrücktem Taster dieses Bit eine 0 liefert.
Vielen Dank, das hilft mir ungemein weiter.
War mir leider nicht bewusst...
Kann es auch sein, dass die Ausgangsschaltung verkehrt ist???
PORTA &= ~(1 << PA0) = Ein
PORTA |= (1 << PA0) = Aus
Alexander F. schrieb:> Vielen Dank, das hilft mir ungemein weiter.> War mir leider nicht bewusst...>> Kann es auch sein, dass die Ausgangsschaltung verkehrt ist???> PORTA &= ~(1 << PA0) = Ein> PORTA |= (1 << PA0) = Aus
Probiers doch einfach aus
1
intmain()
2
{
3
DDRA=0xFF;
4
PORTA=0b11110000;
5
6
while(1)
7
;
8
}
welche LED leuchten? Die bei denen du ein 0-Bit gesetzt hast, oder die
bei denen du ein 1-Bit gesetzt hast?
Und schon hast du das selber rausgefunden.
Alexander F. schrieb:> Ja, Danke.>> Ich hatte gedacht ich hab einen Fehler im Code, anstatt zu wissen dass> eben diverse Bits hierbei anders zu setzen sind...
Genau aus dem Grund beginnen alle Tutorien hier auf der
Mikrocontroller-Website damit, dass erst mal einzelne Ausgänge auf 0
oder 1 gesetzt werden um LED zum Leuchten oder Nicht Leuchten zu
bringen. Sie sind quasi das "Hallo Welt" der µC Szene mit dem
Nebeneffekt, dass man rauskriegt was eine 0 oder eine 1 am Ausgabepin
bewirkt. Es ist ja kein Naturgesetz, dass eine 1 etwas einschalten muss.
Für den "nicht gedrückter Taster liefert eine 1" gibt es allerdings
einen guten Grund. Im AVR gibt es nur Pullup Widerstände. Pullup
bedeutet, dass ein offener Eingang damit auf 1 gezogen wird. Ein nicht
gedrückter Taster ist aber so ein offener Eingang. Erst durch das
Drücken des Tasters wird der Eingang mit irgend einer Spannung
verbunden. Wenn ich aber nur einen Pullup habe und damit einen offenen
Eingang nur auf 1 ziehen kann, dann bleibt für den Taster nicht mehr
viel übrig als nach GND zu schalten. Und damit liefert dann ein
gedrückter Taster eine 0 (weil der Taster den Eingang nach Masse
verbindet) und wenn der Taster nicht gedrückt ist, dann zieht der
Pullup-Widerstand den Eingang auf 1.