mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Berechnung immer Null warum?


Autor: Fabian Hof (Firma: keine) (eimer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

in meinem Programm möchte ich einen RMS ausrechnen, dazu benutze ich zum 
teilen ein Bitshift und eine fastsqrt die ich aus einem Interrupt 
anspringe. Jetzt kommt aber immer NULL ruas egal was ich mache?
Hoff jemand kann sich das erklären.
#include  <msp430x14x.h>
#include  <math.h>
#include  <inttypes.h>

unsigned int i=0;
unsigned long long int SUM_SIG1,SUM_SIG2,SUM_SIG3,SUMT_SIG1,SUMT_SIG2,SUMT_SIG3;
unsigned int RMS_SIG1,RMS_SIG2,RMS_SIG3;
unsigned long int MW_SIG1,MW_SIG2,MW_SIG3,Modulus_quadrature;
unsigned int Modulus;
int Measure;

static unsigned julery_isqrt(unsigned long val) {
      unsigned long temp, g=0, b = 0x8000, bshft = 15;
      do {
          if ( val >= ( temp = (((g << 1) + b)<<bshft--) ) ) {
             g += b;
             val -= temp;
          }
      } while (b >>= 1);
      return g;
  }

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  DCOCTL = DCO0 + DCO1 + DCO2;              //Max. CLK
  BCSCTL1 |= RSEL0 + RSEL1 + RSEL2;
  P4DIR |= 0xFF;                            // P4.0 output
  P4OUT=0;                                  //Reset Outputs
  //P5SEL |= 0xFF;                          //MCLK Rausführen
  P5DIR |= 0xFF;
  P5OUT=0;
  CCTL0 = CCIE;                             // CCR0 interrupt enabled
  CCR0 = 3;                                 //32768/4 =8192
  TACTL = TASSEL_1 + MC_1;                  // ACLK, upmode
  MW_SIG1=0;
  MW_SIG2=0;
  MW_SIG3=0;
  RMS_SIG1=0;
  RMS_SIG2=0;
  RMS_SIG3=0;
  SUM_SIG1=0;
  SUM_SIG2=0;
  SUM_SIG3=0;
  SUMT_SIG1=0;
  SUMT_SIG2=0;
  SUMT_SIG3=0;
  Modulus_quadrature=0;
  Modulus=0;
  Modulus_quadrature=0;
  Measure=0;
  _BIS_SR(LPM0_bits + GIE);                 // Enter LPM0 w/ interrupt I=85uA 
  while(1){
    if(Measure==1){
      P5OUT=0xFF;                //HIER KOMMT IMMER NULL RAUS
      MW_SIG1=SUMT_SIG1>>13;                   //Mean of RMS /j=8192 =>2^13
      MW_SIG2=SUMT_SIG2>>13;
      MW_SIG3=SUMT_SIG3>>13;
      RMS_SIG1=julery_isqrt(MW_SIG1);         //sqrt of RMS
      RMS_SIG2=julery_isqrt(MW_SIG2);
      RMS_SIG3=julery_isqrt(MW_SIG3);
      SUMT_SIG1=0;
      SUMT_SIG2=0;
      SUMT_SIG3=0;
      Measure=0;
      Modulus_quadrature=RMS_SIG1*RMS_SIG1+RMS_SIG2*RMS_SIG2+RMS_SIG3*RMS_SIG3;
      Modulus=julery_isqrt(Modulus_quadrature);
      P5OUT=0x00;
    }else{}
  };
}

// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
  P4OUT ^= 0xFF;                             // Toggle P1.0
  P6SEL |= 0x70;                            // Enable A/D channel A0
  ADC12CTL0 = ADC12ON+SHT0_0+MSC;           // Turn on ADC12, set sampling time
  ADC12CTL1 = ADC12DIV_0+ADC12SSEL_3+CONSEQ_1+SHP;  // Use sampling timer, set mode
  ADC12MCTL0 = INCH_4+SREF_0;               // channel = A4
  ADC12MCTL1 = INCH_5+SREF_0;               // channel = A5
  ADC12MCTL2 = INCH_6+EOS+SREF_0;           // channel = A6
  ADC12IE = 0x01;                           // Enable ADC12IFG.6
  ADC12CTL0 |= ENC;                         // Enable conversions
  ADC12CTL0 |= ADC12SC;                     // Start conversion
  i++;
}

