Hallo Gemeinde,
es geht leider schon wieder um das Thema der Impulslängenauswertung,
hier im Beispiel bei einem Empfänger aus dem Modellbaubereich. Ich weiß,
dass es dazu schon einige Beiträge gibt, welche ich auch gelesen habe
aber mir bisher noch nicht den entscheidenden Hinweis zur Fehlerquelle
in meinem Code gebracht haben.
Nachfolgend erstmal der Programmcode:
1 | #include <inttypes.h>
|
2 | #include <avr/interrupt.h>
|
3 | #include <avr/io.h>
|
4 | #include <util/delay.h>
|
5 |
|
6 |
|
7 | volatile uint16_t signal_1st, signal_2nd;
|
8 | volatile uint16_t impuls;
|
9 | volatile uint8_t kanal = 255;
|
10 | volatile uint8_t setMode = 0;
|
11 | volatile uint8_t signalEnd = 0;
|
12 |
|
13 | uint16_t signalLength = 0;
|
14 |
|
15 |
|
16 | ISR( TIMER1_CAPT_vect )
|
17 | {
|
18 |
|
19 | switch(setMode)
|
20 | {
|
21 | case 0:
|
22 |
|
23 | signal_1st = ICR1;
|
24 |
|
25 | TCCR1B ^= (1<<ICES1); // Capture-Flanke umschalten
|
26 | setMode = 1; // Modus "fallende Flanke"
|
27 | break;
|
28 | case 1:
|
29 |
|
30 | signal_2nd = ICR1;
|
31 | TCCR1B ^= (1<<ICES1); // Capture-Flanke umschalten
|
32 | setMode = 0; // Modus "steigende Flanke"
|
33 | signalEnd = 1; // Variable zum Beginn der Berechnung für die Impulslänge
|
34 | cli();
|
35 | break;
|
36 | }
|
37 | }
|
38 |
|
39 |
|
40 | int main(void)
|
41 | {
|
42 | DDRB = 0x00; // Port B als Input (inkl. PB0 = ICP1)
|
43 | DDRC = 0xff; // Port C als Ausgang
|
44 |
|
45 |
|
46 | TIMSK |= (1<<TICIE1); // Capture Interrupt enable
|
47 | TCCR1B |= (1<<CS12) | (1<<ICES1); // Prescaler 256 Timer 1, Capture bei steigender Flanke
|
48 |
|
49 | sei(); // Globale Interruptfreigabe
|
50 |
|
51 |
|
52 | for(;;)
|
53 | {
|
54 |
|
55 | if(signalEnd)
|
56 | {
|
57 | impuls = (signal_2nd - signal_1st); // Differenzwert zwischen steigender und fallender Flanke
|
58 |
|
59 |
|
60 |
|
61 | if(impuls < 47) // Vergleichswert für 1,5ms bei 8MHz und TimerPrescaler 256
|
62 |
|
63 | PORTC = ~0x00;
|
64 |
|
65 | else
|
66 |
|
67 | PORTC = ~0x01;
|
68 |
|
69 |
|
70 | signalEnd = 0;
|
71 | sei();
|
72 |
|
73 | }
|
74 |
|
75 | }
|
76 | }
|
Zur Funktion:
Eigentlich ist die Geschichte recht simpel und wird bisher auf einem
STK500 getestet. Die Impulslänge eines Empfängerkanals wird mittels
Timer und "Input Capture" auf eine bestimmte Länge überprüft und damit
einfach zwei Ausgänge geschalten.
In der ISR schalte ich die Flankenerkennung von zuerst "steigend" auf
"fallend" um und berechne aus der Differenz der beiden Werte im ICR1 die
vergangene Zeit.
Jetzt ist das Problem, dass ich praktisch immer (unabhängig von der
Impulslänge) in die erste IF-Anweisung reinlaufe und ich vom errechneten
Wert anscheinend immer unter den 47 bin. Die Impulslängenänderung beim
Bewegen des Knüppels passt (lt. Oszi) und liegt auch am ICP1 an.
Ich sehe jetzt keinen Fehler und kann mir das auch nicht wirklich
erklären. Wäre super, wenn jemand einmal über den Code sehen könnte,
vielleicht bin ich ja einfach nur blind :) Bin für jeden Tipp dankbar.
Gruß
Stefan