Ich habe einen phototransistorartigen IC (TSL262R), der durch
Bestrahlung mit einer IR-LED eine Spannung erzeugt. Diese möchte ich mit
dem AD-Wandler-Modul des XMEGAs (in Form einer XDIL3-Adapterplatine)
auslesen. Mit der angehängten Schaltung und dem untenstehenden Code
bekomme ich immer nur eine schwankende 2048 als Ergebnis, was für mich
aber auch keinen Sinn macht, da ich vorzeichenlos arbeite. An den
Eingangspins liegen etwa 100mV an (messbar mit Oszi und Voltmeter), die
externe Spannungsreferenz (AD780) ist zuschaltbar aber derzeit nicht
benutzt.
1 | #include <avr/interrupt.h>
|
2 | #include <avr/io.h>
|
3 |
|
4 | #ifndef F_CPU
|
5 | #define F_CPU 32000000UL
|
6 | #endif
|
7 | #include <util/delay.h>
|
8 |
|
9 | void setClockTo32MHz(void);
|
10 | void init_ports(void);
|
11 | void init_ADC(void);
|
12 | void enable_ADC(void);
|
13 |
|
14 |
|
15 |
|
16 | int main(void) {
|
17 | setClockTo32MHz();
|
18 | init_ports();
|
19 | init_interrupts();
|
20 | init_ADC();
|
21 | sei();
|
22 | enable_ADC();
|
23 |
|
24 | while(1) {
|
25 | }
|
26 | }
|
27 |
|
28 |
|
29 |
|
30 | void setClockTo32MHz(void) {
|
31 | CCP = CCP_IOREG_gc;
|
32 | OSC.CTRL = OSC_RC32MEN_bm;
|
33 | while(!(OSC.STATUS & OSC_RC32MRDY_bm));
|
34 | CCP = CCP_IOREG_gc;
|
35 | CLK.CTRL = CLK_SCLKSEL_RC32M_gc;
|
36 | }
|
37 |
|
38 |
|
39 |
|
40 | void init_ports(void) {
|
41 | PORTB.DIRCLR |= PIN1_bm | PIN2_bm; // ADC inputs (unnötig, ich weiß)
|
42 | }
|
43 |
|
44 |
|
45 |
|
46 | void init_ADC(void) {
|
47 | //ADCB.CTRLB |= ADC_IMPMODE_bm;
|
48 | ADCB.CTRLB |= ADC_CURRLIMIT_LARGE_gc; // set high current limit -> lower MSPS
|
49 |
|
50 | //ADCB.REFCTRL |= ADC_REFSEL_AREFB_gc; // external voltage reference at ADCB
|
51 | ADCB.REFCTRL |= ADC_REFSEL_INT1V_gc; // internal voltage reference
|
52 |
|
53 | ADCB.PRESCALER |= ADC_PRESCALER_DIV16_gc; // prescaler x/16
|
54 |
|
55 | ADCB.CH0.CTRL |= ADC_CH_INPUTMODE_SINGLEENDED_gc; // single ended mode
|
56 | ADCB.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN9_gc; // pin 9 as input
|
57 | ADCB.CH0.INTCTRL = ADC_CH_INTMODE_COMPLETE_gc | ADC_CH_INTLVL_LO_gc;
|
58 |
|
59 | ADCB.EVCTRL |= ADC_SWEEP_0_gc; // in sweep or free running mode, channels 0 shall be used
|
60 | }
|
61 |
|
62 |
|
63 |
|
64 | void enable_ADC(void) {
|
65 | ADCB.CTRLA |= ADC_ENABLE_bm;
|
66 | ADCB.CTRLB |= ADC_FREERUN_bm;
|
67 | }
|
Ist der ADC einfach nur falsch konfiguriert? (Wenn ja, was ist falsch?)
Danke