Forum: Mikrocontroller und Digitale Elektronik LCD, timer, Problem


von al3ko (Gast)


Lesenswert?

Hi,
Ich taste mich gerade an Timer heran. Dazu verwende ich eine Atmega8 
Beschaltung mit einer LED (PB1), einem Taster (PB0) und einem LCD.

Jede Sekunde soll die Variable bla aktualisiert und auf dem LCD 
angezeigt werden. Beim Druecken vom Taster soll die Variable auf 0 
zurueckgesetzt werden.

Leider zaehlt das Display einfach weiter. Die Tastererkennung 
funktioniert einwandfrei, da die LED ein- bzw. ausgeschaltet wird. Ich 
verstehe nur nicht, weshalb das bla=0 nicht in die ISR uebernommen wird.

Kann mir wer meinen Fehler aufzeigen?

Danke.

Hier der Code:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include "lcd-routines.h"
4
#include <avr/interrupt.h>
5
#include <stdlib.h>
6
7
uint32_t bla;
8
char buffer[20];
9
10
/*
11
Makro for debouncing
12
*/
13
#define debounce( port, pin )                                         \
14
({                                                                    \
15
  static uint8_t flag = 0;     /* new variable on every macro usage */  \
16
  uint8_t i = 0;                                                      \
17
                                                                      \
18
  if( flag ){                  /* check for key release: */           \
19
    for(;;){                   /* loop ... */                         \
20
      if( !(port & 1<<pin) ){  /* ... until key pressed or ... */     \
21
        i = 0;                 /* 0 = bounce */                       \
22
        break;                                                        \
23
      }                                                               \
24
      _delay_us( 98 );         /* * 256 = 25ms */                     \
25
      if( --i == 0 ){          /* ... until key >25ms released */     \
26
        flag = 0;              /* clear press flag */                 \
27
        i = 0;                 /* 0 = key release debounced */        \
28
        break;                                                        \
29
      }                                                               \
30
    }                                                                 \
31
  }else{                       /* else check for key press: */        \
32
    for(;;){                   /* loop ... */                         \
33
      if( (port & 1<<pin) ){   /* ... until key released or ... */    \
34
        i = 0;                 /* 0 = bounce */                       \
35
        break;                                                        \
36
      }                                                               \
37
      _delay_us( 98 );         /* * 256 = 25ms */                     \
38
      if( --i == 0 ){          /* ... until key >25ms pressed */      \
39
        flag = 1;              /* set press flag */                   \
40
        i = 1;                 /* 1 = key press debounced */          \
41
        break;                                                        \
42
      }                                                               \
43
    }                                                                 \
44
  }                                                                   \
45
  i;                           /* return value of Macro */            \
46
})
47
48
49
int main(void)
50
{
51
  bla = 0;
52
  uint32_t FCPU = 1000000;
53
  uint32_t Prescaler = 64;
54
  uint8_t Timesec=1;
55
  OCR1A = ((FCPU/Prescaler)*Timesec)-1;        // 1 sekunde
56
  DDRB |= (1<<PB1);
57
  PORTB |= (1<<PB0);
58
  PORTD |= (1<<PD7);
59
  TCCR1B = 0x0B;        // 0b00001011
60
  TIMSK = 0x10;
61
  sei();
62
  lcd_init();
63
  lcd_string("Counter:");
64
  while(1)
65
  {
66
    if(debounce(PINB, PB0))
67
    {
68
      PORTB |= (1<<PB1);
69
      bla=0;
70
    }
71
    if(debounce(PIND, PD7))
72
    {
73
      PORTB &= ~(1<<PB1);
74
      bla=0;
75
    }
76
  }
77
}
78
79
ISR(TIMER1_COMPA_vect)
80
{
81
  itoa(bla,buffer,10);
82
  lcd_clear();
83
  lcd_string("Counter:");
84
  lcd_string(buffer);
85
  lcd_string("sek");
86
  bla++;
87
}

von Electronics'nStuff (Gast)


Lesenswert?

Musst es wohl als volatile deklarieren. Also "volatile uint32_t bla;"

Gruss

von al3ko (Gast)


Lesenswert?

Electronics'nStuff schrieb:
> Musst es wohl als volatile deklarieren. Also "volatile uint32_t bla;"
>
> Gruss

grml, funktioniert jetzt wunderbar. :D
danke.

Und hier stehts ja auch:
"Variablen, auf die sowohl innerhalb wie auch außerhalb einer 
Interruptserviceroutine zugegriffen wird (schreibend oder lesend), 
müssen (ähnlich wie Hardwareregister) mit dem Schlüsselwort volatile 
(flüchtig) versehen werden, damit der C-Compiler berücksichtigen kann, 
dass diese Variablen jederzeit (durch das Auftreten des Interrupts) 
gelesen oder geschrieben werden können. Ansonsten würde der C-Compiler 
das regelmäßige Abfragen oder Beschreiben dieser Variablen ggf. 
wegoptimieren, da er nicht damit rechnet, dass auf die Variable auch 
"ohne sein Zutun" zugegriffen wird."
http://www.mikrocontroller.net/articles/Interrupt#Volatile_Variablen

Wieder etwas dazu gelernt.

Gruss

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.