#pragma vector=ADC12_VECTOR
__interrupt void ADC12ISR (void)
{
  unsigned long int ADC_SIG1,ADC_SIG2,ADC_SIG3;
    //P5OUT=0xFF;
    //TACTL = TASSEL_1 + MC_1;        TimerA off
  if(i<8192){
    ADC_SIG1=ADC12MEM0;
    ADC_SIG2=ADC12MEM1;
    ADC_SIG3=ADC12MEM2;
    SUM_SIG1 += ADC_SIG1 * ADC_SIG1;      //Sum over quadrature
    SUM_SIG2 += ADC_SIG2 * ADC_SIG2;
    SUM_SIG3 += ADC_SIG3 * ADC_SIG3;

    //P5OUT=0x00;
  }else{
    //ADC_SIG1=ADC12MEM0;
    SUMT_SIG1=SUM_SIG1;
    SUMT_SIG2=SUM_SIG2;
    SUMT_SIG3=SUM_SIG3;
    SUM_SIG1=0;
    SUM_SIG2=0;
    SUM_SIG3=0;
    Measure=1;              
    i=0;
    __low_power_mode_off_on_exit();           //I=300uA
  }
  //P5OUT=0x00;
  ADC12CTL0 &= ~ENC;                         // Enable conversions
}

Autor: Lehrmann Michael (ubimbo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab gerade nicht die Zeit mir das alles durchzulesen aber dein 
Problem dürfte sich "Typ-Cast" nennen.

Das ist C-Grundwissen:

beispiel

int x=8,y=66;
float erebnis;

ergebnis=x/y

-> ergebnis ist 0 !

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fabian Hof schrieb:

> Hoff jemand kann sich das erklären.

Premature Optimization is the root of all evil


Wenn du teilen willst, dann benutz auch eine Division.

Für den unwahrscheinlichen Fall, dass dein Compiler tatsächlich zu 
dämlich ist, eine Division durch eine 2-er Potenz durch eine 
Schiebeoperation zu ersetzen (Multiplikation ist dasselbe), kannst du 
hinten nach immer noch deinen Code zu einem "Obfuscated C Code 
Contest"-Beitrag umwandeln.

Aber zuerst machs richtig, dann machs schnell.

Ansonsten: Eingangswerte ansehen, Zwischenwerte ansehen, nachvollziehen 
was passiert.

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lehrmann Michael schrieb:
> int x=8,y=66;
> float erebnis;
>
> ergebnis=x/y
>
> -> ergebnis ist 0 !

Jo, das kann gut sein - mindestens ein Beteiligter in der Rechnung muss 
dann ebenfalls ein float sein.

Also:
int x = 8;
int y = 6;

float ergebnis;

ergebnis = (float) x / y;

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
volatile int Measure;

Wenn ich deinen Kommentar
      P5OUT=0xFF;                //HIER KOMMT IMMER NULL RAUS
wörtlich nehme, dann wird der if Teil nie betreten. Measure volatile 
machen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab ich Tomaten auf den Augen, oder wird in
#pragma vector=ADC12_VECTOR
__interrupt void ADC12ISR (void)
{

die Variable i überhaupt nie erhöht?

(i ist aber auch ein selten schlecht gewählter Name für eine globale 
Variable, die die Anzahl der Messungen mitprotokollieren soll. Gewöhn 
dir an: Globale Variablen - nicht weniger als 5 Zeichen im Namen.)

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> die Variable i überhaupt nie erhöht?

Die wird im Timer-Interrupt erhöht :)
Muß allerdings auch volatile sein.

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und wenn du sie im Interrupt erhöst, dann kann ein volatile auch nicht 
schaden.

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fabian Hof schrieb:
>   Modulus_quadrature=0;
>   Modulus=0;
>   Modulus_quadrature=0;
>   Measure=0;

Und welchen Sinn hat das hier?

Außerdem fehlt dir im ADC12CTL1 das CSTARTADD_x Bit, was du bei dir zu 
CSTARTADD_0 setzen musst.


Gruß, Dennis

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... schrieb:
> Karl heinz Buchegger schrieb:
>> die Variable i überhaupt nie erhöht?
>
> Die wird im Timer-Interrupt erhöht :)

Gefunden.
Ich würd sie trotzdem in den ADC Interrupt verfrachten.

Dann ist die Funktionalität nicht über 25 Funktionen verstreut.

Autor: Fabian Hof (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Leute morgen bin ich wieder an der Hardware dann werd ich alles machen 
was ihr sagt. Ich bedanke mich für die Nacht.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.