Guten Tag,
Ich fange gerade an meine ersten Schritte mit Mikrocontrollern zu wagen.
Für diese ersten Versuche habe ich mir einen ATMEGA8535 zugelegt.
Nun habe ich versucht den internen Zähler zu benutzen um mir die
vergangene Zeit auf einem Port per LEDs anzeigenzu lassen. Idee war den
so lange zählen zu lassen bis eine Sekunde rum ist und ihn dann per
Interrupt das Register des Port D zu inkrementieren lassen.
Das Program habe ich mir aber nicht selber ausgedacht sondern es stammt
hier von der Seite aus dem GCC Tutorial.
Ich benutze AVR Studio 4.17 und einen AVRISP mkII. Sowohl beim
Simulieren, als auch auf dem Mikroncontroller funktioniert das Programm
aber nicht. Und ich bin Ratlos wieso.
Hier erstmal das programm:
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
volatile unsigned int millisekunden=0;
volatile unsigned int sekunde=0;
volatile unsigned int minute=0;
volatile unsigned int stunde=0;
main ()
{
DDRD=0xFF;
TCCR0 =(1<<WGM01) |(1<<CS01);
OCR0=125;
TIMSK|=(1<<OCIE0);
sei();
while(1){
PORTD=sekunde;
}
}
ISR (TIMER0_COMP_vect)
{
millisekunden++;
if(millisekunden==1000)
{
sekunde++;
millisekunden=0;
if(sekunde==60)
{
minute++;
sekunde=0;
}
if(minute ==60)
{
stunde++;
minute=0;
}
}
}
Ich habe beim Simulieren entdeckt, das am Anfang das Register OCR0 nicht
geschrieben wird, aber später wird das Register ja mit dem Counter
verglichen, ergo springt er nie in die Interruptroutine. Aber ich bin
mit meinem bischen Latein am Ende wo es hier hängt.
Grüße Björn
Mmm. Bei mir (AvrSTudio16Build628, WinAvr09032009) funktioniert das
Programm im Simulator 1. Bei 1Mhz Takt wird ein Breakpoint, der in der
Zeile
1
sekunde++;
liegt, alle 1008ms aufgerufen. Wenn du die Zeile
1
OCR0=125;
zu
1
OCR0=124;
ändern würdest dann hättest du auch exakt 1000ms.
Dein Problem muss irgendwo anders sein. Hast du in den Projektoptionen
alles richtig eingestellt? Die Kommandozeile beim Compilieren müsste
etwa so aussehen:
Danke erstmal deine Vermutung war richtig, ich hatte den Takt nicht in
den Projektoptioinen eingestellt :)
Allerdings läuft das Programm immer noch nicht.
Beim Debugging ist mir aufgefallen, das das OCIE0 Bit im TIMSK Register
nicht gesetzt wird, also springt er ja nicht in die Interrupt Routine.
Der Zähler funktioniert jetzt richtig, er zählt hoch bis 124 und bricht
dann ab, bzw beginnt von neuem Hochzuzählen. Allerdings wird die ISR nie
aufgerufen. Das verstehe ich nicht, laut anweisungen soll er das Bit ja
setzten, nur warum tut er es bei mir nicht?
Und bei Compilieren erhalte ich jetzt folgende Meldung:
c12 meint das Zeile 12 im Original c-code, oder bezieht sich das bereits
auf das compilierte?
Und was für auswirkungen hat dieses Warnung, ich habe den verdacht, dass
das vllt Teil des Problems sein könnte.
Gruß Björn
Björn Gustäbel schrieb:
>> c12 meint das Zeile 12 im Original c-code, oder bezieht sich das bereits> auf das compilierte?
Das wäre ziemlich sinnlos.
Die Zeilennummer bezieht sich auf den Code, so wie du ihn geschrieben
hast.
> Und was für auswirkungen hat dieses Warnung, ich habe den verdacht, dass> das vllt Teil des Problems sein könnte.
Es geht um main()
1
main()
2
{
3
...
4
}
Auch main ist aus C-Sicht nichts anderes als eine Funktion. So wie jede
andere Funktion auch, hat auch main() einen Returntyp. Gibst du nichts
an, dann greifen die C-Default Regeln, welche vorschreiben, das der
Returntyp einer Funktion int ist. Das kann richtig sein, kann aber auch
völlig falsch sein. Daher warnt dich der Compiler.
In deinem Fall ist es das Richtige. Trotzdem ist es besser, wenn du dich
nicht auf Default-Regeln verlässt, sondern die Dinge beim Namen nennst
Danke sehr euch allen, jetzt habe ich keine Warnung mehr, und das
Programm läuft, anscheinend hat er sich daran, dass ich nur main()
geschrieben habe so sehr gestört, dass er das TIMSK Register nicht
gesetzt hat. Warum auch immer :)
Jetzt funktioniert alles
Besten Dank
Björn Gustäbel schrieb:
> Danke sehr euch allen, jetzt habe ich keine Warnung mehr, und das> Programm läuft, anscheinend hat er sich daran, dass ich nur main()> geschrieben habe so sehr gestört, dass er das TIMSK Register nicht> gesetzt hat. Warum auch immer :)
Das kann nicht sein.
Dem Debugger ist es egal, ob du beim Compilieren Warnungen hast oder
nicht. Der simuliert den Code, so wie ihn der Compiler erzeugt. Und auch
bei mir läuft der Simulator völlig korrekt durch. Selbst wenn die
Warnung da ist.
Dann haben heute Nacht irgendwelche Heinzelmännchen meinen Code
Repariert, weil ich habe da nichts weiter geändert, außer main() zu int
main (void), achja und den Takt habe ich in den Projektoptionen
eingestellt, das waren die Unterschiede zu gestern Abend.
Nachdem ich den Takt einstellte lief das Programm immer noch nicht, erst
als ich die änderung an der main vornahm lief das Programm durch.
Vllt liegts ja auch daran, dass ich AVR Studio 4.17 verwende, das stammt
ja von der Beta Seite aus Norwegen.
Björn Gustäbel schrieb:
> Dann haben heute Nacht irgendwelche Heinzelmännchen meinen Code> Repariert, weil ich habe da nichts weiter geändert, außer main() zu int> main (void), achja und den Takt habe ich in den Projektoptionen> eingestellt, das waren die Unterschiede zu gestern Abend.>> Nachdem ich den Takt einstellte lief das Programm immer noch nicht, erst> als ich die änderung an der main vornahm lief das Programm durch.>> Vllt liegts ja auch daran, dass ich AVR Studio 4.17 verwende, das stammt> ja von der Beta Seite aus Norwegen.
Ich habe 4.13
Und ja, höchstwahrscheinlich gab es noch eine Änderung:
Du hast den Rechner rebootet oder zumindest deine Entwicklungsumgebung
neu gestartet.
Lach jetzt nicht. Manchmal verklemmt sich tatsächlich der
Make-Mechanismus und dann werden notwendige Updates nicht gemacht.
Sollte nicht vorkommen, kommt aber in jeder Entwicklungsumgebung
manchmal vor. Zb. Microsofts Dev-Studio war zumindest früher berühmt
dafür, dass ein komplettes Löschen der Generierverzeichnisse so manchen
seltsamen/unerklärlichen Fehler behoben hat.