Festkommaarithmetik + ADC

Gast #1604912
Lesenswert?

Nabend,
seit geraumer zeit beschäftige ich mich jetzt mit der 
Festkommaarithmetik, das Tutorial habe ich soweit verstanden und ich 
glaube der Wurm liegt an einer anderen Stelle :(
1
void my_itoa(int32_t zahl, char* string) {
2
  uint8_t i;
3
 
4
  string[11]='\0';                  // String Terminator
5
  if( zahl < 0 ) {                  // ist die Zahl negativ?
6
    string[0] = '-';              
7
    zahl = -zahl;
8
  }
9
  else string[0] = ' ';             // Zahl ist positiv
10
 
11
  for(i=10; i>=1; i--) {
12
    string[i]=(zahl % 10) +'0';     // Modulo rechnen, dann den ASCII-Code von '0' addieren
13
    zahl /= 10;
14
  }
15
}
und die Ausgabe auf dem LCD
1
void my_print_LCD(char* string, uint8_t start, uint8_t komma, uint8_t frac) {
2
 
3
  uint8_t i;            // Zähler
4
  uint8_t flag=0;       // Merker für führende Nullen
5
 
6
  // Vorzeichen ausgeben  
7
  if (string[0]=='-') lcd_data('-'); else lcd_data(' ');
8
 
9
  // Vorkommastellen ohne führende Nullen ausgeben
10
  for(i=start; i<komma; i++) {
11
    if (flag==1 || string[i]!='0') {
12
      lcd_data(string[i]);
13
      flag = 1;
14
    }
15
    else lcd_data(' ');         // Leerzeichen
16
  }
17
 
18
  lcd_data(',');                // Komma ausgeben
19
 
20
  // Nachkommastellen ausgeben
21
  for(; i<(komma+frac); i++) lcd_data(string[i]);
22
 
23
}
Alle klar so soweit.

ich lesen den ADC ein und Multipliziere ihn mit k = 586 die zahl ist 
dann maximal ~600000
1
#include <avr/io.h>
2
#include <stdlib.h>
3
#include "lcd-routines.h"
4
#include <util/delay.h>
5
#include "cpu-routines.h"
6
#include <stdint.h>
7

8

9
char mein_string[10];
10
unsigned long x;
11
int k=586; // mit 1,10,100 getestet siehe unten
12

13
int main(void)
14

15
{   cpu_init();
16
    lcd_init();
17

18

19
    while(1)
20
  {  
21
        x = ReadChannel(0) * k; // ADC 0 lesen mit k Multiplizieren 
22
        my_uitoa(x,mein_string); // 
23
        my_print_LCD(mein_string, 0, 10, 0);
24
  }
25
}
Soweit so gut auf dem Display werden jetzt auch die Werte korrekt bis 
~32000 angezeigt wenn ich k auf 1,10,100 stell. ab ~32000 gibt es dann 
aber einen Sprung :( und alles spinnt. Ich denke es liegt an der 
Multiplikation aber warum?

vielleicht hat jemand einen Tip?!

lg Malte
#1604927
Lesenswert?

@Malte (Gast)
1
        x = ReadChannel(0) * k; // ADC 0 lesen mit k Multiplizieren

>~32000 angezeigt wenn ich k auf 1,10,100 stell. ab ~32000 gibt es dann
>aber einen Sprung :( und alles spinnt. Ich denke es liegt an der
>Multiplikation aber warum?

32000 klingt verdächtig nach Zahlengrenze bei int ;-)

>vielleicht hat jemand einen Tip?!

Die Zeile oben ist der Übeltäter, klassischer Fehler bei C. Versuchs mal 
damit, k als unsigned long zu deklarieren. Oder mit einem cast
1
        x = ReadChannel(0) * (long)k; // ADC 0 lesen mit k Multiplizieren

Denn die RECHNUNG wird in INT durchgeführt, weil das der größte 
Zahlenbereich der Variablen rechts ist. Dabei kommt es zu einem 
Überlauf. Erst danach wird in unsigned long umgewandlet :-0

MFG
Falk

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