Forum: Compiler & IDEs timer0 overflow - anfängerproblem


von lukas (Gast)


Lesenswert?

Hallo leute,

hab ein problem, wahrscheinlich ein sehr banales, aber ich komme aleine 
einfach nicht weiter.

wäre super wenn mir jemand den nötigen denkanstoss geben könnte.

also:
ich möchte eigentlich nur den ausgang pd5 durch einen timer overflow 
interrupt gesteuert blinken lassen. erstmals ;) ...
später soll da natürlich mehr draus werden, aber wie soll ich 
weitermachen wenn ich daran schon scheitere....

hier mein code
1
#ifndef F_CPU
2
#warning "ACHTUNG!! F_CPU wird von mir auf 0.032MHz gesetzt"
3
#define F_CPU 32768
4
#endif
5
6
#include <avr/io.h>
7
#include <avr/interrupt.h>
8
#include <stdint.h>
9
10
11
volatile uint8_t my_global = 0;
12
13
void TIMER_Init( void );
14
15
ISR( TIMER0_OVF_vect ) {
16
  my_global++;
17
}
18
19
int main( void ) {
20
21
  TIMER_Init();
22
23
  DDRC = 0xFF;  //Ausgänge
24
  DDRD = 0xFF;  //Ausgänge
25
  DDRB = 0x00;  //Eingänge
26
  PORTB |= 0x03;  //PullUps
27
28
  sei();  
29
  
30
  while( 1 ) {
31
    if( my_global & 0x01 ) {
32
      PORTD |= 0b00100000;   //PD5 einschalten
33
    }
34
    else {
35
      PORTD &= 0b11011111;   //PD5 ausschalten
36
    }  
37
  }
38
  return 0;
39
}
40
41
void TIMER_Init( void ) {
42
  TCCR0 |= 0b00000101;  //Prescaler 1024
43
  TIMSK |= 0b00000001;  //Timer Overflow Interrupt Enabled
44
}

und danke an alle die es sich antun sich meines problems anzunehmen :)

lg lukas

von g457 (Gast)


Lesenswert?

> hab ein problem

..was für eins? Syntax oder Semantik? Und wie äussert sich selbiges? 
Oder sollen wir die Glaskugeln polieren?..

> #warning "ACHTUNG!! F_CPU wird von mir auf 0.032MHz gesetzt"

..und mit welchem Takt läuft der AVR tatsächlich?

> my_global & 0x01

sogar bei nur 33kHz und einem Vorteiler von 1024 wirds knapp mit 
"blinken" - wenn ich mich nicht verrechnet hab dann sollte die LED alle 
etwa 8 Sekunden wechseln.

> PORTD |= 0b00100000;   //PD5 einschalten
           ^^^^^^^^^^
..und sowas gewöhn Dir besser erst gar nicht an, das kann man viel 
schöner schreiben mit
1
PORTD |= _BV(5); //PD5 einschalten
Wenn man dann noch ein paar schöne sprechende Defines aussen rum 
definiert wirds sogar richtig hübsch:
1
#define FANCY_LED         5
2
#define FANCY_LED_PORT    PORTD
3
#define FANCY_LED_ON()    ( FANCY_LED_PORT |=  _BV(FANCY_LED) )
4
#define FANCY_LED_OFF()   ( FANCY_LED_PORT &= ~_BV(FANCY_LED) )
5
[..]
6
   if (my_global & 0x01)
7
      FANCY_LED_ON();
8
   else
9
      FANCY_LED_OFF();

HTH

von Tim (Gast)


Lesenswert?

Der Code sieht (vom schlechten Stiel mal abgesehen) richtig aus.
Ohne Angabe des AVR Typs und der Taktfrequenz ist eine weitere Diagnose 
unmöglich.
Kannst du eine Hardwarefehler ausschließen? Was hat du schon alles 
überprüft?

von lukas (Gast)


Lesenswert?

Also:

ich verwende einen ATmega8 mit einem externen quarz (32kHz).

sorry dass ihr euch durch meinen hässlichen stil quälen müsst ;)

