Festkommaarithmetik + ADC

Gast #1604912
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
@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
Gast
Danke :D,
habe es im gleichen Moment im Forum entdeckt...
1
x = (unsigned long)ReadChannel(0) * k;

so habe ich es jetzt gemacht :), das war mir aber neu :D

aber ich denke dir!

lg Malte

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.