Hallo! Ich lese das erste Mal mit dem ATMEGA16 ein Servosignal ein. Folgenden Code habe ich mir überlegt. Beim Test sieht es leider so aus dass es nicht funktioniert, die betreffende LED die zum Test eingeschalten werden soll wenn das Signal >1,5ms lang ist blinkt in einem unruhigen Rhytmus... Anbei ein Bild wie ich das Signal eines Servotesters einspeise an den PIN PD6 (ICP). Kann mir jemand einen Tipp geben was der Fehler sien könnte und hat mir jemand ein Feedback zu meiner unten stehenden Lösung? Einstellen des Timers:
1 | // Rauschunterdrückung (Bit7) und steigende Flanke (Bit6) erkennen und CPU-Takt / 8 (enstspr 0,57us)
|
2 | // d.h. Zählregister TCNT1 inkrementiert mit dieser Periode
|
3 | TCCR1B = 0b11000010; |
4 | |
5 | // Interrupt für ICP (Input Capture Pin) einschalten
|
6 | TIMSK |=(1<<TICIE1); |
Die Interrupt Routine:
1 | extern int startWert; |
2 | extern int endWert; |
3 | extern double servoSignal; |
4 | |
5 | |
6 | // Timer 1 Capture Event Interrupt wenn Flanke an ICP Pin (PD6) --> Servosignal einlesen!
|
7 | ISR(TIMER1_CAPT_vect) |
8 | {
|
9 | // Wenn STEIGENDE Flanke erkannt werden soll, startwert einlesen (akt. Zählerstand)
|
10 | if(TCCR1B == 0b11000010) |
11 | {
|
12 | cli(); |
13 | startWert = ICR1L + 16*ICR1H; // einlesen mit deaktivierten Interrupts |
14 | sei(); |
15 | |
16 | TCCR1B = 0b10000010; // auf fallende Flanke umstellen! |
17 | }
|
18 | |
19 | // Wenn FALLENDE Flanke erkannt werden soll, endwert einlesen (akt. Zählerstand)
|
20 | else if(TCCR1B == 0b10000010) |
21 | {
|
22 | cli(); |
23 | endWert = ICR1L + 16*ICR1H; // einlesen mit deaktivierten Interrupts |
24 | sei(); |
25 | |
26 | if (startWert < endWert) |
27 | {
|
28 | servoSignal = (endWert - startWert) * 5.7413e-7; |
29 | }
|
30 | |
31 | else
|
32 | {
|
33 | servoSignal = (endWert - startWert + 65536) * 5.7413e-7; |
34 | }
|
35 | |
36 | // Zähler zurück setzen
|
37 | cli(); |
38 | TCNT1H = 0b00000000; |
39 | TCNT1L = 0b00000000; |
40 | sei(); |
41 | |
42 | TCCR1B = 0b11000010; // wieder auf steigende Flanke umstellen! |
43 | |
44 | }
|
45 | |
46 | |
47 | }
|
Aufruf in der MAIN:
1 | if(servoSignal >= 0.0015) |
2 | {
|
3 | LIGHTPORT1 = 0b11111110; |
4 | }
|
5 | |
6 | else if(servoSignal < 0.0015) |
7 | {
|
8 | LIGHTPORT1 = 0b11111101; |
9 | }
|