ADC, uint16_t und Multiplikationsproblem

OP #885393
Lesenswert?
• ▲
▼
Hallo zusammen,

vllt. ist das Problem leicht behoben, ich schätze ich mache einen 
Denkfehler. Also zuerst mal die Theorie welche dahinter steht.
Ich habe eine Strom und eine Spannungsmessung. Beide werden über OP's 
verstärkt. Beim Strommess-OP kommen hinten max. 2V raus, beim 
Spannungs-OP max. 2,5V(im Test kommen immer um die 1,75V raus, da 
konstante Spannung). Nun nehme ich die Werte mit dem ADC auf(10Bit, 
Referenz sind 2,56V).
Nun habe ich ein Programm geschrieben, welches mir den Strom, über ein 
PWM Signal mit anschließender Elektronik, einstellt.
Ich hatte dann in meinem Programm zwei Abfragen, welche mir Strom und 
Spannung überwachen und bei überschreiten eines bestimmten Stromes 
anhalten und den Strom auf den eingestellten Wert begrenzen. Soweit 
funktionierte das. Nun wollte ich aber nicht mehr über Strom und 
Spannung begrenzen, sondern über die Leistung.
Also einfach die Werte multiplizieren und fertig. Aber er läuft immer 
bis ans Ende der Schleife. Hat das vllt. was mit den Datentypen zu tun? 
Strom und Spannung sind uint16_t Typen, die Leistung muss dann also ein 
uint32_t Typ sein (16Bit*16Bit=32Bit). Denk ich mir zumindest! Der µC 
ist ein Mega32. Ich häng mal nur den Source vom eigentlichen Programm 
an, da der ADC und die PWM funktionieren.
1
int main(void)
2
{
3
/* PWM starten */
4
PORTB = 0x00;  //Alle Bit's löschen
5
DDRB = 0xFF;  //PortB als Ausgang beschalten für die PWM
6
PWM_init();    //Die PWM starten
7

8

9
uint8_t const pwmoffset = 126;  //ADC Offset von 2,5V(2^8*0.5)
10
                                //Der Offset wird von der Elektronik
11
                                //dahinter benötigt
12

13
uint8_t DC = 0;        
14

15
int x=1;
16
uint16_t strom=0;
17
uint16_t spannung=0;
18
uint32_t leistung=0;
19

20
while(1)  //Endlosschleife für den µC
21
{
22

23
/* TESTPROGRAMM */
24
while(x==1)
25
{
26
        //for-Schleife soll langsam den Strom erhöhen, PWM ist DAC als
27
        //Sollwertgeber für einen Tiefpass für die Elektronik
28

29
  for(int i=0; i<=30; i++)
30
  {
31
    OCR0 = pwmoffset + i;
32
    Delay(); //Delay() ist ne Wartefunktion von mir
33
    Delay();
34
    strom = ADCRead(2);
35
    Delay();
36
    spannung = ADCRead(1);
37
    Delay();
38
    leistung = strom * spannung;
39
    if(leistung>=60000) //Wenn die Leistung einen bestimmten
40
                                    //Wert überschreitet, stehenbleiben
41
    {
42
      i=40;
43
      x=0;
44
    }    
45
  }
46
  x=0;
47
}
48

49
/* ENDE WHILE SCHLEIFE!!! */
50
}
51

52
return 0; //Damit der Compiler nicht meckert, der Punkt wird allerdings nie erreicht!
53
}

Meine Vermutung liegt irgendwie darin, das er beim berechnen der 
Leistung ein Problem hat. Mit einer getrennten Abfrage von Strom und 
Spannung klappt's ja.
Kann das was mit dem uint32_t zu tun haben?
Hoffe das die Beschreibung in soweit verständlich ist!!!

Gruß Daniel
OP #885435
Lesenswert?
• ▲
▼
Das "break", nein da hab ich nicht mehr dran gedacht, ist alles schon 
etwas länger her. Werd ich aber versuchen. Aber wie gesagt, vorher bei 
der Stromabfrage hat's ja geklappt.
Die Werte des ADC liegen für
1) Strom bei 0 bis 80 (Ausgabe des ADC in Decimal)
2) Spannung bei 0 bis 700 (Ausgabe des ADC in Decimal)

Zu 1) 80 entspricht etwa 1A, bei dem er dann anhalten soll, was er auhc 
macht
Zu 2) Ich habe eine konstante Eingangsspannung von etwa 30V, das ergibt 
dann die 700.

Multipliziere ich die beiden Werte und überprüfe das Produkt, dann läuft 
er die Schleife bis zum Ende durch. Aber warum ist mir unerklärlich.
#885546
Lesenswert?
• ▲
▼
Hast du auch verstanden, warum das so ist?

Deine Variable 'leistung' ist zwar ein uint32_t, aber das
interessiert bei der Multiplikation herzlich wenig.

Bei jeder arithmetischen Operation sieht sich der Compiler
die beteiligten Operanden an. In deinem (ursprünglichen) Fall
sind das 2 Stück uint16_t. Also wird die Multiplikation auch
als 16 Bit unsigned Multiplikation ausgeführt. Erst danach
wird nachgesehen, was mit diesem Ergebnis passieren muss, damit
es in einen uint32_t geschoben werden kann.

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