das problem äussert sich darin dass die led nicht blinkt oder flakert 
sondern einfach nur stur durchleuchtet.

einen hw-defekt kann ich soweit ausschliessen,....

ich habe alle led´s ein und alle led´s aus schon probiert, was 
funktioniert!

wie könnte ich dass sonst noch testen?

dank euch!

lg

von MWS (Gast)


Lesenswert?

Wurden die Fuses auf Low Frequency Crytal Oscillator gesetzt ?

Aber Vorsicht ! ISP-Takt muss <= 1 / 4 uC-Takt sein. Wenn das Dein 
Programmer nicht kann, hast Du Dich danach selbst ausgesperrt.

von g457 (Gast)


Lesenswert?

> ich verwende einen ATmega8 mit einem externen quarz (32kHz).
[..]
> das problem äussert sich darin dass die led nicht blinkt oder flakert
> sondern einfach nur stur durchleuchtet.

Hast Du ∗überprüft∗ dass der Quarz auch korrekt genutzt wird? Geht (in 
unvollständigem und ungeprüftem Pseudocode) z.B. so
1
#include <util/delay.h>
2
[..]
3
#define FANCY_LED_DDR             DDRD
4
#define FANCY_LED_SET_OUTPUT()    ( FANCY_LED_DDR |=  _BV(FANCY_LED) )
5
[..]
6
int main()
7
{
8
    FANCY_LED_SET_OUTPUT();
9
    while (1)
10
    {
11
        FANCY_LED_ON();
12
        _delay_ms(1000);
13
        FANCY_LED_OFF();
14
        _delay_ms(1000);
15
    }
16
    return 0;
17
}
Wenn die LED nicht alle Sekunde ihren Zustand ändert ist was faul.

HTH

von Uwe (Gast)


Lesenswert?

Hört sich nach falschen Fuses für die Clock an.
probier mal
if( my_global & 0x80 )

von Karl H. (kbuchegg)


Lesenswert?

> ich verwende einen ATmega8 mit einem externen quarz (32kHz).

Gehts nur mir so, oder empfinden auch andere die Verwendung eines 32kHz 
Quarzes als Betriebsfrequenz für den Mega8 als unsinnig?

Das man den 32kHz Quarz als Antrieb für den Timer 2 benutzen kann, steht 
auf einem anderen Blatt. Als Taktfrequenz für den kompletten µC ist das 
in meinen Augen einfach nur Blödsinn.

