LCD, timer, Problem

Gast #2879353
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
}
Gast #2879371
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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.