He Leute,
Meine Hardware:
Atmega32
LCD HD44780
Hilfe aus diesen Tut genommen:
http://www.mikrocontroller.net/articles/FAQ#itoa.28.29_.28utoa.28.29.2C_ltoa.28.29.2C_ultoa.28.29.2C_ftoa.28.29_.29
Habe es zum laufen gebracht auch danke der hilfe dieses Forums =)
Aber ein neues Problem tut sich auf.
Ich will eine Zahl mit 2 Kommastellen am LCD ausgeben.
Das Programm dazu habe ich selbstgeschrieben und es tut unter Windows
auch das was es soll.
Rechenwert = 9,77 diesen multipliziere ich mit 100 und bekomme so 977.
Wenn ich den Rechenwert dann mit einem analogen Wert (der korrekt
eingelesen wird 0-1023) multipliziere erhalte ich das 100fache und somit
2 Kommastellen.
So ist es auch im genannten Tut.
Hier mein Code:
Das Programm mit dem das Komma gesetzt wird:
1
voidkomma(longz,intrechenwert,char*Fertig)
2
{
3
inti=1,j=1;
4
5
charBuffer[20]={0};
6
7
8
9
z=z*rechenwert;
10
if(z<0){//Vorzeichen kontrolle
11
Buffer[0]='-';//wenn - dann in [0] '-' schreiben
12
z*=-1;//z auf postiven Wert bringen
13
}
14
else
15
Buffer[0]=' ';//wenn + dann Vorzeichen weglassen
16
17
for(i=i;z>0;i++){
18
Buffer[i]='0'+z%10;//Restwert in Buffer[i] schreiben, so
19
//wird der Wert verkehrt in Buffer
20
//geschrieben
21
z=z/10;
22
}
23
24
Fertig[0]=Buffer[0];//Fertig = Fertig für die Ausgabe, hier wird das Vorzeichenübernommen
25
26
for(i=19;i>0;i--){//Hier wird der Wert wieder richtig gestellet (umgedreht)
27
if(Buffer[i]>0){
28
Fertig[j]=Buffer[i];
29
j++;
30
}
31
}
32
33
for(i=19;i>0;i--){//Hier werden die letzten 2 Ziffern in "Fertig" gesucht um 1 Array verschoben
34
if(Fertig[i]>0){//und ein Punkt/Komma gesetzt
35
j=i+1;
36
Fertig[j]=Fertig[i];
37
i--;
38
j=i+1;
39
Fertig[j]=Fertig[i];
40
j--;
41
Fertig[j]='.';
42
break;
43
}
44
}
45
46
47
48
}
49
50
Hierdiemain();
51
52
#include<avr/io.h>
53
#include<util/delay.h>
54
#include<stdlib.h>
55
56
#include"analog.h"
57
#include"lcd-routines.h"
58
#include"komma.h"
59
60
61
#define Schalter PA3
62
63
64
#define LED1 PC0
65
#define LED2 PC1
66
#define LED3 PC2
67
#define LED4 PC3
68
#define LED5 PC4
69
#define LED6 PC5
70
#define LED7 PC6
71
#define LED8 PC7
72
73
#define BitmaskP0 0b00000001
74
#define BitmaskP1 0b00000010
75
#define BitmaskP2 0b00000100
76
#define BitmaskP3 0b00001000
77
#define BitmaskP4 0b00010000
78
#define BitmaskP5 0b00100000
79
#define BitmaskP6 0b01000000
80
#define BitmaskP7 0b10000000
81
82
83
84
intmain(void)
85
{
86
87
uint16_tadcval;
88
89
90
ADC_Init();
91
lcd_init();
92
93
94
lcd_setcursor(0,1);
95
lcd_string("Wert:");
96
lcd_setcursor(0,2);
97
//lcd_string("Temp:");
98
//lcd_setcursor( 6, 2);
99
100
101
//temp[0]='1'; temp[1]='1'; temp[2]='.'; temp[3]='1'; temp[4]='1'; //So gibt er die Ziffern einzeln mit Komma aus.
102
103
104
while(1){
105
106
adcval=ADC_Read(4);// Kanal 0
107
108
109
110
lcd_setcursor(6,1);
111
charBuffer[20];
112
itoa(adcval,Buffer,10);
113
lcd_string(Buffer);
114
115
chartemp[20];
116
lcd_setcursor(0,2);
117
komma(adcval,977,temp);
118
lcd_string(temp);
119
120
_delay_ms(200);
121
lcd_setcursor(6,1);
122
lcd_string(" ");
123
lcd_setcursor(6,2);
124
lcd_string(" ");
125
126
}
127
}
Aber aus irgendeinen Grund läuft das Programm zwar unter Windows am PC
richtig, wenn ich in der Konsole starte, aber am Atmega32 nicht.
Vorzeichen stimmt immer.
Die Zahl selbst auch.
Vom errechneten Wert werden alle Ziffern ausgeben.
Wenn der analog Wert 700 ist, ergibt sich somit 6839,00.
Am LCD steht dann 683900 und 3 weitere unleseliche Zeichen.
Woran liegt das ?
Und sry falls mein Programm für manche vlt schrecklich aussieht, weil es
auch einfacher gehen würde :o
Danke für eure Lehren =)
for(i=19;i>0;i--){//Hier wird der Wert wieder richtig gestellet (umgedreht)
müssen bei dir die Alarmglocken zu schrillen anfangen.
Es geht um die 19 hier.
Du weißt doch aus der vorhergehenden Zerlegeschleife, wieviele Zeichen
du generiert hast. Dein i enthält genau diese Information. Benutze sie!
Und mach nicht solche Spielchen wie 'Ich geh durch das Array als ganzes
durch und nur wenn der char größer 0 ist, dann ...'. Denn wenn du ein
Array in einer Schleife mehrmals benutzt, dann werden da eben CHaracter
Leichen nach dem eigentlichen String noch im Array stehen.
> Am LCD steht dann 683900 und 3 weitere unleseliche Zeichen.
So was ist meistens ein Indiz für eine von 2 Möglichkeiten
* die 0-Terminierung des Strings stimmt nicht (und ich sehe nicht, das
bzw. wie du dich in deiner Komma Funktion darum kümmern würdest)
* oder aber der Effekt entsteht dadurch, dass am LCD ein Text durch
einen anderen, kürzeren Text überschrieben wird.
Bei dir ist es aber wahrscheinlich die fehlende bzw. inkorrekte
0-Terminierung. Wenn du in einem Array nach und nach einzelne Zeichen zu
einem String zusammenbaust, dann darfst du nicht vergessen, dass nach
dem letzten Zeichen noch ein Zeichen mit dem Wert '\0' kommen muss,
welches allen String-verarbeitenden Funktionen anzeigt, dass hier der
String zu Ende ist.
Peter II schrieb:> Avr Noob schrieb:>> z bleibt sehr lange groesser 0!>> nein, denn ein Long kann keine nachkomma stellen speichern.>> 6839 / 10 = 683,9 > 0> 683 / 10 = 68 > 0> 68 / 10 = 6 > 0> 6 / 10 = 0
UUUPS, sorry, alles zurueck!
Natuerlich, ich hatte double im kopf.
for(i=19;i>0;i--){//Hier wird der Wert wieder richtig gestellet (umgedreht)
2
if(Buffer[i]>0){
3
Fertig[j]=Buffer[i];
4
j++;
5
}
6
}
7
8
for(i=19;i>0;i--){//Hier werden die letzten 2 Ziffern in "Fertig" gesucht um 1 Array verschoben
9
if(Fertig[i]>0){//und ein Punkt/Komma gesetzt
10
j=i+1;
11
Fertig[j]=Fertig[i];
12
i--;
13
j=i+1;
14
Fertig[j]=Fertig[i];
15
j--;
16
Fertig[j]='.';
17
break;
18
}
19
}
ist deutlich zu kompliziert.
Du könntest den Dezimalpunkt auch in der ersten Schleife mit wenig
Aufwand einfach an der richtigen Stelle einbauen und dann gleich auch
noch das Problem beseitigen, dass du hast, wenn deine auszugebende Zahl
zb eine glatte 0 mit keinen Nachkommastellen ist.
Wobei eine glatte 0 in der Ausgabe sowieso noch Probleme macht, denn
hier
1
for(i=i;z>0;i++){
wird das überhaupt nicht berücksichtigt und du erhälst aus der
Ziffern-Zerlegung einen leeren String.
wow, da kamen viele Antworten auf einmal =)
Danke an jeden einzelnen!!!
Ja die Arrays habe ich nicht geleert und deswegen stand da auch immer
wieder viel unsinniges am LCD!
Habe es so gelöst (nicht schön aber wirkt)
1
voidkomma(longz,intrechenwert,char*Fertig)
2
{
3
inti=0,j=0,v;
4
5
charBuffer[20]={0};
6
7
for(i=19;i>0;i--){
8
Fertig[i]=' ';
9
Buffer[i]=' ';
10
}
11
12
z=z*rechenwert;
13
if(z<0){//Vorzeichen kontrolle
14
Buffer[0]='-';//wenn - dann in [0] '-' schreiben
15
z*=-1;//z auf postiven Wert bringen
16
v=0;
17
i=1;
18
j=1;
19
}
20
else
21
v=-1;
22
23
for(i=i;z>0;i++){
24
Buffer[i]='0'+z%10;//Restwert in Buffer[i] schreiben,
25
z=z/10;//so wird der Wert verkehrt in Buffer geschrieben
26
}
27
28
Fertig[0]=Buffer[0];//Fertig = Fertig für die Ausgabe,
29
//
30
for(i=19;i>v;i--){//Hier wird der Wert wieder richtig gestellet (umgedreht)
31
if(Buffer[i]!=' '){
32
Fertig[j]=Buffer[i];
33
j++;
34
}
35
}
36
37
for(i=19;i>v;i--){//Hier werden die letzten 2 Ziffern in "Fertig" gesucht um 1 Array verschoben
38
if(Fertig[i]!=' '){//und ein Punkt/Komma gesetzt
39
j=i+1;
40
Fertig[j]=Fertig[i];
41
i--;
42
j=i+1;
43
Fertig[j]=Fertig[i];
44
j--;
45
Fertig[j]='.';
46
break;
47
}
48
}
49
}
Das mit dem for (i=i;... ist wirklich nicht gut, ich weis.
Führt leicht zu fehlern wenn man die Schleife wieder verwendet aber hier
stört es soweit nicht.
Bin am lernen also bei Learning by doing ^^
Ist ewig her, dass ich programmiert habe und somit habe ich vieles
vergessen.
Werde aufjedenfall noch das Programm erweitern bzw. verfeinern.
Danke jeden der sich die mühe gemacht hat =)
Weiter vorschläge nehme ich gerne an.