Nabend,
am ADC0 (PA0) meines ATMEGA32 will ich eine Spannung messen. Diese liegt
zurzeit bei ca. 1.8V.
Nachdem ich meinen wie sonst üblichen Code verwendet habe, schwankten
die Werte aber immer stark, meistens blieben sie aber bei 1023. Es ist
auch vollkommen egal, ob Masse am Pin anliegt oder eine andere Spannung!
Es ist auch komischerweise egal, welchen Kanal ich wähle. JTAG ist
ausgeschaltet und es sind auch keine Pull-Ups aktiviert. Langsam
verzweifel ich daran.
Jetzt habe ich den Beispielcode aus dem AVR-Tutorial kopiert und
abgeändert, aber das Ergebnis bleibt das Selbe!
Hier der Code:
1 | #include <avr/io.h>
|
2 | #include <stdio.h>
|
3 | #include <util/delay.h>
|
4 | #include <stdlib.h>
|
5 | #include <avr/interrupt.h>
|
6 | #include <string.h>
|
7 | #include "uart/uart.h"
|
8 | #include "main.h"
|
9 |
|
10 | #define UART_BAUD_RATE 57600
|
11 |
|
12 |
|
13 | void ADC_Init(void);
|
14 | void Spg_Rauchmelder_abfragen(void);
|
15 |
|
16 | int8_t i=0;
|
17 |
|
18 | int main(void)
|
19 | {
|
20 | uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
|
21 |
|
22 | ADC_Init();
|
23 |
|
24 | sei();
|
25 |
|
26 | while(1)
|
27 | {
|
28 | Spg_Rauchmelder_abfragen();
|
29 | _delay_ms(1000);
|
30 | }
|
31 | }
|
32 |
|
33 |
|
34 |
|
35 | void Spg_Rauchmelder_abfragen(void)
|
36 | {
|
37 | uint16_t result = 0;
|
38 |
|
39 | ADMUX = (ADMUX & ~(0x1F)) | (0 & 0x1F);
|
40 | ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
|
41 | while (ADCSRA & (1<<ADSC) ) { // auf Abschluss der Konvertierung warten
|
42 | }
|
43 | result = ADCW; // ADC auslesen und zurückgeben
|
44 |
|
45 | char SpgTempBuffer[30];
|
46 |
|
47 | sprintf(SpgTempBuffer, "Spg-Wert: %d\r\n", result);
|
48 | uart_puts(SpgTempBuffer);
|
49 | }
|
50 |
|
51 |
|
52 | void ADC_Init(void) {
|
53 |
|
54 | uint16_t result;
|
55 |
|
56 | // interne Referenzspannung als Refernz für den ADC wählen:
|
57 | ADMUX = (1<<REFS1) | (1<<REFS0);
|
58 |
|
59 | // Bit ADFR ("free running") in ADCSRA steht beim Einschalten
|
60 | // schon auf 0, also single conversion
|
61 | ADCSRA = (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler
|
62 | ADCSRA |= (1<<ADEN); // ADC aktivieren
|
63 |
|
64 | /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
|
65 | also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
|
66 |
|
67 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
|
68 | while (ADCSRA & (1<<ADSC) ) { // auf Abschluss der Konvertierung warten
|
69 | }
|
70 | /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
|
71 | Wandlung nicht übernommen. */
|
72 | result = ADCW;
|
73 | }
|
Folgendes kommt auf dem Terminalprogramm an:
Spg-Wert: 856<\r><\n>
Spg-Wert: 945<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 817<\r><\n>
Spg-Wert: 828<\r><\n>
Spg-Wert: 856<\r><\n>
Spg-Wert: 944<\r><\n>
Was mache ich falsch?!?
Vielen Dank für eure Hilfe!