xmega_tutorial.jpg

Bewertung:  / 8
SchwachSuper 
  • jtronics_chip_ascii

Damit man eine Zahl, bzw. den Inhalt einer Variable auf einem Display oder per UART ausgeben kann, muss diese zunächst in ihrem Format umgewandelt werden, da meistens für die Ausgabe, Speicherung oder Übertraggung von Daten die sogenannte ASCII-Codieung verwendet wird. Für die Umwandlung einer einfachen Integer Variablen gibt es dazu die Funktion "integer to ascii", kurz "itoa()" welche diese Funktion übernimmt.

itoa( i, Buffer, 10 ) wandelt die Zahl i in ASCII-Zeichen um und speichert den entstandenen String der Zahl in den angegebenen Buffer. Bei der Funktion kann man noch die zu Wandlung zu verwendente Basis einstellen. Als basis kann man hier zum Beispiel folgende Zahlensysteme einstellen:

  • 2 für Binarsystem
  • 10 für Dezimalsystem
  • 16 für Hexadezimalsystem

10, 2 und 16 die häufigsten bei uns verwendeten Einstellungen für die Basis, jedoch kann itoa die Variable grundsätzlich in jedes beliebige Zahlensystem wandlen. Besonders wichtige ist es darauf zu achten, dass das Bufferarray groß genug ist, so dass auch der komplette String, inklusive der 0, die den String abschließt, sowie ein mögliches Vorzeichen der Zahl darin Platz hat.

itoa() ist keine C-Standardfunktion, so dass man bei einigen Compilern spezielle Bibliotheken einbinden. Es ist aber auch nicht besonders sich selber eine kleine Funktion zu schreiben die Umwandlung zum Beispiel für das Dezimalsystem erledigt. Das Grundprinzip der itoa Funktion ist relativ einfach. Die Ermittlung der einzelnen Stellen erfolgt in einer Schleife durch eine Division durch 10 und einer Restbildung (Modulo). Dadurch erhält man die einzelnen Ziffern der Zahl in umgekehrter Reihenfolge. Die falsche Reihenfolge kann man dadurch korrigieren, in dem man einfach den Buffer von hinten nach vorne füllt. Der Funktionsteil vor der 'Zerlegeschleife' behandelt den Sonderfall daß die Zahl negativ ist. Bei negativen Zahlen wird ein Minuszeichen an die erste Stelle des Buffers geschrieben und danach die Zahl positiv gemacht.

Die hier gezeigte Funktion erzeugt immer eine feste Anzahl an Stellen. Ist die Zahl kleiner, so werden alle Felder vor der Zahl mit "0" aufgefüllt.

example - itoa
void my_itoa(int32_t zahl, char* string)
{
uint32_t u;    
 
if( zahl < 0 )				
{                 
	string[0] = '-';              
	u = ((uint32_t)-zahl);
}
else 
{
	u = (uint32_t)zahl;
	string[0] = ' ';            
} 
 
for(uint8_t i=7; i>=1; i--) 
{
	// Modulo rechnen & ASCII von '0' addieren
 	string[i]=(u % 10) +'0';     
 	u /= 10;
}
// String Terminator (optional)
//string[11]='\0';                  
}

Da die Berechnung von Divisionen auf einem Microcontroller relativ rechenintensiv ist, habe ich nach einer Möglichkeit gesucht, wie man die itoa() Funktion für den Microcontroller vereinfachen, bzw. noch schneller gestalten kann. Mit der folgenden Lösung habe ich dabei die besten Ergebnisse erzielt. Statt einer Division mit Rest wird bei diesem Verfahren eine Subtraktionsschleife verwendet. In dieser wird die jeweilige Stelle der Zahl durch eine permanent Subtraktion von zum Beispiel 1000 die 1000der Stelle ermittelt, in dem nach jeder Subtraktion geprüft wird ob die Zahl noch größer 1000 ist. Parallelel werden die Iterationsdurchläufe der Schleife mitgezählt, denn diese beinhalten die darzustellende Ziffer. Der Funktionsteil vor der 'Zerlegeschleife' ist gleich dem bei der einfachen itoa Funktion. Wichtig ist nur, dass die Zahl vor dem Eintritt in die Schleife in "unsigned" konvertiert wird, wodurch die Berechnungen vom Controller schneller druchgeführt werden.

example - fast and fix itoa
void itoa_fix(const int32_t zahl, uint8_t *string)
{
uint32_t u;  
 
// ist die Zahl negativ?
// wenn ja "-" in String speichern
if( zahl < 0 )
{                 
	string[0] = '-';              
	u = (uint32_t)-zahl;
}
else 
{
	u = (uint32_t)zahl;
	string[0] = ' ';             // Zahl ist positiv
} 		
 
static const uint32_t subtractors[] = 
{ 1000000,100000,10000,1000, 100, 10, 1 };
 
for(uint8_t i=0; i<7; i++) 
{
	uint8_t n = '0';
	while (u >= subtractors[i])
	{
		n++;
		u -= subtractors[i];
	}
	string[i+1] = n;
}
}
Kommentar hinzufügen

Neuste Beiträge

30/08/2016
Es gibt nun endlich ein Update für die Tinyg CNC Controller Hardware und der dazu gehörenden PC Software...
03/09/2015
In den letzten Monaten habe ich lange das CAD Programm und meinen kleinen Ultimaker 3D Drucker gequält....
15/05/2015
Zuerst wurde eine kleine Katze am Computer konstruiert. Der erste Druck mit 0,3mm Schichtstärke war...
06/05/2015
Da beim Ultimaker keine Beleuchtung des Arbeitstisches vorgesehen ist, muss ich mir hier selber eine...