avr - adc problem

OP #684687
Lesenswert?

hi,

probier jetzt schon ewig herum, doch ich bekomme am display immer 
denselben wert: 2131.

hab keine ahnung woher dieser wert kommt.

als adc hab ich "ADC1" also an PA1 verwendet.

kann mir vielleicht jemand sagen ob der programmcode falsch ist?
1
int adc_main(int adc_wert)
2
{
3
   ADCSRA = 0x68;  // 1000 0110
4
  ADMUX = 0x41;  // 0100 0001
5

6
  ADCSRA |= (1<<ADSC);
7
  while(ADCSRA & (1<<ADSC));
8
  
9
  // Jetzt 3x die analoge Spannung and Kanal channel auslesen
10
  // und dann Durchschnittswert ausrechnen.
11
  for(int i=0; i<10; i++) {
12
    // Eine Wandlung
13
    ADCSRA |= (1<<ADSC);
14
    // Auf Ergebnis warten...
15
    while(ADCSRA & (1<<ADSC));
16
    
17

18
    adc_wert += ADC;
19
  }
20
  
21
  // ADC wieder deaktivieren
22
  ADCSRA &= ~(1<<ADEN);
23
  
24
  adc_wert /= 3;
25
  
26
  return adc_wert;
27
}

lg
OP #684723
Lesenswert?

1.) es handelt sich um einen ATmega32
2.) am ADC1 hängt eine brückenschaltung mit einem dehnmessstreifen => 
eine waage soll realisiert werden
3.)
1
    lcd_init(LCD_DISP_ON);
2

3
    while(1)
