Sehr geehrtes Forum, ich habe eine Frage bezüglich des ADCs. Ich habe eine Vorrichtung mit einem ATMEGA 88 PA, mit RS232 Verbindung zum PC und folgendem Code in C:
1 | // 19.12.2013 - 17:19 Uhr, Tests zur Kommunikation per RS232 in C |
2 | |
3 | #include <avr/io.h> |
4 | #include <util/delay.h> |
5 | |
6 | #define BAUD 4800UL |
7 | #define F_CPU 1000000UL |
8 | #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) |
9 | |
10 | // Initialisierung des UART |
11 | void uart_init(void) |
12 | { |
13 | // Baudrate einstellen |
14 | UBRR0H = UBRR_VAL >> 8; |
15 | UBRR0L = UBRR_VAL & 0xFF; |
16 | |
17 | // Verwendungsart einstellen |
18 | UCSR0B = (1<<TXEN0); // UART TX einschalten |
19 | UCSR0C = (1<<UCSZ01)|(1<<UCSZ00); // Asynchron 8N1 |
20 | UCSR0B |= (1<<RXEN0); // UART RX einschalten |
21 | } |
22 | // Initialisierung des ADWC |
23 | void adc_init(void) |
24 | { |
25 | // die Versorgungsspannung AVcc als Refernz wählen: |
26 | //ADMUX = (1<<REFS0); |
27 | // oder interne Referenzspannung als Referenz für den ADC wählen: |
28 | ADMUX = (1<<REFS1) | (1<<REFS0); |
29 | |
30 | // Bit ADFR ("free running") in ADCSRA steht beim Einschalten |
31 | // schon auf 0, also single conversion |
32 | ADCSRA = (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler |
33 | ADCSRA |= (1<<ADEN); // ADC aktivieren |
34 | |
35 | /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest |
36 | also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */ |
37 | |
38 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung |
39 | while (ADCSRA & (1<<ADSC) ) { // auf Abschluss der Konvertierung warten |
40 | } |
41 | /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten |
42 | Wandlung nicht übernommen. */ |
43 | (void) ADCW; |
44 | } |
45 | |
46 | /* USART - Senden eines einzelnen Zeichens */ |
47 | int uart_putc(unsigned char c) |
48 | { |
49 | while (!(UCSR0A & (1<<UDRE0))) /* warten bis Senden moeglich */ |
50 | { |
51 | } |
52 | |
53 | UDR0 = c; /* sende Zeichen */ |
54 | return 0; |
55 | } |
56 | /* Zeichen empfangen */ |
57 | uint8_t uart_getc(void) |
58 | { |
59 | while (!(UCSR0A & (1<<RXC0))) // warten bis Zeichen verfuegbar |
60 | ; |
61 | return UDR0; // Zeichen aus UDR an Aufrufer zurueckgeben |
62 | } |
63 | |
64 | /* ADC Einzelmessung */ |
65 | uint16_t adc_read( uint8_t channel ) |
66 | { |
67 | // Kanal waehlen, ohne andere Bits zu beeinflußen |
68 | ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F); |
69 | ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion" |
70 | |
71 | while (ADCSRA & (1<<ADSC) ) // auf Abschluss der Konvertierung warten |
72 | { |
73 | } |
74 | |
75 | return ADCW; // ADC auslesen und zurückgeben |
76 | } |
77 | |
78 | void welcome(void) |
79 | { |
80 | uart_putc('T'); |
81 | uart_putc('E'); |
82 | uart_putc('S'); |
83 | uart_putc('T'); |
84 | uart_putc(' '); |
85 | uart_putc('D'); |
86 | uart_putc('E'); |
87 | uart_putc('V'); |
88 | uart_putc('I'); |
89 | uart_putc('C'); |
90 | uart_putc('E'); |
91 | uart_putc(' '); |
92 | uart_putc('R'); |
93 | uart_putc('E'); |
94 | uart_putc('A'); |
95 | uart_putc('D'); |
96 | uart_putc('Y'); |
97 | } |
98 | |
99 | int main (void) |
100 | { |
101 | uart_init(); |
102 | adc_init(); |
103 | |
104 | welcome(); |
105 | |
106 | while(1) |
107 | { |
108 | uart_getc(); |
109 | |
110 | uint16_t adw = adc_read(0); |
111 | uint8_t lo_value = adw; |
112 | uint8_t hi_value = (adw >> 8); |
113 | |
114 | uart_putc('>'); |
115 | uart_putc(lo_value); |
116 | uart_putc(hi_value); |
117 | } |
118 | return 0; |
119 | } |
Problem ist, die Ausgabe ist immer konstant, egal was ich an ADC Channel 0 auch anschließe, z.B. GND oder VCC oder gar nichts. Woran könnte es liegen, am Code, oder an der Hardware?