PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Timer hängt sich auf?



Ineedhelp
22.08.2008, 14:09
Hi

ich beschäftige mich mit dem Timer des Tiny2313.
In meinem code versuche ich genau jede sekunde die Ausgänge des Port B auf high und in der nächsten wieder auf low zu setzten.

Ich will das mit dem Timer (soll auch möglichst genau sein) machen (nicht sleep oder so). Der code compiliert fehlerfrei, allerdings bleibt er nach dem 1 durchgang beim Debuggen stehen.

Habe ich was übersehen oder was ist los?
Benutze ich den Timer überhaupt richtig? (habe mir das nur im tutorial auf mikrocontroller.net angesehen und extra bei keinem anderen projekt abgeschaut)



#define F_CPU 4096000

#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <stdint.h>

int16_t timer=0;
int8_t status=0;


void initTimer(void)
{
TCCR0B |= (1<<CS00)|(1<<CS02);
}

void initInterrupts(void)
{
sei();
}

ISR(TIMER1_OVF_vect)
{
timer=timer+1;
}

int main (void)
{
initTimer();
initInterrupts();
DDRB = 0xff;

while(1)
{
if(timer>=4000) //hier bleibt der Debugger erst beim 2ten durchgang der schleife stehen
{
timer=0;
if(status==0)
{
PORTB = 0xff;
status=1;
}
else
{
PORTB = 0x00;
status=0;
}
}

}
return 0;
}


Vielleicht sehe ich auch den wald vor bäumen einfach nicht
wäre nett, wenn sich das jemand anschaut
danke

fhs
22.08.2008, 14:19
Hi,

da Du in TIMSK kein Bit gesetzt hast, kommt es nie zu einem Timer-Overflow-Interrupt.

"Die genaue Sekunde". (http://www.mikrocontroller.net/articles/AVR_-_Die_genaue_Sekunde_/_RTC)

Gruß

Fred

McJenso
22.08.2008, 14:53
Hallo,


TCCR0B |= (1<<CS00)|(1<<CS02);
...
ISR(TIMER1_OVF_vect)


Welchen Timer benutzt du nochmal? :wink:

Gruß

Jens

Ineedhelp
22.08.2008, 15:11
hi
danke erstmal

beide fehler behoben
neuer code:


#define F_CPU 4096000

#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <stdint.h>

int16_t timer=0;
int8_t status=0;


void initTimer(void)
{
TCCR0B |= (1<<CS00)|(1<<CS02);
TCNT0 = 0;
TIMSK |= (1<<TOIE0);
}

void initInterrupts(void)
{
sei();
}

ISR(TIMER0_OVF_vect)
{
timer=timer+1;
}

int main (void)
{
initTimer();
initInterrupts();
DDRB = 0xff;

while(1)
{
if(timer>=4000)
{
timer=0;
if(status==0)
{
PORTB = 0xff;
status=1;
}
else
{
PORTB = 0x00;
status=0;
}
}

}
return 0;
}



leider läuft der debugger nun die ganze zeit durch die interrupt funktion und setzt auch nicht den port bei einem timer größer als 4000 um (arbeitet die if funktion nicht ab).

brauche also nochmal hilfe ;-)

fhs
22.08.2008, 15:18
Hi,

<pre>volatile int16_t timer=0; </pre>

MfG

Fred

Ineedhelp
22.08.2008, 15:28
stimmt

allerdings bleibt er bei der if abfrage hängen

if(timer>=4000)

ich habe auch den wert 4000 mal tiefer angesetzt, daran liegt es aber auch nicht

fhs
22.08.2008, 15:41
Hi,

"timer" ist immer noch nicht "volatile"!

Gruß

Fred

Ineedhelp
22.08.2008, 15:55
verstehe ich jetzt nicht




#define F_CPU 4096000

#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <stdint.h>

volatile int16_t timer=0;
volatile int8_t status=0;


void initTimer(void)
{
TCCR0B |= (1<<CS00)|(1<<CS02);
TCNT0 = 0;
TIMSK |= (1<<TOIE0);
}

void initInterrupts(void)
{
sei();
}

ISR(TIMER0_OVF_vect)
{
timer=timer+1;
}

int main (void)
{
initTimer();
initInterrupts();
DDRB = 0xff;

while(1)
{
if(timer>=4)
{
timer=0;
if(status==0)
{
PORTB = 0xff;
status=1;
}
else
{
PORTB = 0x00;
status=0;
}
}

}
return 0;
}

fhs
22.08.2008, 15:58
Hallo,

Deine jetzige Version läuft bei mir im Simulator problemlos. Wenn ich "timer" auf 3 und einen Breakpoint in der ISR setze, springt der Inhalt von "timer" beim nächsten Durchlauf wieder auf 0. Dein Code funktioniert also wie gewünscht! "status" muss nicht "volatile" sein.

Gruß

Fred

Ineedhelp
22.08.2008, 16:08
mhm
beii mir setzt er den auf PORTB = 0xff;

aber danach passiert nix mehr

welche simulationssoftware verwendest du?

fhs
22.08.2008, 16:22
Hallo,


welche simulationssoftware verwendest du?
AVRStudio v.4.14 Build 589 unter XP-SP2. Darunter geht PORTB auch wieder auf 0, wenn zum 2. Mail "timer==4" eintritt.

MfG

Fred

Ineedhelp
22.08.2008, 16:56
okay, benutze die 4.13

irgendwas stimmt aber nciht
ich habe den code mal abgeändert
es kommt nie vor, dass status = 1 wird, weil sich bei meiner simulation beim port D nichts tut



#define F_CPU 4096000

#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <stdint.h>

volatile int16_t timer=0;
volatile int8_t status=0;


void initTimer(void)
{
TCCR0B |= (1<<CS00)|(1<<CS02);
TCNT0 = 1;
TIMSK |= (1<<TOIE0);
}

void initInterrupts(void)
{
sei();
}

ISR(TIMER0_OVF_vect)
{
timer=timer+1;

}

int main (void)
{
initTimer();
initInterrupts();
DDRB = 0xff;

while(1)
{
if(timer>=4)
{
timer=0;
if(status==0)
{
PORTB = 0xff;
status=1;
}
if(status==1)
{
PORTB = 0x00;
DDRD = 0xff;
PORTD = 0xff;
status=0;
}
}
}
return 0;
}



danke für deine hilfe
ich weiß, es nervt ein bisschen ;-)

fhs
22.08.2008, 17:10
Hallo,

bei Deiner Vorversion wird "status==1", wie in den folgenden Bildern zu sehen ist. Deiner neueste Version läuft bei mir auch; status wird 1 und PORTD=0xff.

Gruß

Fred

Ineedhelp
22.08.2008, 17:21
okay
du hast mich überzeugt
werde mal meine version updaten

dankeschön für deine hilfe

Ineedhelp
22.08.2008, 17:32
jetzt geht es bei mir auch
habe nicht mit breakpoints gearbeitet
sonder nur schrittweise

danke nochmal
wieder was gelernt

fhs
22.08.2008, 17:49
Schön, dass es jetzt klappt! Wollte gerade schreiben, dass das Problem sicher nicht beim AVRStudio v.3.13 liegt, sondern eine andere Ursache haben muss. Ohne Breakpoints kannst Du im Einzelschrittmodus oft nur im Assembler-Listing (View|Disassembler) verfolgen, was gerade passiert.

Gruß

Fred