Forum: Mikrocontroller und Digitale Elektronik ATtiny4313: 16 Bit Timer/Interrupt jede s erzeugen


von Andi K (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich bin relativ neu hier und hab noch nicht sooo viel Ahnung von MCUs.
Ich versuche eine einfache Binäruhr mit dem Attiny zu basteln. Dazu habe 
ich folgenden Code geschrieben um den entsprechenden Timer einzustellen:
1
  TCCR1B = (1<<CS12|1<<WGM12);
2
  OCR1A = 15625-1;
3
  TIMSK = 1<<OCIE1A;
4
  sei();
die ISR schaut so aus:
1
ISR(TIMER1_COMPA_vect)
2
{
3
  seconds++;
4
        usw.
5
}
Der Tiny hängt an einem 4MHz quarz und Fuses habe ich sowie auf dem Bild 
gesetzt.
Nun zum eigentlichen Problem. Der INterrupt kommt nicht annährend im 
sekundentakt. Es vergehen mindestens 3-5s bis der MCU schaltet.
Woran liegt das was ist da los?
Ich habe einen ähnlichen code mit meinem ATMega8 getestet mit dem 
unterschied, dass ich in der ISR eine LED ein und ausschalte aber dort 
ist das schon eher ein sekundentakt (auch 4mhz quarz)

Den kompletten sourcecode gibt es hier unten (damit es oben 
übersichtlicher bleibt):
1
#define F_CPU  4000000UL
2
#include <util/delay.h>
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
6
/*Global Variables Declarations*/
7
unsigned char hours = 0;
8
unsigned char minutes = 0;
9
unsigned char seconds = 0;
10
11
void refreshDisplay(void)
12
{
13
  PORTD = hours+96;
14
  PORTB = seconds;
15
}
16
17
ISR(TIMER1_COMPA_vect)
18
{
19
  seconds++;
20
   
21
  if(seconds == 60)
22
  {
23
    seconds = 0;
24
    minutes++;
25
  }
26
  if(minutes == 60)
27
  {
28
    minutes = 0;
29
    hours++;  
30
  }
31
  if(hours > 23)
32
    hours = 0;
33
}
34
35
int main(void)
36
{
37
  int Pressed = 0;
38
  int Pressed_Confidence_Level = 0; //Measure button press cofidence
39
  int Released_Confidence_Level = 0; //Measure button release confidence
40
  DDRB = 0xff;
41
  DDRD = 0x1f;
42
  
43
  DDRD &= ~(1 << PIND6);
44
  PORTD |= 1 << PIND6;
45
  DDRD &= ~(1 << PIND5);
46
  PORTD |= 1 << PIND5;
47
48
  TCCR1B = (1<<CS12|1<<WGM12);
49
  OCR1A = 15625-1;
50
  
51
  TIMSK = 1<<OCIE1A;
52
  
53
  sei();
54
   
55
   
56
  while(1)
57
  {  
58
    if (bit_is_clear(PIND, 5))
59
    {
60
      Pressed_Confidence_Level ++;
61
      Released_Confidence_Level = 0;
62
      if (Pressed_Confidence_Level >500)
63
      {
64
        if (Pressed == 0)
65
        {
66
          minutes++;
67
          seconds = 0;
68
          if(minutes == 60)
69
          {
70
            minutes = 0;
71
            hours++;  
72
          }
73
          refreshDisplay();
74
          Pressed = 1;
75
        }
76
        Pressed_Confidence_Level = 0;
77
      }
78
    }
79
    else if (bit_is_clear(PIND, 6))
80
    {
81
      Pressed_Confidence_Level ++;
82
      Released_Confidence_Level = 0;
83
      if (Pressed_Confidence_Level >500)
84
      {
85
        if (Pressed == 0)
86
        {
87
          hours++;
88
          if(hours > 23)
89
            hours = 0;
90
          refreshDisplay();
91
          Pressed = 1;
92
        }
93
        Pressed_Confidence_Level = 0;
94
      }
95
    }
96
    else
97
    {
98
      Released_Confidence_Level ++;
99
      Pressed_Confidence_Level = 0;
100
      if (Released_Confidence_Level >500)
101
      {
102
        Pressed = 0;
103
        Released_Confidence_Level = 0;
104
      }
105
    }
106
    refreshDisplay();
107
  }
108
}

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Da aber deine CKDIV8 Fuse noch gesetzt ist, hast du keinen Systemtakt 
von 4Mhz, sonder nur 1/8 davon. Also 500kHz.

von Karl H. (kbuchegg)


Lesenswert?

da fehlen noch ein paar volatiles
1
volatile unsigned char hours = 0;
2
volatile unsigned char minutes = 0;
3
volatile unsigned char seconds = 0;

von Andi K (Gast)


Lesenswert?

Wow das ging fix. Danke!

Problem gelöst!

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.