timer problem atmega8

OP #2494461
Hallo Programmierer,

ich habe folgendes Problem. Es soll aus der main() eine Art 
Atemzugsgenerator aufgerufen werden, dessen Frequenz und Wiederholungen 
einstellbar ist.
Es wird ein Atmega8 mit 3.686400MHz verwendet.
Im nachfolgenden Code findet die Abarbeitung der zeitlichen Reihenfolge 
in der ISR statt, bis zu 27 Atemzüge pro Minute klappt das auch 
hervorragend. Aber ab dieser Frequenz leuchtet die LED entweder 
dauerhaft oder gar nicht.
Ich denke es könnte an der Berechnung liegen (klar, int ist nicht 
ganzzahlig).
Habt ihr einen Tip wonach ich suchen kann, eventuell ist ja auch mit den 
Timersettings etwas falsch.

Vielen Dank schon mal,
WastlB
1
#include <stdlib.h>
2
#include <stdio.h>
3
#include <avr\io.h>
4
#include <avr\interrupt.h>
5

6
volatile int exsp=0,insp=0,act=0,state=0,max=0;
7
volatile int timer;
8

9
ISR(TIMER1_OVF_vect)
10
{              
11
timer++;
12
  
13
    if(state==1)
14
    {
15
      if(timer<<insp)
16
      {
17
      PORTC |= (1<<0);
18
      }
19
      if((timer<<exsp) && (timer>=insp))
20
      {
21
      PORTC &= ~(1<<0);
22
      }
23
      if(timer==exsp)
24
      {
25
      act++;
26
      timer=0;
27
        if(act==max)
28
        {
29
        state=2;
30
        }  
31
      }
32
    }
33
}
34

35
void init_timer()
36
  {
37
    TCCR1A |= (0 << WGM11) | (1 << WGM10);
38
    TCCR1B |= (1 << WGM13) | (0 << WGM12);
39
    TCCR1B |= (1 << CS12)  | (0 << CS11)  | (1 << CS10);
40
    TIMSK |= (1<<TOIE1);
41
  OCR1A = 1;
42
  }
43

44
void init_front()
45
  {
46
  DDRC |= (1<<0)|(1<<1);
47
  PORTC |= (0<<0)|(0<<1);
48
  DDRB |= (0<<0)|(0<<1)|(0<<2);
49
  }
50

51
void calc_vent(int cyc,int ventf)
52
{
53
max=cyc;
54
exsp = (60000/ventf);
55
insp = exsp/3;    
56

57
}
58

59
int main(void)
60
{
61
  init_timer();
62
  init_front();
63
  sei();
64

65
  for(;;)
66
  {
67
      if(state==0)
68
      {
69
      calc_vent(5,27);
70
      state=1;
71
      }
72
  }
73

74
}
#2494546
Bist du sicher, dass das hier

      if(timer<<insp)

tatsächlich ein Links-Schieben sein soll und kein Vergleich auf kleiner?

Persönlich finde ich es immer unklug, wenn man Programmtext so ganz ohne 
Leerzeichen Buchstaben an Buchstaben setzt. Man sieht dann so schlecht 
die kleinen Feinheiten. Dein Lesezentrum im Gehirn wurde seit du 6 Jahre 
alt bist, darauf trainiert, dass zwischen Wörtern ein Leerraum steht und 
wenn du etwas liest, dann sucht das Gehirn erst mal diese Leerräume um 
dort die gedankliche Trennung der Wörter reinzulegen. Kein Mensch käme 
auf die Idee,
deutschenTextkomplettohneLeerzeichenzuschreiben,weildanndasLeseneinfachn 
ur
furchtbarermüdendist.
Nur wenn dieselben Leute dann C Programmieren, dann müssen alle 
Buchstaben knirsch auf knirsch geschrieben werden, weil das ja beim 
Schreiben so wahsinnig viel Zeit spart.


   if( timer << insp )

Schon sticht das << heraus und es ist weit schwieriger so etwas beim 
Korrekturlesen des Codes irrtümlich als < zu lesen. Gerade in einer 
Sprache wie C, in der jedes falsche Zeichen über Sieg oder Niederlage 
entscheiden kann, ist es umso wichtiger, dass man seinen Code so 
gestaltet, dass er gut lesbar ist. Dazu gehören neben optischen Hilfen 
wie Leerzeichen auch korrekte Einrückungen.

Vergleich mal deine Variante
1
ISR(TIMER1_OVF_vect)
2
{              
3
timer++;
4
  
5
    if(state==1)
6
    {
7
      if(timer<<insp)
8
      {
9
      PORTC |= (1<<0);
10
      }
11
      if((timer<<exsp) && (timer>=insp))
12
      {
13
      PORTC &= ~(1<<0);
14
      }
15
      if(timer==exsp)
16
      {
17
      act++;
18
      timer=0;
19
        if(act==max)
20
        {
21
        state=2;
22
        }  
23
      }
24
    }
25
}

mit der hier
1
#define ATMEN  1
2
#define OFF    2
3

4
#define LED_PORT  PORTC
5
#define ATEM_LED  0
6

7
ISR(TIMER1_OVF_vect)
8
{              
9
  timer++;
10
  
11
  if( state == ATMEN )
12
  {
13
    if( timer < EinatemZeit )
14
      LED_PORT |= (1 << ATEM_LED);
15

16
    else if( timer < AusatemZeit )
17
      LED_PORT &= ~(1 << ATEM_LED);
18

19
    else {
20
      timer = 0;
21
      ZugNummer++;
22

23
      if( ZugNummer == AnzahlZuege )
24
        state = OFF;
25
    }
26
  }
27
}

Denk dir ein paar Füllwörter dazu und der Programmtext der ISR liest 
sich schon fast wie deutsche Sätze.

   if( timer < EinatemZeit )

Aha. Wenn die Zeitzählung als noch kleiner als die Zeit ist, die fürs 
einatmen vorgesehen ist, dann ....

      LED_PORT |= (1 << ATEM_LED);

... ja, logisch. Dann soll die LED welche einatmen anzeigt eingeschaltet 
werden.
Da brauch ich nur den Programmtext lesen, mir ein paar Wörter dazudenken 
und komm zum Schluss: passt. Die Logik kann stimmen.
OP #2494561
Gut, abgesehen davon hilft das meinem Problem aber auch nicht weiter.
Es sollte tatsächlich ein Vergleich sein, nur ging ich davon aus, daß es 
sich wie bei dem booleschen Vergleich wie zum Beispiel if (i==0) 
verhält.
Die ISR verhält sich nach wie vor ab einer Frequenz von 27 seltsam.
#2494571
Wastl B. schrieb:
> Gut, abgesehen davon hilft das meinem Problem aber auch nicht weiter.

Inwiefern hilft das deinem Problem nicht weiter, wenn ich dir mitteile, 
dass du an dieser Stelle die völlig falsche Operation machst?

> Es sollte tatsächlich ein Vergleich sein, nur ging ich davon aus, daß es
> sich wie bei dem booleschen Vergleich wie zum Beispiel if (i==0)
> verhält.

Ähm.
Wie wäre es mit C-Grundlagen lernen, ehe man an ein Projekt geht. 
Wenigstens die einfachsten Sachen.

   <      ist kleiner
   <<     ist Links-Schieben

 if( time < zeit )

ist etwas komplett völlig anderes als

 if( time << zeit )
OP #2494585
Sorry.
Hatte (aus irgendwelchen Gründen) deinen Code nicht angezeigt bekommen. 
Erst beim erneuten Aufrufen der Seite war dein Post komplett.
Ich habe die Operatoren angepasst/korrigiert. Immer noch ist die 
Funktion gestört (ich nehme mal an, daß das Programm sich richtig 
verhält, ich es nur falsch programmiert habe).

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.