Hallo zusammen,
Ich habs jetzt hingekriegt des ich den µC (atmel Atmega128)
programmieren kann . Jetzt wollt ich einfach mal zum test eine LED
blinken lassen dafür hab ich einfach den PORTA = 0x01 gesetzt ne for
Schleife reingemacht und wieder zurückgesetzt die LED blinkt zwar aber
immer im gleichen Rythmus egal wie lang ich die for Schleife mach kann
mir jemand sagen woran des liegt wäre super !
Vielen Dank schonmal !
Gruß
Carsten
Ohne Deinen Sourecode gesehen zu haben, wird Dir das wohl niemand sagen
können. Aber raten kann man ja mal: Vielleicht optimiert der verwendete
Compiler die Schleife immer weg? => Compileroptionen prüfen. Es ist
jedenfalls erwiesen, dass man Zeitschleifen unterschiedlicher Länge für
die AVR programmieren kann. ;-)
Gruß, Frank
Hhm, bin ja nicht gerade ein C-Freak, aber IMHO ist das soweit in
Ordnung. Mit welcher Taktfrequenz läuft denn Dein Chip und welche Werte
für die Schleife hast Du ausprobiert? Und wie schnell blinkt die LED
mit dem Schleifenwert 10000 ungefähr?
Gruß, Frank
Mein Controller läuft mit 16 MHz.
Ich habe schon 10 000, 100 000, 1 mio, 2 mio ausprobiert,
aber da ändert sich nichts...
Die LED blinkt etwa 10 mal in der sek. habe die Frequenz nicht
gemessen.
Gruß
Carsten
Hi Carsten,
Dein Code ist nicht ganz richtig.
Die For-Schleife wird kein einziges Mal durchlaufen, weil die
Abbruchbedingung "verkehrt rum" ist.
Anstatt
for (i=0;i>=10000;i++)
hast Du wohl
for (i=0; i < 10000; i++)
gemeint. Ich denke Du möchtest, dass er die Schleife 10.000 mal
durchläuft.
Und der zweite Punkt:
Ich vermute ganz stark, dass Frank recht hat und die Schleife komplett
wegoptimiert wird. Der Compiler erkennt, dass eine solche Schleife
keinen Sinn macht und entfernt sie...
Probier mal das folgende:
for (i=0; i < 10000; i++)
asm volatile ("nop");
Das volatile verhindert, dass der Compiler das NOP (=no operation)
wegoptimiert.
Was mir noch einfällt: Ich weiss nicht, wie die Pins standardmässig
geschaltet sind, also ob als Ausgang oder als Eingang. Daher würde ich
vor der while()-Schleife sicherheitshalber den Pin mit der LED als
Ausgang schalten.
Bye
Daniel Jelkmann
@Daniel: Aua! Stimmt natürlich, habe ich aber auch nicht gesehen.
<schnarch> Aber egal, ob die Schleife nun wegoptimiert oder sowieso
nicht ausgeführt wird, warum blinkt die LED dann mit so einer niedrigen
Frequenz? Soooooooooooooooooooooo langsam kann C gegenüber ASM doch nun
wirklich nicht sein. ;-)
Gruß, Frank
Guten Morgen!
Danke euch für eure Mühe!
Ich hab nun noch nen Ansatz. Ich hab versucht das über ein
"Unterprogramm" zu lösen.
while(1){
if (PORTA = 0x01)
{ PORTA = 0x00;
pause();
}
else
{ PORTA = 0x01;
pause();
}
}
}
void pause (void)
{
unsigned char i;
for (i=0;i>=32667;i++);
}
Kann mir einer von euch sagen wie ich die for-Schleife verschachteln
kann, so das ich doppelte oder dreifache oder x-fache Zeit raus
bekommen?
Benutze nach wie vor den ATmega128 von Atmel!
Gruß
Carsten
deine Abbruchbedingung ist wieder falsch :-)
Und was ist mit dem watchdog? Wenn dein 1. Programm geblinkt hat, ist
eigentlich die einzige Erklärung ein watchdogreset.
Schleifenzeit erhöhen ist keine grosse Sache, du kannst den Prozessor
innerhalb der Schleife mit irgendwas beschäfigen, jeder Behehl kostet
Zeit. Alternativ keine Int, sondern eine long-Variable verwenden.
Der bessere Weg wäre, einen Timer einzusetzen.
z.B. Timer0, erzeugt jede 1ms einen Timerinterrupt (Timer mit passendem
Vorteiler im CTC-Modus starten, passenden Wert ins OCR-Register
schreiben, in der ISR zählst du nur eine globale Variable hoch.)
im Hauptprogramm kannst du die Variable abfragen und somit definierte
Verzögerungen erzeugen.
Hi nochmal...
Ich war gestern wohl halb blind ;)
if (PORTA = 0x01)
geht so nicht. Erstens ist das keine Abfrage auf Gleichheit, sondern
eine simple Zuweisung. Vom Sinn her war wohl eher PORTA == 0x01
gemeint.
Und zweitens geht das mit der Abfrage von PORTA nicht auf diese Weise,
wenn ich nicht irre. Ich würde mir da ne Variable nehmen, deren Zustand
sich abwechselnd von 1 auf 0 bzw von 0 auf 1 ändert und damit den Wert
der LED am Port wiederspiegelt.
DDRA = 0xFF; // alle Pins als Ausgänge schalten
int toggle = 0;
while(1)
{
if (toggle)
{
PORTA = 0x00;
toggle = 0;
}
else
{
PORTA = 0x01;
toggle = 1;
}
pause();
}
Hab das jetzt nicht probiert sondern einfach mal runtergeschrieben, ich
hoffe das läuft so ;)
Zum Thema Pause: es dürfte doch genug Delay-Routinen geben, die im Netz
rumschwirren oder sogar mit dem Compiler mitgeliefert werden. Warum das
Rad immer neu erfinden?
Bye
Daniel Jelkmann