PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem Atmega32 LED blinklicht



semicolon
24.05.2006, 10:53
Hallo zusammen

Ich habe eigentlich nur ein kleines Problem, dass mich aber bereits mehrere Stunden in Anspruch genommen hat.

Schaltung:

Es sind zwei LED an PortB0 und PortB2 angeschlossen über einen 1kOhm Widerstand gegen Masse.

Hardware: Atmega32 4MHz Quarz, progammed mittels avrdude

Software:

#include "io.h"
#include "iom32.h"

void wait () {

int i;
for (i = 0; i <20000; i++) {
int j;
for(j = 0; j <20000; j++){

}

}
}



int main (void)
{

//DDRB = (1<<DDB2);
DDRB = (1<<DDB0) | (1<<DDB2);


while (1) /* Note [6] */

wait();
PORTB = 1;
wait();
PORTB = 5;
wait();

return (0);
}

Die wait-Funktion verzögert ungefähr eine Sekunde. Wahrscheinlich sogar etwas mehr.

Nun zum Problem: Es funzt gar nicht. Nur dass LED an PortB0 dauernd leuchtet. Was ist falsch? Selbt wen der AVR nicht den externen Quart nehmen würde, sollte dennoch ein blinken stattfinden.

Danke für eure Hilfe

Cybrix
24.05.2006, 11:35
wenn ich das richtig sehe musst du beim PORTB =5 nicht 5 sondern 4 hinschreiben weil 5 wäre ja 101 und du willst ja eigentlich 001 haben wenn ich das richtig verstehe! So leuchtet die LED an PORTB0 andauernt mit!

Cybrix
24.05.2006, 11:41
Hallo zusammen

int main (void)
{

//DDRB = (1<<DDB2);
DDRB = (1<<DDB0) | (1<<DDB2);


while (1) /* Note [6] */

wait();
PORTB = 1;
wait();
PORTB = 5;
wait();

return (0);
}


Wenn ich richtig bin ist das Zeichen beim DDRB | bedeutet das nicht oder?
Müsste da nicht ein & hin? Oder && ! Das weis ich jetzt nicht genau!

BiGF00T
24.05.2006, 11:55
Ja, das bedeutet oder.
Will man ein Bit auf 1 setzen, so macht man ein oder. Um es auf 0 zu setzen, muss man es mit und behandeln. 1 oder irgendwas gibt immer 1, 0 und irgendwas gibt immer 0.

Btw, code-Tags wären cool :)



#include "io.h"
#include "iom32.h"

void wait ()
{
int i;
for (i = 0; i <20000; i++)
{
int j;
for(j = 0; j <20000; j++)
{
}

}
}



int main (void)
{

//DDRB = (1<<DDB2);
DDRB = (1<<DDB0) | (1<<DDB2);


while (1) /* Note [6] */

wait();
PORTB = 1;
wait();
PORTB = 5;
wait();

return (0);
}

uwegw
24.05.2006, 11:58
Zu Erinnerung mal die korrekte Syntax für das Setzen von Bits in den Registern:

Bit setzen:
PORTB |= (1<<PB4);
(ODER [|] mit der Bitmaske rechts und dem alten Zustand)

Bit löschen:
PORTB &= ~(1<<PB4);
(UND [&] mit der INVERTIERTEN [~] Bitmaske)

Bit toggeln:
PORTB ^= (1<<PB4);
(EXODER [^] mit der Bitmaske)

PS: für die Verzögerung bietet sich auch folgendes an:


#include <avr/delay.h>
void warte(uint16_t loop) //loop: wartezeit in ms
{
uint16_t i;
for(i=0;i<loop;i++) _delay_ms(1);
}

BiGF00T
24.05.2006, 11:59
Moment, hab ich da gerade gesehen


while (1) /* Note [6] */

wait();

?
macht das nicht endlos wait?