von Dietmar (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Gehts nur mir so, oder empfinden auch andere die Verwendung eines 32kHz
> Quarzes als Betriebsfrequenz für den Mega8 als unsinnig?

Seh ich auch so.
Mein Ansatz wäre intern RC nehmen, Vorteiler entsprechend setzten und 
die LED damit blinken lassen. Weniger Bauteile und damit weniger 
Fehlermöglichkeiten.

von lukas (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Gehts nur mir so, oder empfinden auch andere die Verwendung eines 32kHz
> Quarzes als Betriebsfrequenz für den Mega8 als unsinnig?
>
> Das man den 32kHz Quarz als Antrieb für den Timer 2 benutzen kann, steht
> auf einem anderen Blatt. Als Taktfrequenz für den kompletten µC ist das
> in meinen Augen einfach nur Blödsinn.

das werd ich wahrscheinlich machen! an diese möglichkeit hab ich noch 
nicht gedacht,... und wahrscheinlich habe ich mich durch den zu 
niedrigen takt ausgesperrt grrrrrrr
ich verwende den myavr usb light programmer. hab aber keine ahnung wie 
weit runter der mit der isp-frequenz kann.

naja, werde dann mal einen anderen mega8 drauf setzen und ausprobieren.

vielen dank.

lg lukas

von MWS (Gast)


Lesenswert?

lukas schrieb:
> und wahrscheinlich habe ich mich durch den zu
> niedrigen takt ausgesperrt grrrrrrr

Ehm, ja, späte Erkenntnis. Mein Post erst nachher gelesen ?

von lukas (Gast)


Lesenswert?

MWS schrieb:
> lukas schrieb:
>> und wahrscheinlich habe ich mich durch den zu
>> niedrigen takt ausgesperrt grrrrrrr
>
> Ehm, ja, späte Erkenntnis. Mein Post erst nachher gelesen ?

OH, noch garnicht gelesen. :)

der interne rc ist für meine zwecke zu ungenau, aber danke trotzdem.

lg lukas

von MWS (Gast)


Lesenswert?

lukas schrieb:
> der interne rc ist für meine zwecke zu ungenau, aber danke trotzdem.

Bitte.

Hatte gestern sogar nachgesehen, ob man die Fuse per Hand reintakten 
könnte, sind nur 32 Bit :D
Ist aber ein bisserl zu abgedreht, außerdem hab' ich's selbst noch nie 
versucht. Würde außerdem einen prellfreien Taster zumindest für SCK 
erfordern.

Das hier und bei jedem Bit SCK auf L/H müsste ihn wieder auf internen 
R/C zurückstellen, MSB zuerst.
1
RST <- 0
2
        MSB                          LSB   
3
MOSI <- 10101100101000000000000011100001
4
RST <- 1

Den asynchronen Timer2 mit dem 32kHz Quarz zu verwenden wurde Dir 
bereits empfohlen, das wäre auch mein Rat gewesen. Es dürfte eine 
Application Note geben, um den internen R/C per OSCCAL mit dem 32kHz 
Quarz an Timer2 abzugleichen. Hatte das mal in 'nem Code für einen 
AVR-Butterfly gesehen.

von lukas (Gast)


Lesenswert?

das wäre ja mal was :D

naja, ich hab ihn schon ausgetauscht, (und einen sockel eingelötet, 
falls ich nochmals tauschen muss :) )

aber wenn mir meine mcu´s mal ausgehen dann werd ich ihn vll mit deiner 
methode retten.

so, hab das jetzt im schöneren stil nochmals geschrieben:
1
void TIMER_Init( void ) {
2
  ASSR |= (1<<AS2);    //Asynchrone Modus, tcnt-quelle=TOSC1/2
3
  _delay_ms(500);      //1/2sekunden Warten
4
  TCCR2 |= (1<<CS22);   //Prescaler 64 -> bei 32768Hz OVF alle 0,5sec
5
  TIMSK |= (1<<TOIE2);  //Timer2 Overflow Interrupt Enabled
6
}

sieht schon besser aus, oder?

danke an alle die mir geholfen haben!
es ist sehr erfreulich wie kompetent, schnell und freundlich dieses 
forum ist!

lg lukas

von MWS (Gast)


Lesenswert?

lukas schrieb:
> aber wenn mir meine mcu´s mal ausgehen dann werd ich ihn vll mit deiner
> methode retten.

Man könnte sich für diesen Zweck auch 'nen Tiny programmieren, der einen 
die Defaultfuses wieder reinschreibt und gleich noch 'nen Takt 
generiert, falls auf ext. Oszillator/Crystal ver-fust wurde. Nur bei der 
RSTDISBL würd' das auch nix mehr helfen, da muss dann HV-Programmierung 
ran.

lukas schrieb:
> ASSR |= (1<<AS2);

Ich würd' für das Erstbeschreiben eines Registers nicht ver-odern, denn 
bei einem Re-Init könnten sonst falsche Registerwerte drinbleiben, also 
besser:
> ASSR = (1<<AS2);

lukas schrieb:
> und freundlich dieses forum ist!

Nun, wie Du feststellen kannst, nicht immer ;D
Kommt sehr drauf an, wie gefragt wird.

von lukas (Gast)


Lesenswert?

MWS schrieb:
> Ich würd' für das Erstbeschreiben eines Registers nicht ver-odern, denn
> bei einem Re-Init könnten sonst falsche Registerwerte drinbleiben, also
> besser:
>> ASSR = (1<<AS2);

ok, vielen dank für den tip!

btw.: die binäruhr zählt jetzt schon fleißig nach oben :)

lg und schönen abend.
lukas

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.