Forum: Mikrocontroller und Digitale Elektronik Analog Komparator Input Capture + Timer


von Sven (Gast)


Lesenswert?

Hallo,

leider muss ich auch nochmal mit dem Thema Analog Komparator anfangen...

Ich versuche ganz einfach die Zeit zwischen 2 Flanken zu messen, und 
verwende dazu Testweise den Timer 1, der alle 1 Sekunde einen überläuft. 
Da die Signalfrequenz aber über 1Hz ist passiert das aber nie, ist also 
nur zu Testzwecken so gewählt.
Erkennt der Komparator eine steigende Flanke sollte ja der Zählerstand 
in das ICR1x Register kopiert werden, welches ich dann gleich über den 
UART verschicke. Danach stelle ich den Timer wieder auf die 1 Sekunde 
ein, so dass die nächste Messung beginnen kann.

Den Timer Initialisiere ich so:
1
void timer_init(void)
2
{
3
4
  TCCR1A = 0;
5
  TCCR1B |= (1<<ICNC1) | (1<<ICES1) | (1<<CS12)| (1<<CS10);  // prescaler 1024
6
7
  ACSR = (1<<ACIC) | (1<<ACIS1) | (1<<ACIS0);// rising edge, timer 1
8
9
  TIMSK |= (1<<TICIE1) | (1<<TOIE1);  // input compare + overflow
10
11
  TCNT1H = 0xC2;  // preset for 1sec interrupts
12
  TCNT1L = 0xF7;
13
14
  TIFR &= ~(1<<ICF1);
15
16
}

Dazu habe ich folgende ISRs:
1
ISR(SIG_COMPARATOR)
2
{
3
    while( (UCSRA & 1<<UDRE) == 0 );
4
      UDR = 10;
5
6
7
}
8
9
10
ISR(TIMER1_CAPT_vect)
11
{
12
    
13
    cli();
14
    c_time = ICR1L;
15
    c_time += (ICR1H<<8);
16
    
17
    c_time -= 49911;  // offset durch preset value  
18
    c_time /= 61;  // scale to 8 bits
19
20
21
    TCNT1H = 0xC2;
22
    TCNT1L = 0xF7;
23
  
24
    TIFR &= ~(1<<ICF1);
25
26
    while( (UCSRA & 1<<UDRE) == 0 );
27
      UDR = c_time;
28
29
    sei();
30
}
31
32
33
ISR(TIMER1_OVF_vect)
34
{
35
36
    while( (UCSRA & 1<<UDRE) == 0 );
37
      UDR = 11;
38
39
    TCNT1H = 0xC2;
40
    TCNT1L = 0xF7;
41
42
}

In der main mache ich nur:
1
int main( void )
2
{
3
4
  timer_init();
5
  uart_init();
6
  sei();
7
8
  while(1){
9
10
  }
11
}
Jetzt habe ich leider noch das Problem, dass ich fast immer 2 mal den 
"Messwert" am PC empfange, und dazwischen sehr viele (~20) 0en gesendet 
werden. Die Signalquelle ist ein Frequenzgenerator der einen 0-5V Sinus 
erzeugt, und hängt an AIN1. AIN0 habe ich über einen Spannungsteiler auf 
2,5V gelegt.

Kann mir irgendjemand sagen was das Problem an meinem Code ist?

von Johnny (Gast)


Lesenswert?

Damit Dir geholfen werden kann, würde ich noch den verwendeten uC 
angeben.

von Sven (Gast)


Lesenswert?

Ich verwende einen Mega8 der mit 16Mhz Quarz läuft.

von Karl H. (kbuchegg)


Lesenswert?

Wie schnell wird dein µC getaktet?
Welche Frequenz legst du an den Komperator an?


Lass in einer ISR das Interrupt Flag in Ruhe! sei() und cli() haben in 
einer ISR normalerweise nichts verloren.
Ein Flag Bit in den Interrupt Registern kann man nicht mit
    TIFR &= ~(1<<ICF1);
löschen. Damit löscht du alle anderen Flag-Bits, nur das ICF1 Flag nicht 
:-)

Dein Compiler unterstützt dich beim Auslesen von 16-Bit Pseudoregistern. 
Nutze das!

Entscheide dich für Hex oder Dezimal, je nachdem was in deiner Situation 
am sinnvollsten ist. Aber mische nicht die Zahlensysteme, wenn es nicht 
notwendig ist.

Achte auf deine Einrückungen. Die Ausgabe auf die UART suggeriert durch 
die äussere Form an dieser Stelle, dass sie von der while-Schleife 
wiederholend kontrolliert wird. Dem ist nicht so!
1
ISR(TIMER1_CAPT_vect)
2
{
3
    c_time = ICR1;
4
5
    c_time -= 49911;  // offset durch preset value  
6
    c_time /= 61;  // scale to 8 bits
7
8
    TCNT1 = 49911;
9
  
10
    while( (UCSRA & 1<<UDRE) == 0 )
11
      ;
12
    UDR = c_time;
13
14
    TIFR |= (1<<ICF1);
15
}

von Sven (Gast)


Lesenswert?

Vielen Dank Dir schon mal! Das mit den 16 bit Registern habe ich noch 
nie gesehen und ist wirklich sehr praktisch.

Leider habe ich noch nicht wirklich rausgefunden wo die 0en herkommen, 
aber ansonsten funktioniert es soweit ganz gut.

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.