ADC Werte ändern sich nicht

Gast #3161402
Lesenswert?

Hallo zusammen,
nachdem ich seit kurzen Assembler programmiere wollte ich jetzt mal das 
ganze in C versuchen. Testumgebung ist ein Atmega8. Jetzt habe ich aber 
das Problem, dass mein ADC sehr komische Werte leifert. Ich will dabei 
nur das High bit haben. In Assembler hat das wunderbar funktioniert und 
in C überhaupt nicht...
Der ADC pendelt sich einfach sofort auf 84/85 ein und ändert den Wert 
nicht mehr, egal welche Quelle als Eingang, egal wie sich das Signal 
ändert. Zuerst Low dann High auslesen hat nicht funktioniert, es mit 
ADCW auslesen auch nicht, mit und ohne Dummy, Mittelwert, An/Abschalten, 
Warten usw alles erfolglos. Werte lass ich mir über den UART ausgeben 
(wird im Bootloader initialisiert). Hat jemand noch einen Tipp, was an 
dem C Code falsch ist?
1
#define F_CPU 8000000UL //define 8MHz
2

3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include <avr/interrupt.h>
6

7
void myinit();
8
uint8_t get_adc_value();
9
void send(uint8_t);
10

11

12

13
int main(void)
14
{
15
  myinit();
16
  uint8_t left_adcvalue_on = 0;
17
  ADMUX |= (1 << REFS0)|(1 << MUX1) |(1 << MUX0)  |(1 << ADLAR); //set left to adc
18
  PORTD |= (1<<PD6); //switch led on
19
  
20
    while(1)
21
    {
22
    _delay_ms(500);
23
    left_adcvalue_on = get_adc_value();
24
    send(left_adcvalue_on);    
25
    }
26
}
27

28
uint8_t get_adc_value()
29
{
30
  uint8_t i;
31
  uint16_t result = 0;
32
  ADCSRA |= (1 << ADEN); //enable adc
33
  
34
  //dummy readout
35
  ADCSRA |= (1<<ADSC);
36
  while(ADCSRA & (1<<ADSC));
37

38
  //read real value
39
  for(i=0; i<3; i++) 
40
  {
41
    ADCSRA |= (1<<ADSC);
42
    while(ADCSRA & (1<<ADSC));
43
    result += ADCH;
44
  }
45
  result /= 3  ;
46
  
47
  ADCSRA &= ~(1<<ADEN); //disable adc
48
  return result;
49
}
50

51
void send(uint8_t send_this)
52
{
53
    while (!(UCSRA & (1<<UDRE))) ;  //wait until you can send
54
    UDR = send_this;
55
  return;
56
}
57

58
void myinit()
59
{
60
  //init leds
61
  DDRD |= (1<<PD7)| (1<<PD6);
62
  DDRC |= (1<<PC1)| (1<<PC0);
63
  PORTD &= ~(1<<PD7);
64
  //init USART
65
  UCSRB |= (1<<TXEN)|(1<<RXEN);
66
  //init ADC
67
  ADCSRA |= (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1);
68
  //init PWM
69
  TCCR1A |= (1 << WGM10) | (1 << COM1A1) | (1 << COM1B1);
70
  TCCR1B |= (1 << CS11);
71
  return;
72
}
Gast #3161493
Lesenswert?

Der Rückgabetyp stand noch falsch drin, weil ich es davor mit ADCW 
versucht hatte. Hat aber leider nichts geändert, außer dass er jetzt 
zwischen 33/34 schwankt.
Ein Dauerplus am Eingang ist eigentlich auch nicht möglich. Da ist ein 
Phototrans davor, der den Wert je nach Helligkeit ja dann schön ändern 
sollte. Außerdem tritt das Problem ja leider bei jedem Eingang auf
Gast #3162049
Lesenswert?

zwergenstadt schrieb:
> zwergenstadt schrieb:
>> ADMUX |= (1 << REFS0)|(1 << MUX1) |(1 << MUX0)  |(1 << ADLAR);
>
> Hab den Fehler gefunden...
> Das sollte = nicht |= sein. Also:
> ADMUX = (1 << REFS0)|(1 << MUX1) |(1 << MUX0)  |(1 << ADLAR);

Versteh ich nicht. Nach Einschalten ist ADMUX mit 0x00 initialisiert. Im 
Programm wird ADMUX nur einmal beschrieben. Da sollte es keine Rolle 
spielen, ob der Inhalt verodert wird oder nicht?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren