Forum: Mikrocontroller und Digitale Elektronik negative Berechnung der Temperatur


von M. B. (marko_b10)


Lesenswert?

Hallo alle zusammen,
ich habe eine Leiterplatte mit dem "Atmel AT90PWM316" und 4 
7-Segment-Anzeigen.

Mein Problem ist jetzt aber, dass die Angezeigte Temperatur im positiven 
Bereich in Ordnung ist aber im negativen Bereich "komische" Werte 
(z.B.948) angezeit werden.


Hier erst einmal der Code:
1
#include <avr/io.h>
2
#include <util/delay.h>     
3
4
5
unsigned int ADC_value, zahl, x, ergebniss;
6
unsigned char einer, rest, zehner, hunderter;
7
8
9
#define T1 0xEF    // Transistor 1 = ON
10
#define T2 0xDF    // Transistor 2 = ON
11
#define T3 0xBF    // Transistor 3 = ON
12
#define T4 0x7F    // Transistor 4 = ON
13
14
15
16
void wert_zerlegen (void)
17
{
18
  einer       = ADC_value % 10;  // Einer
19
  rest        = ADC_value / 10;    
20
  zehner      = rest % 10;    // Zehner
21
  hunderter   = rest / 10;    // Hunderter  
22
}
23
24
25
void main (void)
26
{
27
  DDRB   = 0xFF;    // Richtungsregister Port B auf Ausgang
28
  DDRC  = 0xFF;    // Richtungsregister Port C auf Ausgang
29
  PORTB   = 0xFF;    // Port B = High (7-Segm. Anzeige OFF)
30
  PORTC  = 0xFF;    // Port C = High (Transistoren sperren)
31
32
33
34
    //****  Init ADC ****
35
  ADCSRA  |= 1<<ADEN;      // ADC aktivieren
36
  ADCSRA  |= (1<<ADPS1)|(1<<ADPS2);  // Vorteiler auf 64
37
  ADMUX  |= (1<<REFS0)|(1<<REFS1);  // Einstellung Uref = 2,56V
38
  ADMUX  |= (1<<MUX0);      // ADC1 (PIN PD4) als ADC-Kanal definieren
39
40
  ADMUX  |= (0<<ADLAR);  // Ausgabe = linksbündig
41
  DIDR0  |= 1<<ADC1D;  // Digital Input Kanal ADC1D disabled
42
43
// nach Aktivieren des ADC wird ein "Dummy-Readout" empfolen, man liest
44
// also einen Wert ein und verwirft diesen, um den ADC "warmlaufen zu lassen"
45
46
47
48
49
  const unsigned char segmenttable[11] = 
50
  { 
51
  // Wertetabelle der 7-Segmentcodierung:
52
    0x03,  0xF3,   0x25,   0x0D,   0x99,   0x49,   0x41,   0x1F,   0x01,   0x19,   0xFE
53
  };
54
//  0  1  2  3  4  5  6  7     8    9    dp  
55
  
56
57
58
59
60
  ADCSRA  |= (1<<ADSC);    // Start ADC-Wandlung
61
  while (ADCSRA & (1<<ADSC));     // auf Abschluss der Konventierung warten
62
    x=ADC;      // Ergebnis der nächsten Wandlung nicht übernommen
63
64
65
  while (1)
66
  {    
67
68
      zahl ++;
69
    
70
      if(zahl == 50)    // wenn "zahl" 50
71
      {
72
        ADCSRA |= (1<<ADSC);      // Start ADC-Wandlung
73
        while (ADCSRA & (1<<ADSC));    // auf Abschluss der Konvertierung warten
74
        ADC_value = ADC;
75
        ADC_value = (ADC-200)/4+2;    // Anpassung an die Temperaturkennlinie (y=kx+d) + Korrekturfaktor
76
        zahl = 0;
77
78
        if(ADC_value < 0)
79
        {
80
          PORTB = T4;
81
          PORTC = 0xFD;
82
          _delay_ms(5);
83
        }
84
        
85
        if(ADC_value >= 0)
86
        {
87
88
        wert_zerlegen();
89
90
        
91
        PORTB = T1;              // Anzeige 1 aktivieren
92
        PORTC = segmenttable [einer];    // Ausgabe der EINER auf 1. Anzeige
93
        _delay_ms(5);
94
95
        PORTB = T2;              // Anzeige 2 aktivieren
96
        PORTC = segmenttable [zehner];    // Ausgabe der ZEHNER auf 2. Anzeige
97
        _delay_ms(5);
98
99
        PORTB = T3;              // Anzeige 3 aktivieren
100
        PORTC = segmenttable [hunderter];  // Ausgabe der HUNDERTER auf 3. Anzeige 
101
        _delay_ms(5);
102
103
        }  
104
          
105
      }      
106
107
  }
108
}


jetzt ist der Code so geschrieben, dass er "-" anzeigen soll wenn die 
Temperatur unter 0°C ist, aber wie berechne ich jetzt negative 
Temperaturen ?


freu mich auf antworten :)

von M.A. (Gast)


Lesenswert?

Du malst das "-"-Zeichen hin und gibst den Betrag der Temperatur 
formatiert aus.

von Peter B. (pbuenger)


Lesenswert?

Du musst selbstverständlich bei negativen Temperaturen ausse dem "-" 
auch die Temperatur selbst negieren: ADC_value = 0 - ADC_value;

Peter

von MaWin (Gast)


Lesenswert?

So lange ADC_value ein unsigned int ist, wird
if(ADC_value < 0) nie erfolgreich sein.

Und mit if(ADC_value >= 0) kannst du auch nicht
erwarten, daß eine negative Zahl jemals erscheint,
ADC_value = -ADC_value sollte vorher stattfinden.

Desweiteren ist es nicht so richtig cool,
bei positiven Zahlen die Stellen 1/3 der Zeit
an zu lassen, und bei negativen Werten 1/4
der Zeit. Auch bei positiven Zahlen sollte der
delay_5ms für T4 durchgeführt werden, nur mit
PORTB=0xFF

von M.A. (Gast)


Lesenswert?

In der Annahme, das ADC_value nach der Kennlininenrechnung die 
berechnete Temperatur/°C enthalten soll, müßte die Variable für negative 
Temperaturen als vorzeichenbehaftet deklariert werden.

M. B. schrieb:
> unsigned int ADC_value

Damit kann das nicht funktionieren.

von M. B. (marko_b10)


Lesenswert?

MaWin schrieb:
> Und mit if(ADC_value >= 0) kannst du auch nicht
> erwarten, daß eine negative Zahl jemals erscheint,
> ADC_value = -ADC_value sollte vorher stattfinden.

wenn ADC_value = -ADC_value ist, wie soll ich dann die positive 
Temperatur berechnen ?

von MaWin (Gast)


Lesenswert?

> wie soll ich dann die positive Temperatur berechnen ?

Schau doch mal was Peter Bünger schon geschrieben hat.

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.