www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Festkommaarithmetik + ADC


Autor: Malte (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :(

void my_itoa(int32_t zahl, char* string) {
  uint8_t i;
 
  string[11]='\0';                  // String Terminator
  if( zahl < 0 ) {                  // ist die Zahl negativ?
    string[0] = '-';              
    zahl = -zahl;
  }
  else string[0] = ' ';             // Zahl ist positiv
 
  for(i=10; i>=1; i--) {
    string[i]=(zahl % 10) +'0';     // Modulo rechnen, dann den ASCII-Code von '0' addieren
    zahl /= 10;
  }
}
und die Ausgabe auf dem LCD

void my_print_LCD(char* string, uint8_t start, uint8_t komma, uint8_t frac) {
 
  uint8_t i;            // Zähler
  uint8_t flag=0;       // Merker für führende Nullen
 
  // Vorzeichen ausgeben  
  if (string[0]=='-') lcd_data('-'); else lcd_data(' ');
 
  // Vorkommastellen ohne führende Nullen ausgeben
  for(i=start; i<komma; i++) {
    if (flag==1 || string[i]!='0') {
      lcd_data(string[i]);
      flag = 1;
    }
    else lcd_data(' ');         // Leerzeichen
  }
 
  lcd_data(',');                // Komma ausgeben
 
  // Nachkommastellen ausgeben
  for(; i<(komma+frac); i++) lcd_data(string[i]);
 
}
Alle klar so soweit.

ich lesen den ADC ein und Multipliziere ihn mit k = 586 die zahl ist 
dann maximal ~600000

#include <avr/io.h>
#include <stdlib.h>
#include "lcd-routines.h"
#include <util/delay.h>
#include "cpu-routines.h"
#include <stdint.h>


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

int main(void)

{   cpu_init();
    lcd_init();


    while(1)
  {  
        x = ReadChannel(0) * k; // ADC 0 lesen mit k Multiplizieren 
        my_uitoa(x,mein_string); // 
        my_print_LCD(mein_string, 0, 10, 0);
  }
}
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

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Malte (Gast)
        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
        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

Autor: Malte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke :D,
habe es im gleichen Moment im Forum entdeckt...
x = (unsigned long)ReadChannel(0) * k;

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

aber ich denke dir!

lg Malte

Autor: Anja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
noch was:

char mein_string[10];

string[11]='\0';                  // String Terminator

Du Schreibst 2 Zeichen mehr in den String als darin platz haben.

Gruß Anja

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.