RC-Reciever und das seltsame Timer Ergebniss

OP (Firma: Hobby) #2702677
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?
OP (Firma: Hobby)
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.
Persönliche Seite
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.
OP (Firma: Hobby)
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.
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.

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.