Hallo zusammen!
Ich habe in den letzten Tagen eine Platine mit einem ATmega64 gebaut.
Anstelle des externen Quarz wird der interen 1Mhz Oszillator (4ms)
verwendet, d.h. die XTAL1/2 Anschlüsse hängen in der Luft. CkOPT ist
unprogrammiert.
Mein Ziel: Ein LCD Display ansteuern, wobei dabei "_delay_ms()"
verwendet wird.
Problem: Mein Prozessor scheint sich aufzuhängen, wenn ich die
delay-Funktion aufrufe.
Ich habe alternativ als eine Art "Debug-Hardware-Ausgabe" folgendes
versucht:
Wenn ich den PORTD |= 0xF0 (DDRD = 0xF0) nach dem Aufruf von delay setze
und eine LED dran packe, dann leuchtet die Led umso weniger hell je
höher ich den Wert für _delay_ms() setze.
Somit: _delay_ms(1ms);
PORTD |= 0xF0; led leuchtet hell
_delay_ms(5ms);
PORTD |= 0xF0; led leuchtet fast nicht mehr, aber sie leuchtet
noch
-> Die Spannung für "high" nimmt am ganzen Port ab...
Weiterer Versuch:
Anstelle des anscheinend nicht funktionierenden delay-Befehls habe ich
dann den Timer0 verwendet und eine eigene "wait_ms" Funktion
geschrieben.
Dabei wird der CTC-Modus verwendet und der Interrupt mit ISR gefangen.
Jeder Interrupt sorgt für eine Erhöhung der timer_counter Variable.
Da der Timer alle 1ms etwa einen Interrupt erzeugt, warte ich einfach in
der wait_ms-Funktion mit "while(timer_counter < 1)" und zähle so die
Anzahl der Milisekunden (Variable i).
Problem: Wie bei _delay_ms() setze ich den PORTD = 0x00, danach wird ein
wait_ms(x) aufgerufen und PORTD |= 0xF0 (DDRB = 0xF0) gesetzt. Je höher
ich x (= ms) setze, desto weniger leuchtet meine LED am PORTD ...
Vielleicht findet jemand im Code einen Fehler. Wenn nicht gibts
vielleicht sonstige Tips!!
Als Programm verwende ich AVR Studio 5.1 und ich habe folgenden Code
programmiert:
Mounty schrieb:> Wenn ich den PORTD |= 0xF0 (DDRD = 0xF0) nach dem Aufruf von delay setze> und eine LED dran packe, dann leuchtet die Led umso weniger hell je> höher ich den Wert für _delay_ms() setze.> Somit: _delay_ms(1ms);> PORTD |= 0xF0; led leuchtet hell> _delay_ms(5ms);> PORTD |= 0xF0; led leuchtet fast nicht mehr, aber sie leuchtet> noch> -> Die Spannung für "high" nimmt am ganzen Port ab...>> Weiterer Versuch:>> Anstelle des anscheinend nicht funktionierenden delay-Befehls habe ich> dann den Timer0 verwendet und eine eigene "wait_ms" Funktion> wait_ms(x) aufgerufen und PORTD |= 0xF0 (DDRB = 0xF0) gesetzt. Je höher> ich x (= ms) setze, desto weniger leuchtet meine LED am PORTD ...
Du hast also auf 2 unterschiedlichen Wegen dieselben Symptome. Wie
kommst du dann zum Schluss, dass _delay_ms nicht funktioniert?
Wenn du das abklären willst, dann wirf alles raus, was nicht mit den
Ports bzw LED zu tun hat und überzeug dich davon, dass _delay_ms
tadellos funktioniert
int main()
{
Led Port auf Ausgang
while( 1 )
{
Led einschalten
_delay_ms( 1000 );
Led aussschalten
_delay_ms( 1000 );
}
}
Erst wenn das nicht funktioniert, bist du in der gesicherten Lage eine
Aussage über ein Nicht-funktionieren von _delay_ms zu geben.
Folgender Code liefert weder en Blinken noch sonstwas...
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 1000000UL
int main(void)
{
while(1)
{
_delay_ms( 1000 );
PORTD |= 0x78;
_delay_ms( 1000 );
PORTD &= 0x87;
}
return 0;
}
Stelle ich allerdings beide Delay-Zeiten auf 100ms: LEDs leuchten
durchgehend ganz schwach
10ms: mittel, 1ms: Leds leuchten stärker... da soll sich wer auskennen?
Peter Dannegger schrieb:> M103 Fuse
Der M64 hat eine M103 Fuse?
Ich dachte, die hätte nur der M128.
Wieder was gelernt.
(Den Typen, der sich den Quatsch ausgedacht hat, das diese Fuse per
Default eingeschaltet ist, dem würde ich auch gerne mal in die ....
treten)
Karl Heinz Buchegger schrieb:> Peter Dannegger schrieb:>> M103 Fuse>> Der M64 hat eine M103 Fuse?
Ja, das ist gewissermaßen nur ein runterskalierter ATmega128.
> (Den Typen, der sich den Quatsch ausgedacht hat, das diese Fuse per> Default eingeschaltet ist, dem würde ich auch gerne mal in die ....> treten)
Vermutlich gab's da einen volume-Kunden, der bis dato ATmega103
verbaut hatte, und dem man daher den ATmega128 als Upgrade-Typ so
schmackhaft wie nur möglich verkaufen wollte, um den '103 aus dem
Programm streichen zu können.
Jörg Wunsch schrieb:> Kein Wunder, wenn du keinen Ausgang aktivierst, sondern nur die> Pullups.
Sorry, etwas beim Kopieren vergessen... folgende Zeile fehlt nicht im
Code von oben:
DDRD = 0x78; // vor dem while(1)
Hab das Problem näher eingeschränkt:
Das Problem muss irgendwie mit dem Interrupt / ISR zusammenhängen.
Wenn ich wait_ms(1) aufrufe kann ich danach meine Ausgänge auf "low"
setzen (= 0.3V) ... wenn ich allerdings wait_ms(2) aufrufe, dann wird
die "low" spannung etwa 1V.
Die Ausgänge werden jeweils nach dem wait_ms() mit DDRx = 0xF0, PORTx =
0x00; gesetzt.
Weiß einer warum die Spannung raufgeht?
Mounty schrieb:> Das Problem muss irgendwie mit dem Interrupt / ISR zusammenhängen.
Mit welchem? In deinem Minimalbeispiel hast du doch gar keinen drin.
Oder hast du auch nur wieder vergessen, uns den mit zu kopieren?
Bitte poste uns exakt den Code, den du auch benutzt, und am besten
noch die Compiler-Kommandozeile dazu.
Und äußere dich bitte mal zur M103C-Fuse. Ich kann in keinem deiner
Beiträge eine Bestätigung dazu sehen, dass du diesen Hinweis von Peter
überhaupt zur Kenntnis genommen, geschweige denn überprüft hast.
Mounty schrieb:> Weiß einer warum die Spannung raufgeht?
Klare Aussage:
Dein Problem ist erst mal die M103 Fuse!
Die scheint immer noch gesetzt zu sein, wodurch es beim ersten
Funktionsaufruf zu einem Prozessorreset kommt!
Solange du die nicht ausgeschaltet hast, brauchst du nicht weitermachen.