Ich denke es sollte wohl eher eine { hinter das wait und dann später nochmal.

Also praktisch so:




#include "io.h"
#include "iom32.h"

void wait ()
{
int i;
for (i = 0; i <20000; i++)
{
int j;
for(j = 0; j <20000; j++)
{
}

}
}



int main (void)
{

//DDRB = (1<<DDB2);
DDRB = (1<<DDB0) | (1<<DDB2);


while (1) /* Note [6] */
{
wait();
PORTB = 1;
wait();
PORTB = 5;
}

return (0);
}

uwegw
24.05.2006, 12:02
Genau! Der While-Schleife fehlen die Klammern!!!
So ergibt sich für den Compiler eine leere While-Schleife, deren Bedingung immer wahr ist, daher beliebt der AVR für immer in dieser Zeile hängen...

Cybrix
24.05.2006, 12:03
ne aber muss while nicht auch mit geschwiften klammern ein gerückt sein in etwa so:

int main (void)
{

//DDRB = (1<<DDB2);
DDRB = (1<<DDB0) | (1<<DDB2);


while (1) /* Note [6] */

{

wait();
PORTB = 1;
wait();
PORTB = 5;
wait();

}

return (0);
}

BiGF00T
24.05.2006, 12:04
/* Note [6] */


Nur Spass... Hat bestimmt jeder schonmal sowas gebaut ;)

Ich zumindest bin das erste Mal fast verzweifelt, als ich nach einem while() was gelöscht hatte und aber den ; nicht mitgelöscht habe und dann nie was tat.

EDIT:
Das letzte wait() habe ich in meinem Stück Code übrigens auch weggelassen, da ja sonst das wait() ausgeführt wird, dann die Schleife von neuem anfängt, wo dann gleich wieder ein wait() steht. Falls das so geplant war, dann wieder einfügen :)

semicolon
24.05.2006, 13:05
Danke für eure Hilfe.

Habe vor lauter Bäume den Wald nicht mehr gesehen.

Tja, was weggelassene {} so alles auswirken können?!

Danke nochmals

Cybrix
24.05.2006, 13:42
aber normalerweise beschwert er sich bei mir deswegen mit welchem programm programmierst du denn?

semicolon
24.05.2006, 15:13
Ja ist ein einfaches Programm Names WINAVR. Hat jedenfalls nicht gemotzt.

BiGF00T
24.05.2006, 15:57
Nein, was er erzeugt hat war ja auch astreiner C-Code. Das ist ein Fehler, den kein Compiler findet. Das ist genauso, also ob du machst:

for (x=0; x<10; x++); blinkLED();

und dich dann wunderst, warum es nur 1x blinkt anstatt 10x.

Wenn WinAVR bei dir motzt, dann ist was echt falsch.
Sonst könntest du ja nie machen


while (1)
dosomethinguseful(someparams);

ohne Compilerfehler zu bekommen.
Das Programm denkt sich nicht, ob es jetzt sinnvoll ist oder nicht, da mal endlos zu warten. Könnte ja so gewollt sein und verstößt in keinster Weise gegen die Syntax von C.

SprinterSB
24.05.2006, 16:05
Warum sollte gcc motzen, ist ja ein syntaktisch korrektes C-Programm ;-)

gcc kennt tausende von Warnungen. Einige davon bekommst du mit -W -Wall

Speziell in deinem Fall hätte dich folgendes aus der Kurve gehebelt:

avr-gcc ... -Wunreachable-code -Werror


-Wunreachable-code

Warn if the compiler detects that code will never be
executed.

This option is intended to warn when the compiler
detects that at least a whole line of source code will
never be executed, because some condition is never
satisfied or because it is after a procedure that
never returns.

It is possible for this option to produce a warning
even though there are circumstances under which part
of the affected line can be executed, so care should
be taken when removing apparently-unreachable code.

For instance, when a function is inlined, a warning
may mean that the line is unreachable in only one
inlined copy of the function.

This option is not made part of -Wall because in a
debugging version of a program there is often
substantial code which checks correct functioning of
the program and is, hopefully, unreachable because the
program does work.

Another common use of unreachable
code is to provide behavior which is selectable at
compile-time.