Hallo zusammen,
ich bin gerade dabei, mit meinem Mikrocontroller Infrarotsignale zu
empfangen. Ich benutze dazu einen ATMEGA16 16PU mit internem Quarz, der
auf 4 Mhz eingestellt ist. Die verwendete LG-Fernbedienung sendet im
NEC-Format, das am Anfang aus einem 9ms High-Pegel und einem 4,5ms
Low-Pegel besteht und anschließend 32 Bit überträgt, die alle jeweils
mit einem 562,5µs High-Pegel beginnen und dann abhängig vom übertragenen
Bit entweder mit einem ebenfalls 562,5µs Low-Pegel (Bit = 0) oder einem
1687,5µs Low-Pegel (Bit = 0) enden.
Um diese Signale abzufangen, habe ich einen Prescaler von 1 eingestellt.
Das Timer_Register TCNT0 hatte ich auf -10 eingestellt, um die
Flankenwechsel so schnell wie möglich detektieren zu können und die
Genauigkeit des internen Quarzes zu testen. In einem Array habe ich die
Anzahl der Overflow-Triggerungen während eines Signals gespeichert. Der
erste Wert gehört quasi zur Wartezeit, der erste zu der Anzahl der
Overflow-Trigger während des 9ms High-Pegels usw.
Ich würde erwarten, dass bei dieser Konstellation die Anzahl der
Overflow-Triggerungen bei 0,009s * 4000000Hz / 10 = 3600 liegt.
Es werden allerdings nur 400 Overflow-Triggerungen für den 9ms
High-Pegel gemeldet, die zusätzlich nicht mit einer Veränderung von
TCNT0 bis über 50 variiert. Kann mir jemand erklären woher das kommt.
Dauert die Interrupt-Routine zu lange? Kann der Sensor nicht mehr (TSOP
4838)?
1 | #define XTAL 1e6
|
2 | #define F_CPU XTAL
|
3 |
|
4 | #include <avr/io.h>
|
5 | #include <util/delay.h>
|
6 |
|
7 | unsigned char i_lo; // intermediate storage variable
|
8 | unsigned char nec_bit;
|
9 | int16_t timeArray[70];
|
10 | int16_t iCounter;
|
11 | static int16_t time;
|
12 |
|
13 | int main (void)
|
14 | {
|
15 | mode = NONE;
|
16 | DDRB = 0xFF;
|
17 | DDRB = ~(1 << PB0);
|
18 |
|
19 | TIMSK |= (1<<TOIE0); // output compare A match interrupt
|
20 | TCCR0 = (1 << CS00); // prescaler 1
|
21 | TCNT0 = 0;
|
22 |
|
23 | while(1)
|
24 | {
|
25 | cli();
|
26 | i_lo = RemCo_data;
|
27 | sei();
|
28 | }
|
29 | return 0;
|
30 | }
|
31 |
|
32 | ISR (TIMER0_OVF_vect)
|
33 | {
|
34 | TCNT0 = -10;
|
35 |
|
36 | time++;
|
37 |
|
38 | if((nec_bit ^(!PINB & (1 << PB0))) & 1) // edge detection @ PB0
|
39 | {
|
40 |
|
41 | nec_bit = ~nec_bit; // toggle bit
|
42 |
|
43 | timeArray[iCounter] = time;
|
44 | iCounter++;
|
45 | if(iCounter > 67)
|
46 | nec_bit = 0;
|
47 | time = 0;
|
48 | }
|
49 | }
|
Viele Grüße
Paul