Forum: Mikrocontroller und Digitale Elektronik Atmega128 Differenzspannung wird falsch berechnet.


von Jan S. (simpson1991)


Angehängte Dateien:

Lesenswert?

Hallo, ich habe folgendes Problem:
Ich möchte mir über den ADC die Differenzspannung zwischen F0 und F1 an 
einem Display ausgeben lassen.
Das Datenblatt des Atmega gibt dafür den MUX 10000 an.
Das Problem ist, dass beide Spannungen 5v und (0v-5v) addiert statt 
subtrahiert werden.
Weiß jemand wieso?

Edit: Sehe grad die Kommentare sind etwas durcheinander, hoffe dass 
stört nicht. :)




1
/*
2
 * AD-Wandler.c
3
 *
4
 * Created: 18.12.2017 11:27:10
5
 * Author : Sch
6
 */ 
7
8
#include <avr/io.h>
9
#include "lcd.h"
10
#define F_CPU 16000000UL
11
#include <util/delay.h>
12
13
14
int main(void)
15
{
16
  DDRB |= 0x00;//Eingang
17
  DDRC |= 0xFF;//Ausgang
18
  DDRF |= 0x00;//Eingang
19
  DDRG |= 0xFF;//Ausgang
20
  PORTC = 0;//PORTC ausschalten
21
  PORTF = 0;//PORTF ausschalten
22
  PORTG = 0;//PORTG ausschalten
23
  
24
  uint16_t wert1; // Deklarierung der Variable “wert1”
25
  uint16_t wert2; // Deklarierung der Variable “wert2”
26
  uint16_t wert3;
27
  
28
  char oupt1[20];
29
  char oupt2[20];
30
  
31
  lcd_init();
32
  
33
  ADMUX |= (0<<REFS1)|(1<<REFS0);//interne Referenzspannung an, AVCC als
34
            //Referenzspannungsquelle gewählt
35
  ADMUX |= (0<<MUX0) | (0<<MUX1) | (0<<MUX2) | (0<<MUX3) | (1<<MUX4);//PORTF0-PORTF1 mit Gain x1 
36
  ADMUX &= ~(1<<ADLAR);//ADC Right adjustment ist aktiviert
37
            //niederwertiges Byte im ADCL Register
38
            //des AD-Wandlers
39
            
40
  ADCSRA |= (1<<ADPS1)|(1<<ADPS0);//AD-Wandler-Rate auf 1/8 der Quarzfrequenz
41
                  //(hier = 16/8 MHz = 2 MHz)
42
  ADCSRA |= (1<<ADEN);//AD-Konverter "enablen" (=einschalten)
43
  ADCSRA &= ~(1<<ADIE);//Interrupt Modus ausschalten
44
  ADCSRA &= ~(1<<ADFR);//AD-Konverter läuft nicht im free running
45
            //mode (Es wird nur ein Einzelevent gewandelt)
46
            
47
  ADCSRA |= (1<<ADSC);//AD-Konverter einschalten Start Einzel-
48
            //Konversion
49
  
50
  while(ADCSRA & (1<<ADSC) ) {} //warten bis ADSC Bit gelöscht wird und ADC
51
                //fertig ist
52
  
53
    while(1)
54
    {
55
    
56
    ADCSRA |= (1<<ADSC); //“AD Start conversion” startet Konvertierung
57
    
58
    while(ADCSRA & (1<<ADSC)){} //warten bis ADSC Bit wieder von selbst gelöscht wird
59
    
60
    wert1 = ADCL;
61
        wert1 |= (ADCH << 8);              //(AD Konverter ist dann fertig)
62
    //wert1=ADCL+(256*ADCH);//Wert des AD-Konverters (10 bits als 2 x 8 Bit-Wert
63
              //aus 256 * Hi-Byte und Lo-Byte
64
    
65
    
66
    wert3=((REFS0*(ADCL+256*ADCH))/(1*512));//Dezimalwert in Volt
67
    
68
    
69
    itoa(wert1,oupt1,10);
70
    itoa(wert3,oupt2,10);
71
    
72
    lcd_clear();
73
    lcd_setcursor(0,1);
74
    lcd_string(oupt1);
75
    lcd_setcursor(0,2);
76
    lcd_string(oupt2);
77
    lcd_data('V');
78
    _delay_ms(50);
79
  }
80
  
81
  
82
}

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Ach wenn's nix mit deinem Problem zu tun hat...

Jan S. schrieb:
>   ADCSRA |= (1<<ADPS1)|(1<<ADPS0);//AD-Wandler-Rate auf 1/8 der
> Quarzfrequenz
>                   //(hier = 16/8 MHz = 2 MHz)

Der ADC schafft 2MHz ?

>     wert1 = ADCL;
>         wert1 |= (ADCH << 8);              //(AD Konverter ist dann
> fertig)

Besser: "wert1 = ADC;"

>     wert3=((REFS0*(ADCL+256*ADCH))/(1*512));//Dezimalwert in Volt

Nochmals Lesen und Byte-Frickel?

Besser: "wert3 = (REFS0 * wert1) / (1 * 512);"

Checken, ob die möglichen Werte von REFS0 nicht zu einem Überlauf des 
Zählers führen.  Falls dem so ist, mit 32 Bits rechnen lassen:

wert3 = (REFS0 * (uint32_t) wert1) / (1 * 512);

von Jan S. (simpson1991)


Lesenswert?

Danke, aber er addiert immer noch,.

von S. Landolt (Gast)


Lesenswert?

> wert3=((REFS0*(ADCL+256*ADCH))/(1*512));//Dezimalwert in Volt
?
REFS0 ist 6, was wird hier berechnet?

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.