Forum: Mikrocontroller und Digitale Elektronik Schon wieder ein Timerproblem.


von Christian T. (johannf)


Lesenswert?

Hallo Allerseits,
Ich weiß, es gibt schon viele Threads, trotzdem komme ich hier auch nach 
vielem stöbern und machen nicht weiter.

Mein Programm auf das Timerproblem reduziert:
1
#include <avr/io.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
volatile unsigned long millis;    
5
6
int main(void)
7
{
8
  PORTC |= ((1<<5)|(1<<4)|(1<<3));
9
  DDRC |= ((1<<5)|(1<<4)|(1<<3));  
10
  TCCR0A |= (1<<WGM01);
11
  TCCR0B |= (1<<CS01)|(1<<CS00);
12
  TIMSK0 |= (1<<OCIE0A);
13
  OCR0A = 125;
14
  sei();
15
  
16
    while (1) 
17
    {
18
    }
19
}
20
21
ISR(TIMER0_COMPA_vect)
22
{
23
  millis++;
24
  if(millis>1000)
25
  {
26
    cli();
27
    PORTC ^= ((1<<5)|(1<<4)|(1<<3));
28
    millis=0;
29
    sei();
30
  }
31
}

LED soll einfach nur Toggeln.
Mit WGM01 im TCCR0A Register setz ich laut Datenblatt den CTC-Mode.
Hab zwar nen Quarz dran hängen aber um Fehler auszuschließen hab ich den 
int. RC-Osz gesetzt. Ich will das der Timer ca jede ms die ISR auslöst.
8.000.000 Hz / Prescale(64) / Gewünschte Frequenz (1000Hz) = 125
Deshalb hab ich das Compare Register OCR0A auf 125 gesetzt.
Zähl ich jetzt die unsigned long variable millis auf 1000 hoch sollte 1s 
vergangen sein. Also die LEDs sollten mit 0,5Hz blinken.
Problem ist jetzt dass die LED ca 8s an bzw aus bleiben...

Hier nochmal die Fuses:
1
BODLEVEL = DISABLED
2
RSTDISBL = [ ]
3
DWEN = [ ]
4
SPIEN = [X]
5
WDTON = [ ]
6
EESAVE = [X]
7
BOOTSZ = 2048W_3800
8
BOOTRST = [ ]
9
CKDIV8 = [X]
10
CKOUT = [ ]
11
SUT_CKSEL = INTRCOSC_8MHZ_6CK_14CK_65MS
12
13
EXTENDED = 0xFF (valid)
14
HIGH = 0xD1 (valid)
15
LOW = 0x62 (valid)

Ich bin am Verzweifeln und hoffe mir kann hier einer weiter helfen....

--

Dieses Forum sieht Tags für das Formatieren von Quelltext vor. Nutze 
sie!

-rufus

: Bearbeitet durch User
von Loddaar (Gast)


Lesenswert?

Christian T. schrieb:
> cli();
>     PORTC ^= ((1<<5)|(1<<4)|(1<<3));
>     millis=0;
>     sei();

cli und sei haben in der Interruptroutine nichts verloren,
das wird automatisch gemacht

von Christian T. (johannf)


Lesenswert?

Loddaar schrieb:
> Christian T. schrieb:
>> cli();
>>     PORTC ^= ((1<<5)|(1<<4)|(1<<3));
>>     millis=0;
>>     sei();
>
> cli und sei haben in der Interruptroutine nichts verloren,
> das wird automatisch gemacht

Hallo,
Danke für die Antwort, ändert aber nichts. Das war einer meiner Versuche 
dem Problem auf den Grund zu gehen. Von wegen Toggle und Atomar usw.

von Klaus (Gast)


Lesenswert?

CKDIV8

von Christian T. (johannf)


Lesenswert?

Und das war ein ganzer Tag Probieren?
.... Wer setzt denn sowas auf default 1....
Vielen vielen Dank. Schon geht alles!

von Carl D. (jcw2)


Lesenswert?

> dem Problem auf den Grund zu gehen. Von wegen Toggle und Atomar usw.

Das passiert aber doch in der ISR. Und so wie die definiert ist, sperrt 
sie weitere Interrupt, so sie denn auftreten könnten, bis diese per 
sei() wieder freigeben werden, oder eben bis zu ihrem (ISR) Ende.
Atomar ist damit nicht gefragt.

Welche AVR ist das? Nicht zufällig ein 40Pinner, der auf PC2..5 JTAG 
liegen hat?

von Christian T. (johannf)


Lesenswert?

Carl D. schrieb:
>> dem Problem auf den Grund zu gehen. Von wegen Toggle und Atomar usw.
>
> Das passiert aber doch in der ISR. Und so wie die definiert ist, sperrt
> sie weitere Interrupt, so sie denn auftreten könnten, bis diese per
> sei() wieder freigeben werden, oder eben bis zu ihrem (ISR) Ende.
> Atomar ist damit nicht gefragt.
>
> Welche AVR ist das? Nicht zufällig ein 40Pinner, der auf PC2..5 JTAG
> liegen hat?

Also alles hatte damit angefangen das ich mein großes Programm auf nem 
ATMega8535 geschrieben habe (da läufts auch ohne Probleme) und an die 
8kb Programmcode gestoßen bin. Dann dachte ich mir ich kann von nem 40 
auf nen 32 switchen weil ichs sowieso nicht brauche und hab mir den 
ATMega328p gekauft. Diesen mit ein paar Registern an den Timern und dem 
UART angepasst hat eben auf einmal nichts mehr gemacht. Und weil das 
eben das erste größere Projekt seit vielen Jahren ist und ich wieder von 
Grund auf neu angefangen hab gings nach dem ganzen Morgen testen 
irgendwann gegen Mittag ans "wilde" Probieren....
Ich dachte nicht das sich da auch bei den Fuses so viel geändert hat. 
Bei den anderen älteren Atmegas hab ich auch nie dieses DIV8 wegnehmen 
müssen. Ich hoffe doch das ich nicht auf noch mehr solcher Probleme 
stoße.
Muss ich denn bei dem JTAG Pins auch noch was ändern? Letztendlich 
sollen das alles Ausgänge werden auf denen ich via PWM Leds ansteuere.

von Carl D. (jcw2)


Lesenswert?

JTAG ist raus, das hat der Mega328 nicht.

Der ATmega368p war auch im Projekt/Makefile angegeben? Der hat nämlich 
(potentiell) andere Interrupt-Vektor-/IO-Adresse als der 8535.
 Beide Hexfiles wären natürlich ohne Probleme in beide μC's ladbar, da 
beide 32k Flash haben. Nur funktionieren würde nichts.

von Christian T. (johannf)


Lesenswert?

Hallo,
Hab jetzt ein bisschen getestet.
Timer 0 und 2 funktionieren auch im großen Programm einwandfrei. Nur der 
UART RX geht noch nicht ganz.
Aber das schau ich mir morgen nochmal an und stell dann im Zweifelsfall 
weitere Fragen :-)

Danke euch nochmal für die schnelle Hilfe!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.