Forum: Compiler & IDEs RC-Reciever und das seltsame Timer Ergebniss


von Max D. (Firma: Hobby) (fmhweb)


Lesenswert?

Hallo,

ich kann mir vorstellen, dass einige bei den folgenden Fragen ihr Gehirn 
sehen und bitte um Verständnis. Ich versuche etwas noch nie da Gewesenes 
zu machen, nämlich einen RC-Reciever auszulesen und kann zumindest einen 
Teilerfolg bieten. Ich wundere mich über die Ausgabe des Timers.

Ich verwende einen ATMega16 mit einem 8MHz Quartz und einen analogen 
Futuba Reciever, angeschlossen an INT0. Derzeit versuche ich, zum 
lernen, nur ein Servosignal auzuwerten und nicht das Summensignal. 
Soweit klappt das auch, doch der Timer gibt mir nicht das gewünschte 
Ergebniss auf meinem LCD aus. Die Fuses habe ich mit _delay_ms(1000) und 
LEDs getestet. Das übliche Servosignal ist 1ms – 2ms.

Hier meine (ausführliche) Rechnung:
8000000 Hz / 64 prescaler = 125000 Schritte pro Sekunde
1 sek / 12500 Schritte * 1000 = 0,008 ms pro Schritt
1 ms / 0,008 ms pro Schritt = 125 Schritte
2 ms / 0,008 ms pro Schritt = 250 Schritte
Auflösung: 125

Bei 1 ms erwarte ich also ein Countervalue (TCNT1) von 125 und bei 2 ms 
250. (Timer0 würde also ausreichen)

Auf dem LCD lese ich aber +/- 5:
1ms = 18608  (Knüppel unten)
1,5ms = 18680  (Knüppel mitte)
2ms = 18760  (Knüppel oben)

Bitte schaut euch dazu meinen Code an:
1
#define F_CPU 8000000UL
2
3
#include <avr/io.h>
4
#include "lcd-routines.c"
5
#include <avr/interrupt.h>
6
#include <stdlib.h>
7
8
//volatile uint16_t starttime = 0;
9
volatile uint16_t signal1 = 0;
10
volatile uint8_t edge_switch=0;
11
12
ISR(INT0_vect) {
13
  if(edge_switch == 0){
14
    //starttime = TCNT1;
15
    TCNT1 = 0;
16
    edge_switch = 1;
17
    MCUCR |= (0<<ISC00);          //Fallende Flanke
18
  }
19
  else{
20
    //signal1 = TCNT1 - starttime;
21
    signal1 = TCNT1;
22
    edge_switch = 0;
23
    MCUCR |= (1<<ISC00);          //Steigende Flanke
24
  }
25
}
26
27
void lcd_string_int(uint16_t tmp_int){
28
  char buffer[20];
29
  utoa(tmp_int, buffer, 10);
30
  lcd_string(buffer);
31
}
32
33
int main(void){
34
  GICR |= (1<<INT0);                     //INT0 enable
35
  MCUCR |= ((1<<ISC01) | (1<<ISC00));    //Steigende Flanke
36
  TCCR1B = ((1<<CS10) | (1<<CS11));      //Prescaler 64
37
  
38
  lcd_init();
39
  sei();
40
  
41
  while(1){
42
    lcd_clear();
43
    lcd_string_int(signal1);
44
    _delay_ms(1000);
45
  }
46
}

1) Kann jemand erkennen wo mein Fehler liegt?
2) Habe ich mich verrechnet?
3) Sind die Einstellungen richtig?

von L.A: (Gast)


Lesenswert?

Max Durst schrieb:
> Reciever

Was ist das?

von Max D. (Firma: Hobby) (fmhweb)


Angehängte Dateien:

Lesenswert?

Empfänger?

Mit Reciever meine ich natürlich Receiver

von Max D. (Firma: Hobby) (fmhweb)


Lesenswert?

Mit dem Betreff und dem eingedeutschtem Receiver habe ich wohl einiges 
an street credit eingebüsst. Dabei habe ich GCSE, A-Level und in England 
business information technology studiert:( Wie unangenehm.

von Stefan E. (sternst)


Lesenswert?

1
    MCUCR |= (0<<ISC00);          //Fallende Flanke
Die Zeile macht rein gar nichts, also misst du ständig nur die Zeit 
zwischen zwei steigenden Flanken.

von Tom M. (tomm) Benutzerseite


Lesenswert?

Max Durst schrieb:
> MCUCR |= ((1<<ISC01) | (1<<ISC00));    //Steigende Flanke

Ich weiss nicht, ob das die Ursache ist, aber du setzt MCUCR an 
verschiedenen Stellen, auch in der ISR. Dort ver-oder-st du auch, also 
ändert das nichts an der Konfiguration.

MCUCR scheint mir etwas exotisch zu sein, passt da nicht eher EICRx 
(kuck nohcmals in Datenblatt).

Jedenfalls feuert die ISR bei beiden Flanken, und du weisst nicht, ob du 
gerade die steigende oder fallende beobachtet hast, das könnte eine 
Fehlerquelle sein.

von Max D. (Firma: Hobby) (fmhweb)


Lesenswert?

Danke vielmals. Habe die Zeile geändert und jetzt geht es.
1
MCUCR ^= (1<<ISC00);

PS: EICRx ist habe ich mal bei einem Tiny AT gesehen. Wahrscheinlich 
kann man das bei den MCs nicht im Interrupt setzen. I dunno.

von Karl H. (kbuchegg)


Lesenswert?

Max Durst schrieb:
> Danke vielmals. Habe die Zeile geändert und jetzt geht es.
>
1
> MCUCR ^= (1<<ISC00);
2
>

Kann man machen. Persönlich würdeich aber

  MCUCR &= ~( 1<<ISC00);

vorziehen.
Ich finde das klarer, dass hier das Bit dezidiert gelöscht werden soll. 
Bei deiner Lösung muss man ständig im Hinterkopf halten, dass es im 
anderen Zweig gesetzt wird um zu wissen, was hier eigentlich 
beabsichtigt ist.

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.