Hallo, ich will mittels XMega eine einfache IR-Reflexschranke aufbauen. Als IR-Diode verwende ich TSUS-5202. Als Empfänger TSOP-4836. Der Vorwiderstand zur IR-Diode sind 100Ohm. Die Beschaltung des TSOP-4836 ist identisch der im Datenblatt vorgeschriebenen Beschaltung. Die Taktung der IR-Diode ist 36kHz. Dazu will ich 22 Takte (mit 36kHz) die IR-Diode ein/ausschalten. Und dann Pause für 22 Takte. So wie laut Datenblatt gefordert. Sobald ich meine Hand als Reflektor benutze, möchte ich, dass eine rote LED aufleuchtet. Jedoch blinkt sie nur sehr unrhythmisch. Ich erwarte eigentlich, dass die LED durchgehen rot leuchtet, sobald ich meine Hand über die IR-Diode bzw. Empfänger halte. Im Anhang habe ich Video beigefügt. Leider kann ich einfach keinen Fehler in meinem Code finden. Könnt ihr vielleicht erkennen, woran es liegen kann? Das ist mein Code:
1 | #define F_CPU 2e6
|
2 | #include <avr/io.h> |
3 | #include <asf.h> |
4 | #include <gfx_mono.h> |
5 | #include <sysfont.h> |
6 | |
7 | volatile int zaehler = 0; |
8 | int ADC_result; |
9 | char strng[20]; |
10 | |
11 | ISR(TCD1_OVF_vect) { |
12 | if(zaehler<44) { //44-> 22 mal Aufleuchten |
13 | PORTB.OUTTGL = 0b00000001; |
14 | }
|
15 | zaehler++; |
16 | if(zaehler>87) { // 87 -> 22 Impulse Pause |
17 | zaehler = 0; |
18 | }
|
19 | }
|
20 | |
21 | |
22 | int main(void) |
23 | {
|
24 | board_init(); |
25 | |
26 | // Ausgänge für rote LED (bit 1) und IR-LED setzen (bit 0)
|
27 | PORTB.DIR = 0b00000011; |
28 | |
29 | // Interrupts freigeben
|
30 | PMIC.CTRL |= PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; |
31 | |
32 | //Oszillator auf 32Mhz stellen
|
33 | OSC.CTRL |= OSC_RC32MEN_bm; |
34 | // Warten bis der Oszillator bereit ist
|
35 | while(!(OSC.STATUS & OSC_RC32MRDY_bm)); |
36 | //Schützt I/O Register, Interrupts werden ignoriert
|
37 | CCP = CCP_IOREG_gc; |
38 | //aktiviert den internen Oszillator
|
39 | CLK.CTRL = CLK_SCLKSEL_RC32M_gc; |
40 | |
41 | //Prescaler 64, PER 7, Takt 32Mhz --> 600Mikrosekunden Burst bei 22 Impulsen. Impulsfrequenz ist dann bei 36kHz
|
42 | // oder
|
43 | //Prescaler 1, PER 444, Takt 32Mhz --> 600Mikrosekunden Burst bei 22 Impulsen. Impulsfrequenz ist dann bei 36kHz
|
44 | TCD1.CTRLA = TC_CLKSEL_DIV1_gc; // Pre-Scaler |
45 | TCD1.PER = 444; // Wert zu dem gezählt wird |
46 | TCD1.CTRLB = 0x00; // Normal-Modus |
47 | TCD1.INTCTRLA = 0x03; // Höchste Interrupt Priorität |
48 | |
49 | // initialize ADC
|
50 | PORTA.DIR = 0x00; |
51 | ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc|ADC_CONMODE_bm; // 12 bit signed |
52 | ADCA.REFCTRL |= 0b00010000; // Ref = VCC/1.6 = 2.06 V |
53 | ADCA.PRESCALER = ADC_PRESCALER_DIV4_gc; |
54 | ADCA.CTRLA = ADC_ENABLE_bm; |
55 | |
56 | sei(); // Interrupts aktivieren |
57 | |
58 | while(1) |
59 | {
|
60 | // ADC channel lesen
|
61 | ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc; |
62 | ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN4_gc; |
63 | ADCA.CH0.CTRL |= ADC_CH_START_bm; |
64 | while(!ADCA.CH0.INTFLAGS); |
65 | ADC_result= ADCA.CH0.RES; |
66 | |
67 | if (ADC_result<1000) // ca. 50: Hand drangehalten, 1700: Hand weg |
68 | { // Rote LED an |
69 | PORTB.OUT |= (1<<1); |
70 | }
|
71 | else
|
72 | { // Rote LED aus |
73 | PORTB.OUT &= ~(1<<1); |
74 | }
|
75 | }
|
76 | }
|