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?