4
  {                           /* loop forever */
5
      
6
  //  unsigned char ReadChannel();
7
      /* 
8
         * Test 1:  write text to display
9
         */
10

11
        /* clear display and home cursor */
12
        lcd_clrscr();
13
        
14
        /* put string to display (line 1) with linefeed */
15
        lcd_puts("  Digi - Waage\n");
16

17
        /* cursor is now on second line, write second line */
18
        
19
    lcd_puts("Gewicht:");
20

21
// ******************************************************************** //
22
// ******************************************************************** //
23
// ******************************************************************** //
24
   ADCSRA = 0x86;  // 1000 0110
25
  ADMUX = 0xC1;  // 1100 0001
26

27
  while(1)
28
  {
29
  ADCSRA |= (1<<ADSC);
30
  while(ADCSRA & (1<<ADSC));
31
  
32
  // Jetzt 3x die analoge Spannung and Kanal channel auslesen
33
  // und dann Durchschnittswert ausrechnen.
34
    // Eine Wandlung
35
    ADCSRA |= (1<<ADSC);
36
    // Auf Ergebnis warten...
37
    while(ADCSRA & (1<<ADSC));
38

39
    adc_wert = ADCL;
40
    adc_wert += (ADCH >> 8);
41
  }
42
  
43
  // ADC wieder deaktivieren
44
  ADCSRA &= ~(1<<ADEN);
45
// ******************************************************************** //
46
// ******************************************************************** //
47
// ******************************************************************** //
48

49
        
50
        /* move cursor to position 9 on line 2 */
51
  
52
      itoa(adc_wert,buffer,10);
53
    lcd_gotoxy(9,1);  
54
        
55
        lcd_puts(buffer);

das ist im großen und ganzen der programmcode, diesmal die adc funktion 
direkt im main geschrieben...
#684743
Lesenswert?

Könntest Du bitte EXAKT DEN CODE posten, den Du auch wirklich 
verwendest und mit dem es nicht funktioniert? Der Code hat mit dem von 
oben nichts zu tun und die Kommentare stimmen auch nicht mit dem Code 
überein.

> adc_wert = ADCL;
> adc_wert += (ADCH >> 8);
Und das ist schwachsinnig. Benutze ADC, wie Du es oben ja auch richtig 
gemacht hast! Dann passieren auch keine Sachen wie hier der Rechtsshift 
anstelle des (korrekten) *LINKS*shifts!
OP #684750
Lesenswert?

1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <avr/pgmspace.h>
4
#include "lcd.h"
5

6
/*
7
** constant definitions
8
*/
9
static const PROGMEM unsigned char copyRightChar[] =
10
{
11
  0x07, 0x08, 0x13, 0x14, 0x14, 0x13, 0x08, 0x07,
12
  0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x00
13
};
14

15

16
/*
17
** function prototypes
18
*/ 
19
void wait_until_key_pressed(void);
20

21

22
void wait_until_key_pressed(void)
23
{
24
    unsigned char temp1, temp2;
25
    unsigned int i;
26
    
27
    do {
28
        temp1 = PIND;                  // read input
29
        for(i=0;i<65535;i++);
30
        temp2 = PIND;                  // read input
31
        temp1 = (temp1 & temp2);       // debounce input
32
    } while ( temp1 & _BV(PIND2) );
33
    
34
    loop_until_bit_is_set(PIND,PIND2);            /* wait until key is released */
35
  
36
}
37

38

39
int main(void)
40
{
41

42
  int adc_wert;
43
    char buffer[7];
44
    
45
    
46
    DDRD &=~ (1 << PD2);        /* Pin PD2 input              */
47
    PORTD |= (1 << PD2);        /* Pin PD2 pull-up enabled    */
48

49

50
    /* initialize display, cursor off */
51
    lcd_init(LCD_DISP_ON);
52

53
    while(1)
54
  {    
55
        /* clear display and home cursor */
56
        lcd_clrscr();
57
        
58
        /* put string to display (line 1) with linefeed */
59
        lcd_puts("  Digi - Waage\n");
60

61
        /* cursor is now on second line, write second line */
62
        
63
    lcd_puts("Gewicht:");
64

65
// ******************************************************************** //
66
// ****************************ADC************************************* //
67
// ******************************************************************** //
68
   ADCSRA = 0x86;  // 1000 0110
69
  ADMUX = 0x41;  // 0100 0001
70

71
  ADCSRA |= (1<<ADSC);
72
  while(ADCSRA & (1<<ADSC));
73
  
74
  for(int i=0;i<10;i++) {
75
    // Eine Wandlung
76
    ADCSRA |= (1<<ADSC);
77
    // Auf Ergebnis warten...
78
    while(ADCSRA & (1<<ADSC));
79

80
    adc_wert = ADCL;
81
    adc_wert += (ADCH >> 8);
82
  }
83
  
84
  // ADC wieder deaktivieren
85
  //ADCSRA &= ~(1<<ADEN);
86
// ******************************************************************** //
87
// ******************************************************************** //
88
// ******************************************************************** //
89

90
        
91
        /* move cursor to position 9 on line 2 */
92
  
93
      itoa(adc_wert,buffer,10);
94
    lcd_gotoxy(9,1);  
95
        
96
        lcd_puts(buffer);
97

98
    lcd_gotoxy(14,1);
99
    lcd_puts("g");
100
        
101
        /* wait until push button PD2 (INT0) is pressed */
102
        wait_until_key_pressed();
103
        
104
              
105
    }
106
}

hier mein gesamtes main, wo auch alles fürn adc drinnen ist.

hab naürlich noch andere module fürs lcd, diese funktionieren ja. es 
geht rein um den adc...
OP #684773
Lesenswert?

danke für die vielen tipps...

hab das jetzt soweit hinbekommen dass ich richtige werte bekommen.

nur ein letztes problem hab ich noch...

wenn ich die analoge eingangsspannung am adc ändere verändert sich der 
wert nur, wenn ich das programm wieder neu rüber lade, bzw. wenn ich den 
avr von der spannung trenne und wieder anschließe....

ich möchte aber dass sich der wert ständig ändert, also dass der adc 
ständig wandelt...

nur weiß ich leider nicht wie ich das programmtechnisch lösen soll ...
#684796
Lesenswert?

Chris :) wrote:

> ich möchte aber dass sich der wert ständig ändert, also dass der adc
> ständig wandelt...
>
> nur weiß ich leider nicht wie ich das programmtechnisch lösen soll ...

Hast du doch im Prinzip schon.
Du hast alles in eine while(1) Schleife gepackt.
Damit wird es ständig wiederholt.
Allerdings ist am Ende der Schleife ein Aufruf von
wait_until_key_pressed();
und diese Funktion ist reichlich kryptisch. Nur durch
schnelles Hinschauen kann ich in 30 Sekunden nicht sagen,
ob diese Funktion korrekt ist oder nicht.

Ich würde den Aufruf einfach mal rausschmeissen.

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