Forum: Mikrocontroller und Digitale Elektronik ADC Werte ändern sich nicht


von zwergenstadt (Gast)


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
}

von auch c Beginner (Gast)


Lesenswert?

zwergenstadt schrieb:
> }
>
> uint8_t get_adc_value()
> {
>
>   uint16_t result = 0;
>   return result;
> }
>

Rückgabetyp und Variablentyp passen nicht zusammen?

Dauerplus an PC3 (ADC3)?

von zwergenstadt (Gast)


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

von Walter S. (avatar)


Lesenswert?

zwergenstadt schrieb:
> der den Wert je nach Helligkeit ja dann schön ändern
> sollte.

"sollte" sollte man nicht sagen sondern den Spannungswert am Eingang 
überprüfen

von zwergenstadt (Gast)


Lesenswert?

Da hast du natürlich vollkommen recht. Multimeter zeigt an, dass es 
zwischen 0V und 5V Schwankt (ziemlich schlechtes Multimeter, gerade kein 
anders zur Hand)

von zwergenstadt (Gast)


Lesenswert?

Habe das ganze eben auf anderer Hardware getestet, da ist der Wert auch 
immer gleich :(

von zwergenstadt (Gast)


Lesenswert?

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);

von auch c Beginner (Gast)


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?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.