Forum: Mikrocontroller und Digitale Elektronik Frequenzmessung mittels Input Capture mode ( mega 32 )


von Tim (Gast)


Angehängte Dateien:

Lesenswert?

Hallo!

Ich würde gerne die Zeit zwischen 2 Signalen messen mittels des Input 
Capture modes.
Hizu habe ich auch hier im Forum einen ganz nützlichen Code Gefunden, 
jedoch wirft mir mein Compiler jedes mal einen Fehler aus, mit dem ich 
absolut nichts anfangen kann.

 und zwar:

../Frequenzmessung.c:72: error: redefinition of 'ISR'
../Frequenzmessung.c:41: error: previous definition of 'ISR' was here



Ich sitze jetzt schon Stunden da und komme einfach nicht weiter.
Könnte mir bitte jemand dabei einen Tip geben.

Danke!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

ISR wird normalerweise hier definiert:

#include <avr/interrupt.h>

Da das bei dir nicht hilft, benutzt du offensichtlich eine hornalte
Version der Bibliothek (vor 1.4.x, aktuell ist 1.6.7).  Dafür sind
leider mittlerweile die Supportverträge abgelaufen. ;-)

von Tim (Gast)


Lesenswert?

Danke für die Info!

Ich habe mir alerdings erst kürzlich die neueste Version von AVR-Studio 
runtergeladen. (4.16)
Habe leider keine Ahnung ob das auch mit der Bibliothek zusammenhängt.
Kann man die irgend wie updaten?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Tim schrieb:

> Ich habe mir alerdings erst kürzlich die neueste Version von AVR-Studio
> runtergeladen. (4.16)

Davon abgesehen, dass es meines Wissens schon eine 4.17 gibt
(zumindest als Beta), AVR Studio hat damit nichts zu tun.

Sehr wahrscheinlich hast du ein WinAVR da drunter, das müsstest du
mal auf einen aktuellen Stand bringen.  Deiner muss noch von ca.
2005 stammen.

von Tim (Gast)


Lesenswert?

stimmt; die Version ist von 2005.

Habe sie jetzt auf Stand gebracht ( 2009 ) Version 1.6.6.
ändert jedoch nichts an meinem Problem

von Karl H. (kbuchegg)


Lesenswert?

Ich bin so frei und poste den Code einfach mal hier herinnen.
Das ständige zum *.txt wechseln (warum eigentlich *.txt und nicht *.c) 
ist mir nämlich zu blöd.
Und damit man das alles auch lesen kann, lege ich wieder mal Hand an und 
formatiere das mal etwas
(Ist es nicht erstaunlich. Diejenigen bei denen der Source Code auch 
optisch in Ordnung ist haben meistens auch viel weniger 'seltsame 
Probleme')
1
#ifndef F_CPU
2
#define F_CPU 8000000
3
#endif
4
5
#include <avr/io.h>
6
#include <avr/interrupt.h>
7
#include <avr/delay.h>
8
9
#include <stdlib.h>
10
#include "lcd.h"
11
12
#ifndef TRUE
13
#define TRUE 1
14
#define FALSE 0
15
#endif
16
17
volatile unsigned char NrOverflows = 0;   // Anzahl der Timer Overflows die während der Messung passiert sind
18
volatile unsigned int StartTime = 0;   // ICR-Wert bei der 1.High-Flanke speichern
19
volatile unsigned int EndTime = 0;    // ICR-Wert bei der 2.High-Flanke speichern
20
volatile unsigned char UpdateDisplay;  // Job Flag
21
22
//#define LCD_LINE1 0x00 // Position an der das ERgebnis der Frequenzmessung ausgegeben wird
23
24
ISR( TIMER1_CAPT_vect )
25
{
26
  static unsigned char ErsteFlanke = TRUE;
27
    
28
  if (UpdateDisplay)  // das Display wurde mit den Ergebnissen der vorhergehenden Messung
29
    return;      // noch nicht upgedatet. Die nächste Messung verzögern, bis der Start
30
              // und EndTime Variablen wieder gefahrlos beschrieben werden können.
31
32
  // Bei der ersten Flanke beginnt die Messung, es wird der momentane 
33
  // Timer beim Input Capture als Startwert gesichert
34
  //
35
36
  if ( ErsteFlanke )
37
  {
38
    StartTime = ICR1;
39
    NrOverflows = 0;
40
    ErsteFlanke = FALSE;    // Die nächste Flanke ist das Ende der Messung
41
  }
42
43
  // das ist die zweite Flankte im Messzyklus. Die Messung wird gestoppt
44
45
  else 
46
  {
47
    EndTime = ICR1;
48
    UpdateDisplay = TRUE;  // Eine vollständige Messung. Sie kann ausgewertet werden
49
    ErsteFlanke = TRUE;    // Bei der naechsten Flanke beginnt der nächste Messzyklus
50
  }
51
}
52
53
ISR( TIMER1_OVF_vect )
54
{
55
  NrOverflows++;
56
}
57
58
int main()
59
{
60
  char lcdCounterString[8];
61
  double Erg = 0.0;
62
63
  lcd_clrscr();
64
65
  TCCR1B = (1<<ICES1) | (1<<CS10);  // Input Capture Edge, kein PreScale
66
  TIMSK = (1<<TICIE1) | (1<<TOIE1); // Interrupts akivieren, Capture + Overflow
67
68
  sei();
69
70
  while(1)
71
  {
72
    if( UpdateDisplay )    // liegt eine vollständige Messung vor?
73
    {
74
                           // Berechnung der Zeitdauer zwischen den Takten
75
                           // EndTime und StartTime sind unsigned darum braucht kann EndTime auf
76
                           // kleiner sein als StartTime, nur Overflows müssen berücksichtigt werden
77
        
78
        
79
      Erg = ( NrOverflows * 65536 ) + EndTime - StartTime; // ausrechnen der Takte
80
         
81
        // aufbereiten fürs Display
82
83
      Erg = F_CPU / Erg;   // f=1/t Signalfrequenz
84
85
      itoa(Erg, lcdCounterString, 8);
86
87
      //dtostrf( Erg, 5, 3, lcdCounterString ); // 3 Nachkommastellen
88
                                                // ausgeben
89
      lcd_clrscr();
90
      lcd_gotoxy ( 0,0 );
91
      lcd_puts (lcdCounterString);
92
        
93
      UpdateDisplay = FALSE; // nächste Messung kann Starten                
94
    }
95
  }
96
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

1
%% avr-gcc -Wall -Wextra -mmcu=atmega128 -Os -o foo.elf foo.c lcd.c
2
In file included from foo.c:7:
3
/usr/local/lib/gcc/avr/4.3.2/../../../../avr/include/avr/delay.h:36:2: warning: #warning "This file has been moved to <util/delay.h>."

Diese Warnung ist das einzige, was mein Compiler daran auszusetzen
hat.

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.