Hallo Leute,
habe ich in meinem Code ein Denkfehler?
Ein Unterprogramm wird immer wieder in main aufgeruffen.
>>int main(void) {>> while(1) {>> Code();>> }>>}
Wenn ich den Taster (E0,1) drücke, dann soll die LED (A0,3) angehen und
auch wenn der Taster (E0,1) nicht mehr gedrückt wird soll die LED
leuchten.
>>void Code(void){>> If(E0 & ( 1 << 1) ) {>> A0 |= ( 1 << 3 );>> }>>}
Leider ist es so, dass sobald ich den Taster los lasse, wird auch die
LED gelöscht.
Was mache ich falsch? Wo liegt mein Fehler? Ich teste das Programm auf
STK500 (ATmega8)
Gruß
steve schrieb:
> Was mache ich falsch? Wo liegt mein Fehler? Ich teste das Programm auf
Dein Fehler besteht darin, dass du nicht das komplette Programm postest.
Sprich: der Fehler befindet sich in dem Teil, den du hier nicht zeigst.
Gruß,
Magnetus
>Dein Fehler besteht darin, dass du nicht das komplette Programm postest.>Sprich: der Fehler befindet sich in dem Teil, den du hier nicht zeigst.
Möglicherweise liegt der Fehler aber auch in deinem Versuchsaufbau.
Sicher das du die led nicht ausversehen direkt mit dem schalter
schaltest, weil du irgend eine Brücke falsch gesetzt hast?
>allerdings mag ich hier gerne ein einfaches Makro:>#define BIT(n) (1 << (n))>dann wirds vernünftig lesbar.
Geschmackssache. Auf jeden Fall sollte man sich auf eine Variante
festlegen und auf jeden Fall die von den avr-Headern bereitgestellten
Kosntanten benutzen.
funky schrieb:
> gehts nur mir so, das ich 0x08 einleuchtender finde als 1 << 3 ??
Ja.
"1 << 3" ist zwar auch nicht das Gelbe vom Ei, aber immer noch besser
als "0x08".
Besser wäre es so:
Warum aber
#define LED3 (1<<3)
besser sein soll als
#define LED3 (0x08)
, das erschließt sich mir nicht so ganz... ich benutze dann ja eh keine
"magic numbers" mehr im Code, dafür hab ich ja das define.
Ja, zumindest in den letzten 20 Jahren ;-)
Es ist nicht nur schneller bei der Ausführung, sondern schon beim
compilieren, wenn der Parser auch complexe konstante Ausdrücke als
konstanten Wert an den Compiler übergibt.
@Mark,
na auch deine #defines muss jemand anderes in angemessener Zeit lesen
können. Code-Reviews mit lauter 0xDEADBEEF sind meist nicht die
Angenehmsten ;-)
Maxxie schrieb:
> @Mark,>> na auch deine #defines muss jemand anderes in angemessener Zeit lesen> können. Code-Reviews mit lauter 0xDEADBEEF sind meist nicht die> Angenehmsten ;-)
Hehe, ich kenn DEBB und AFFE...
Naja aber die Zweierpotenzen sollte man schon drauf haben, oder? Zumal
wenn da sowas steht wie:
#define LED0 (0x01)
#define LED1 (0x02)
#define LED2 (0x04)
#define LED3 (0x08)
#define LED4 (0x10)
#define LED5 (0x20)
#define LED6 (0x40)
#define LED7 (0x80)
Also das sollte man vielleicht gerade noch so vom Verständnis hinkriegen
:-)
Hallo Leute,
ich habe den "Fehler" gefunden, aber ich verstehen trotzdem nicht was
das damit zu tun hat.
Und zwar sobald ich die Globale Interupts (sei();) einschalte, habe ich
dieses Problem.
Mein Code sieht man im Anhang?
Warum kommt das so?
Gruß Steve
Ist ja normal, du schaltes den Interrupt des Timer0 frei, hast aber
keine Routine, welche den Interrupt abarbeiten kann.
versuch mal ISR(TIM0_OVF_vect) oder so ähnlich.
> ...du schaltes den Interrupt des Timer0 frei, hast aber> keine Routine, welche den Interrupt abarbeiten kann.
Deshalb wird der Reset-Vektor angesprungen
--> das Programm startet neu
--> die LED ist wieder aus.
Lothar Miller schrieb:
>> ...du schaltes den Interrupt des Timer0 frei, hast aber>> keine Routine, welche den Interrupt abarbeiten kann.> Deshalb wird der Reset-Vektor angesprungen> --> das Programm startet neu> --> die LED ist wieder aus.
Womit wir wieder bei dem Punkt wären, den Magnus 10 Minuten nach
Fragestellung angemerkt hat:
> Sprich: der Fehler befindet sich in dem Teil, den du hier nicht zeigst.
Mark Brandis schrieb:
> Warum aber>> #define LED3 (1<<3)>> besser sein soll als>> #define LED3 (0x08)
Weil ich bei 0x08 wieder nachdenken muss, welches Bit denn nun gesetzt
ist. Bei (1<<3) brauch ich das nicht. Es steht schon dort: Bit 3 ist
gesetzt. Wenn die Led aus irgendeinem Grund von Pin 3 auf Pin 6 versetzt
werden muss, schreib ich einfach
#define LED3 (1<<6)
und fertig.
Bei deiner Version muss ich wieder überlegen, welche Hexzahl sich
ergibt, wenn Bit 6 gesetzt ist.
Lass den Compiler die Routinearbeiten erledigen. Der macht das
zuverlässiger. Die Kunst beim Programmieren besteht auch darin, sich den
Source Code so zu organisieren, dass man Änderungen einfach machen
kann ohne grossartig nachdenken oder analysieren zu müssen.
> ich benutze dann ja eh keine "magic numbers" mehr im Code, dafür hab> ich ja das define.
"magic numbers" zu vermeiden ist das eine. Aber es ist nur die halbe
Miete.
1
#define NR_ENTRIES 5
2
intEntries[NR_ENTRIES]={10,80,100,40,80};
3
4
intmain()
5
{
6
for(i=0;i<NR_ENTRIES;++i)
7
// mach was mit Entries[i]
8
}
benutzt auch keine direkten 'magic numbers' im Code.
Trotzdem hast du dir unnötigerweise einen möglichen Stolperstein
eingehandelt. NR_ENTRIES und die Anzahl der Initialisierungen müssen
übereinstimmen.
(Und nein: Beides ist gleich effizient. Nur um gleich dem Einwand der
erhöhten Laufzeit vorzubeugen. Die paar Hunderstel Sekunden, die der
Compiler zum Parsen und Bewertung des konstanten Ausdrucks benötigt,
können wir getrost vergessen. Spätestens wenn du nur ein einziges mal
einen 2.ten Compilerlauf benötigst, weil der Compiler warnt, dass die
Anzahl der Initialisierungen nicht mit der Array-Size übereinstimmt,
hast du mehr Zeit unnötig verbrutzelt als das Schreiben und die
zusätzliche Compilerlast in vielen Tausend Compilerdurchgängen benötigt)
> Also das sollte man vielleicht gerade noch so vom Verständnis hinkriegen
Klar sollte man das. Aber wozu, wenn es eine Schreibweise gibt, bei der
die Bitnummer direkt dort steht? Und an dieser Stelle interessiert mich
die Bitnummer viel mehr als alles andere, weil sie mir sagt, nach
welchem Pin ich auf dem µC suchen muss, wenn ich ein Multimeter
draufhalten will. Die Hex-Zahl bringt dagegen keinen Vorteil an dieser
Stelle, ausser den, den Programmierer geistig beweglich zu halten und
seine Fertigkeit im Erkennen von gesetzten Bits in einer Hexzahl zu
trainieren.
In der alternativen Schreibweise muss ich mir lediglich merken, dass das
Muster 1 << x ein Datenwort ergibt, welches an der Stelle x ein 1-Bit
aufweist. Diese Erkentniss brauchst du aber in der µC-Programmierung
sowieso alle Nase lang.
> Weil ich bei 0x08 nachdenken muss, welches Bit denn nun gesetzt ist.
Nachdenken schadet nicht...
Wenn ich z.B. ein Kommandoregister initialisiere, dann sagt mir
1
kreg=0x47;
dass ich alle Bits angeschaut, bewertet und anschliessend auf 1 oder 0
gesetzt habe. Wenn ich dagegen
1
kreg=(1<<6)|(1<<2)|(1<<1)|(1<<0);
ansehe, dann könnte man ja meinen, ich hätte nur die Bits angefasst, von
denen ich meinte, sie wären wichtig. Hier könnte der geneigte Leser des
Programms den Verdacht hegen, dass ich eines einfach vergessen habe.
Ausführlich müsste ich also schreiben
Leserlich ist das jetzt nicht mehr.
> Die Hex-Zahl bringt dagegen keinen Vorteil an dieser Stelle, ausser den,> den Programmierer geistig beweglich zu halten und seine Fertigkeit im> Erkennen von gesetzten Bits in einer Hexzahl zu trainieren.
... und kompakter zu Schreiben und zu Lesen zu sein. Es ist doch nur ein
klitzekleiner Mehraufwand, sich neben all dem anderen Zeug noch die
Hexzahlen anzulernen.
> Die Hex-Zahl bringt dagegen keinen Vorteil an dieser Stelle...
Aber an anderer Stelle doch? Dann muß ich sie auch lesen können, und
Übung macht bekanntlich den Meister ;-)
Lothar Miller schrieb:
> Wenn ich z.B. ein Kommandoregister initialisiere, dann sagt mir>
1
kreg=0x47;
> dass ich alle Bits angeschaut, bewertet und anschliessend auf 1 oder 0> gesetzt habe. Wenn ich dagegen>
1
kreg=(1<<6)|(1<<2)|(1<<1)|(1<<0);
> ansehe, dann könnte man ja meinen, ich hätte nur die Bits angefasst, von> denen ich meinte, sie wären wichtig. Hier könnte der geneigte Leser des> Programms den Verdacht hegen, dass ich eines einfach vergessen habe.> Ausführlich müsste ich also schreiben>
Christopher G. schrieb:
> Falsch!> Du hast bei der HEX Schreibweise vergessen 0xB8 mal 0x00 zu addieren!
Rechne mal nach, das hab ich schon im Kopf gemacht :-o
Und sogar noch 0xFF dazuverundet ;-)
Gut, dann denke mal nach was (0<<3) | (0<<7) ergibt.
Zuweisung ist Zuweisung! Hex oda Shift sagt genau nichts darüber aus, ob
man die ganze Funktion des Registers beachtet!
> Gut, dann denke mal nach was (0<<3) | (0<<7) ergibt.
Ich weiß das schon, glaubs mir ;-)
Aber ich könnte mir gut vorstellen, dass das einige ins Schleudern
bringt.
> Hex oda Shift sagt genau nichts darüber aus, ob man die ganze Funktion> des Registers beachtet!
Nein, aber in Hex habe ich jedem Bit explizit einen Wert zugewiesen, ich
kann nicht einfach eines vergessen.
BTW: was ist eigentlich in C der Wert 0987 als Hex-Zahl dargestellt?
@ Jochen64:
Das eigentliche Problem ist schon lange gelöst:
Interrupts verwendet, ohne eine Interruptroutine zu haben.
Beitrag "Re: einfacher C-Code -> Denkfehler??"
Lothar Miller schrieb:
>> Die Hex-Zahl bringt dagegen keinen Vorteil an dieser Stelle...> Aber an anderer Stelle doch?
Klar.
Kommt immer darauf an, in welchem Zusammenhang ich eine Zahl benutze.
#define SECS_PER_HALF_HOUR 60*60
#define SECS_PER_HALF_HOUR 3C*1C
Hier ist Dezimal 'besser' als 'Hex'
Es gibt kein 'pauschales' besser.
Lothar Miller schrieb:
> Nein, aber in Hex habe ich jedem Bit explizit einen Wert zugewiesen, ich> kann nicht einfach eines vergessen.
Bei
1
FOO=(1<<3);
habe ich auch jedem Bit einen Wert zugewiesen.
Bei
1
FOO|=(1<<3);//bzw &= ~(..);
siehts anders aus, tortzdem heisst es bei Hex nicht, dass man alles
beachtet hat.
> BTW: was ist eigentlich in C der Wert 0987 als Hex-Zahl dargestellt?
Ich verstehe die Frage nicht. 0987 ist eine Oktalzahl in C, da sie mit 0
beginnt. Als Hex wäre es einfach 0x987 (bzw 0x0987 wennst die führende 0
willst).
HB schrieb:
> Einfacher gehts nicht>> #define LED1_ON (PORTA &= ~0x01)> #define LED1_OFF (PORTA |= 0x01)> #define TASTER1 (PINE & 0x01)>>> While(1)> {> if(TASTER1)LED1_ON> .> .> .> .> irgendwo...LED1_OFF
Ich finde Bitvariablen einfacher.
Man kann sie auf 0 oder 1 testen bzw. setzen, wie jede andere Variable
auch.
Und man kann ihnen vor allem aussagekräftige Namen geben:
> #define SECS_PER_HALF_HOUR 60*60>> #define SECS_PER_HALF_HOUR 3C*1C
Ist aber Müll... Klammern vergessen... Kann also häßliche Seiteneffekte
haben. Ausserdem ist "3C" kein gültiges C...
Besser ist:
> 0987 ist eine Oktalzahl in C
Yeah, reingefallen :-D
9 und 8 gibts in einer Oktalzahl nicht :-o
Übrigens:
0321 ist in C nicht 0x0321, sondern
0 3 2 1
binär 000 011 010 001
und damit 0000 1101 0001
0 D 1
In C gilt also:
0321 = 0xD1
Lothar Miller schrieb:
>> 0987 ist eine Oktalzahl in C> Yeah, reingefallen :-D> 9 und 8 gibts in einer Oktalzahl nicht :-o
Du Hund! (:
> In C gilt also:> 0321 = 0xD1
Dazu war die Fragestellung nicht präzise genug.
Christopher G. schrieb:
>> 0321 = 0xD1> Dazu war die Fragestellung nicht präzise genug.
Du hast schneller eine Ausrede, als eine Maus ein Loch.
Ich bin beeindruckt ;-)
Programmierer schrieb:
>> #define SECS_PER_HALF_HOUR 60*60>>>> #define SECS_PER_HALF_HOUR 3C*1C>> Ist aber Müll... Klammern vergessen... Kann also häßliche Seiteneffekte> haben. Ausserdem ist "3C" kein gültiges C...>> Besser ist:>>
1
>#defineSECS_PER_HALF_HOUR(60*60)
2
>
3
>#defineSECS_PER_HALF_HOUR(0x3C*0x1C)
4
>
Veto!
1. Eine halbe Stunde hat 30 * 60 Sekunden.
2. 0x1C sind 28 und passen nun gar nicht ins Schema ;)
Ansonsten stimme ich der Aussage von "Programmierer" zu.
Magnus Müller schrieb:
> Ansonsten stimme ich der Aussage von "Programmierer" zu.
Recht hat er.
Ich bin beim Schreiben gestört worden (Achtung: Chef kommt!) und habe
kurzfristig auf Senden gedrückt :-)
Der Sinn dürfte aber rübergekommen sein.
Ob Hex oder Dezimal oder Binär oder die 1<<x Schreibweise:
Es kommt auf den Verwendungszweck an, welche Darstellung vernünftiger
ist.
> Veto!>> 1. Eine halbe Stunde hat 30 * 60 Sekunden.>> 2. 0x1C sind 28 und passen nun gar nicht ins Schema ;)
Sehr gut aufgepasst!
Es ist immer wieder spannend, wieviele Fehler man in nur zwei Zeilen
Code einbauen kann. Faszinierend.
> Es ist immer wieder spannend, wieviele Fehler man in nur zwei Zeilen> Code einbauen kann. Faszinierend.
Dieser Satz hätte von Mr. Spock stammen können. Allerdings hätte er an
Stelle statt "man" wohl eher "ein Humanoid" geschrieben ;)