Meine Glaskugel sagt mir, dass DATA keine Variable ist, der du was
zuweisen kannst.
Aber ich verrate dir mal ein Geheimnis: Glaskugeln gibts nur bei Harry
Potter und leider nicht im richtigen Leben. Wie wärs also, wenn du uns
mit einem vollständigen Quellcode versorgst?
> 65 if (i & value) DATA=1; //masking value with i , write to
Vielleicht meinst du
65 if (i & value.i) DATA=1; //masking value with i , write to
jedenfalls kannst du nicht "pur" auf die Unionvalue zugreifen
Timo P. schrieb:
> #define DATA PORTA & (1<<1)>> verwendung ist DATA = 1;>> sollte doch eigentlich gehen oder? AStudio 4 mit Winavr
Nö. Bitmanipulation
Timo P. schrieb:
> #define DATA PORTA & (1<<1)>> verwendung ist DATA = 1;>> sollte doch eigentlich gehen oder?
Aha.
Dann spiel doch einfach mal Präprozessor
Aus
1
DATA=1;
wird
1
PORTA&(1<<1)=1;
Und jetzt erklär mit mal, was der Compiler da draus deiner Meinung nach
machen soll.
@ stefan, die union ist zu vergessen, hierbei geht es um value als
parameter der funktion. dies ist ein Byte, wo man einzelne bits
ausmaskiert. Diese Variable(zu versendende Daten) heiß zufälligerweise
auch "value".
mein prob ist glaube ich die verwendung von dem define DATA:
#define DATA PORTA & (1<<1)
verwendung ist:
DATA = 1; // das geht irgendwie nicht :(
Timo P. schrieb:
> @ stefan, die union ist zu vergessen, hierbei geht es um value als> parameter der funktion. dies ist ein Byte, wo man einzelne bits> ausmaskiert. Diese Variable(zu versendende Daten) heiß zufälligerweise> auch "value".
Ah. Habe ich übersehen.
Timo P. schrieb:
> mein prob ist glaube ich die verwendung von dem define DATA:>> #define DATA PORTA & (1<<1)> verwendung ist:> DATA = 1; // das geht irgendwie nicht :(
Da hast du recht.
So wird das nichts.
Verdammt, wie muss denn mein define aussehen?
Bei Infineon und Microvision gab es einen schönen sbit befehl, der hat
genau das gemacht, ein Bit ausmaskieren und einen handelbaren namen
dafür vergeben.
Timo P. schrieb:
> der compiler macht doch aus (1<<1) ne 00000010 wenn er diese mit rem> Register PORTA verundet, dann bleibt doch das einzelne Bit aus PORTA> über oder?
Ein Bit bleibst schon einmal gar nicht übrig, weil es das in C so nicht
gibt. Die kleinste Einheit, die für dich manipulierbar ist, ist ein Byte
in Form eines unsigned char.
Ein einzelnes Bit ist so nicht adressierbar (ausser man macht es mit
Bitfeldern in einer struct)
Timo P. schrieb:
> #define DATA PORTA & (1<<1)>> verwendung ist DATA = 1;>> sollte doch eigentlich gehen oder?
Nein. Das kann nicht gehen. DATA ist keine Variable, man kann ihr keinen
Wert zuweisen.
Vielleicht sollte es PORTA anstatt DATA heißen?
Oder
#define DATA PORTA
würde eventuell auch Sinn ergeben.
Timo P. schrieb:
> Verdammt, wie muss denn mein define aussehen?> Bei Infineon und Microvision gab es einen schönen sbit befehl, der hat> genau das gemacht, ein Bit ausmaskieren und einen handelbaren namen> dafür vergeben.
Und?
Warum baust du dir dann nicht einfach ein sbit nach?
Du bist Programmierer. Manchmal muss man sich eben seine Werkzeuge
selber machen, wenn die vorgefertigen nicht ausreichen.
Ist doch nicht schwer
Jo hätt ich auch selbst machen können. Manchmal kommt man halt nicht
selbst drauf. Im übrigen bin ich halt noch Anfänger, der zwar schon
einiges an Grundwissen hat, aber anscheinend einiges auch noch nicht...
Danke auf jeden Fall!
Sinn der sache wäre doch, eine define Zeile zu verwenden und dann
via "definetes wort" = 0; oder =1; schreiben zu können,
anstatt folgenden langen code verwenden zu müssen:
#define SBIT( wo, bit ) (wo) |= ( 1 << (bit) )
#define CBIT( wo, bit ) (wo) &= ~( 1 << (bit) )
#define DATA_PORT PORTA
#define DATA_BIT 5
und als Verwendung muss ich zu allem Übel noch zwei verschiedene Zeilen
nutzen um ein Bit zu setzen/rücksetzen:
SBIT( DATA_PORT, DATA_BIT ); oder:
CBIT( DATA_PORT, DATA_BIT );
Ich wünsche mir ein define, welches mir folgende Verwendung ermöglicht:
DATA = 1; oder DATA = 0; Und damit wird ein vorher (auf welche Weise?!?)
defineter Portpin getoggelt.
@Mark Brandis:
nein PORTA sollte nicht anstelle von DATA stehen, weil ich ja nicht den
ganzen PORT auf Hih stellen will, sondern lediglich einen einzigen PIN.
Wenn ich DATA als PORTA definen würde könnte ich ja problemlos den PORT
auf 0xFF oder 0x00 setzen. Aber wie gesagt, es geht um PIN-Toggeln
und zwar durch die Verwendung:
DATA = 0;
DATA = 1;
Timo P. schrieb:
> Ich wünsche mir ein define, welches mir folgende Verwendung ermöglicht:
Das kriegst man mit einem simplen #define nicht hin.
Dazu muss man sich im Kern eine Struktur mit einem Bitfeld bauen, dann
erledigt der Compiler den Schweinkram.
PeDa verwendet gerne so etwas. Aber wie die Details dazu aussehen, hab
ich auch nicht auswändig im Kopf.
Da bisher keiner eine Lösung hatte,
werde ich ausweichen und folgenden Umweg gehen müssen:
#define DATA_PORT PORTA
#define DATA_PIN (1<<5)
und nun JEDE Verwendung im GESAMTEN CODE :
von DATA = 1; in :
DATA_PORT |= DATA_PIN;
und :
von DATA = 0; in :
DATA_PORT &=~DATA_PIN;
ändern. :( Schade, dass es anscheinend nicht anders geht. Zum Glück gibt
es in allen editoren eine find+replace funktion......
DANKE trotzdem für die rege beteiligung an die Leute, die Anregungen
hatten
Gruß timo
So müsste es klappen.
Wenn man im DATA Makro anstelle der Konstanten für die Bitdefinition
selbst wieder Makros benutzen will, müsste man noch einen Umweg gehen.
1
structEinzelBit
2
{
3
uint8_tBit0:1;
4
uint8_tBit1:1;
5
uint8_tBit2:1;
6
uint8_tBit3:1;
7
uint8_tBit4:1;
8
uint8_tBit5:1;
9
uint8_tBit6:1;
10
uint8_tBit7:1;
11
};
12
13
#define SBIT( p, b ) ( ((struct EinzelBit*)(p))->Bit##b )
Ok Verwendung ist möglich!
RESPEKT an Kbuchegg
Wie kann ich denn nop() mit winavr nachbilden? Gerne möchte ich mal
wissen, wie nop() überhaupt aufgebaut ist, ob es wirklich ein
Funktionsaufruf ist und was er tut.(Oder wie er nichts tut)
M.a.W: Das ist exakt der Maschinenbefehl NOP. Inline, kein
Funktionsaufruf. Und was dieser Befehl macht steht in aller
Ausführlichkeit in Atmels Dokumentation.
Ahso also macht die Funktion einen Taktzyklus lang "nix" ;)
hier steht, dass dies eine genaue delay möglichkeit ist. Wird sie denn
oft als delay verwendet, auch wenn man timer benutzen kann?!?
>
wenn ich das kompiliere, meckert der rum, elf file does not exist!
kommentiere ich die oben genannte zeile aus, dann kompiliert der zwar,
aber kennt halt die nop()`s nicht...
Klar vorher hat er gemeckert, weil er die nop() funktionen nicht kannte.
mit der inline zeile habe ich aber als einzige Fehlermeldung die oben
angegebene, anstatt Fehler im Code zu sehen, wenn ich z.B. bewusst einen
syntaxfehler mache, semikolon weg oder so, dann sehe ich das nicht in
den fehlern, soweit kommt der garnicht.
also scheint die zeile:
static __inline void nop(void) { _asm_ volatile ("nop"); }
für mich quatsch zu sein.
"Vorher" meint: weiter vorne im Protokoll des Compilers. ELF ist das
Äquivalent des EXE-Files von PCs, d.h. er muss schon in den Zeilen davor
grösszügig darauf vezichtet haben, ein solches File überhaupt zu
erzeugen. Und das sollte einen Grund haben.
A. K. schrieb:
> Und das sollte einen Grund haben.
Da hast du wohl Recht mit deiner Aussage.....
Ich denke dass diese Inline-Funktion mein Problem ist.
Timo P. schrieb:
> Da hast du wohl Recht mit deiner Aussage.....> Ich denke dass diese Inline-Funktion mein Problem ist.
Kann schon sein, aber dann nur in grösserem Zusammenhang, vielleicht
doppelt definiert, nop als Makro, ... Denn Code wie
>Winavr mit Astudio habe ich...
Dann sollte es ja funktionieren (vorausgesetzt du meinst mit Astudio das
AVRStudio). Bei mir funktioniert es in dieser Kombination jedenfalls...
kann man
nop();
nicht durch :
variable++;
ersetzen?
Wie viele Taktzyklen benötigt das Inkrementieren einer Variable bei
einem Atmega-Controller? Soweit ich weiß, war das bei einem PIC
Controller so, dass 4 FOSC Zyklen einen Befehl ausmachen.
Wie ists Bei ATMEGAs fürs ....++;?
Timo P. schrieb:
> kann man>> nop();>> nicht durch :>> variable++;>> ersetzen?
Nein.
> Wie viele Taktzyklen benötigt das Inkrementieren einer Variable bei> einem Atmega-Controller?
Kommt drauf an. Mindestens 0 bis um die 80 Ticks.
Johann
Timo P. schrieb:
> AVR Studio 4.14.589> GUI Version 4, 14, 0, 589>>> und WINAVR 20080610>>> bei mir gehts nicht :(
Leg ein neues Projekt an, such dir einen Mega16 aus und kopiere diesen
Code in das vom AVR-Studio angelegte Source Code File
dann F7.
Kriegst du eine Fehlermeldung?
(Tu es aber wirklich! Nicht einfach nur sagen "bei mir gehts das nicht",
weil es in deinem realen Projekt, in dem du das letztendlich einsetzen
willst, nicht geht. Wir müssen jetzt erst mal aussortieren ob es ein
Problem in deiner generellen WinAVR/AVR-Studio Konfiguration gibt, oder
ob das Problem auf dein reales Projekt beschränkt ist)
Thomas W. schrieb:
> @ Johann>> Der Compiler Optimiert bei nichtverwendung einfach weg, oder ?> (Variable++;)
Nicht wenn die Variable als 'volatile' markiert ist...
Thomas W. schrieb:
> @ Johann>> Der Compiler Optimiert bei nichtverwendung einfach weg, oder ?> (Variable++;)
kommt drauf an.
Wenn die Variable als volatile markiert ist, kann er die Variable nicht
einfach wegoptimieren.
kommt auch drauf an, was das für eine Variable ist. Eine funktionslokale
oder filelokale Variable könnte er wegoptimieren. Eine globale Variable
kann er aber nicht so einfach wegoptimieren.
variable ++ ist ja eine verwendung der variable oder?
mal ne frage, mit ist bekannt, was volatile bedeutet.
ich kenne das nur beim anlegen von variablen, zb:
volatile unsigned char a;
gibt es auch eine möglichkeit einen Codeblock als volatile zu "machen" ?
zb durch irgendeine Präprozessoranweisung? WINAVR?
@ (kbuchegg): ich werde gleich mal ein neues Projekt für nen ATMEGA
anlegen....
die fehlermeldung, elf file does not exist kommt nicht mehr, wenn ich
eine funktion auskommentiere. Diese funktion ist komischerweise
fehlerfrei.
Kann es sein, dass WINAVR ab einer best. Codegröße zumzickt? In diesem
Projekt habe ich nämlich bisher nur eine C-File, sonst nix....
Was meint ihr? Werde auf jeden Fall mal alles aufspalten in schöne
main.h und diverse C-Files....
>Diese funktion ist komischerweise>fehlerfrei.
Zeig deinen Code!
>Was meint ihr? Werde auf jeden Fall mal alles aufspalten in schöne>main.h und diverse C-Files....
Jo, erstmal alles auseinanderreißen und noch mehr Fehler einbauen ;)
Timo P. schrieb:
> Kann es sein, dass WINAVR ab einer best. Codegröße zumzickt? In diesem> Projekt habe ich nämlich bisher nur eine C-File, sonst nix....
Wenn du in deinem Projekt 'bisher nur 1 C-File hast', dann ist klar
warum die Funktion lcd_clrscr() oder auch alle anderen lcd Funktionen
nicht gefunden werden.
Die sind in lcd.c drinnen und dieses File muss klarerweise auch mit in
das Projekt aufgenommen werden.
>> Was meint ihr? Werde auf jeden Fall mal alles aufspalten in schöne> main.h und diverse C-Files....
Grundsätzlich eine gute Idee, aber wenn du jetzt schon Schwierigkeiten
hast, das alles auf die Reihe zu kriegen, solltest du vielleicht etwas
warten, ehe du dir dein Projekt komplett zerstörst.
wenn ich verschiedene C-Files aus einer erzeuge, dann stehen einfach
einige funktionen in anderen c-files, baue ich damit dann gleich Fehler
ein?!? Verstehe ich nicht! Das musst du mir mal erklären!!!!!!!!!!
der code ist im Anhang!
vllt. ist ja doch nur die auskommentierte Funktion falsch!
calc_dewpoint() direkt vor main
aus besagter Funktion habe ich folgende Zeilen einzeln auskommentiert:
logEx=0.66077+7.5*t/(237.3+t)+(log10(h)-2);
//dew_point = (logEx - 0.66077)*237.3/(0.66077+7.5-logEx);
erst die eine, dann die andere. Wenn eine der Zeilen auskomm. ist, dann
kann ich den Code kompilieren, Wenn ich jedoch beide zeilen drin habe,
dann kann ich nicht kompilieren, kein elf file :(
MEGA 32!!
(code war ursprünglich für nen <AT89s53.h>)
AVR Memory Usage
----------------
Device: atmega32
Program: 6220 bytes (19.0% Full)
(.text + .data + .bootloader)
Data: 365 bytes (17.8% Full)
(.data + .bss + .noinit)
diese meldung bek. ich wenn ich calc_dewpoint() auskommentiere die fkt
und deren Aufruf
und die union value schmeisst du ganz raus.
Und wenn du schon dabei bist, dann korrigierst du auch noch das SBIT
Makro. Die Warnungen des Compilers sind nicht ohne Grund.
1
#define SBIT( p, b ) ( ((struct EinzelBit*)(&p))->Bit##b )
OH man danke für Antwort.
soll ich:
dew_point=calc_dewpoint(humi_val,temp_val); //calculate dew point
noch durch:
dew_point=calc_dewpoint(&humi_val,&temp_val); //calculate dew point
ersetzen??
Timo P. schrieb:
> soll ich:> noch durch:> ersetzen??
Wenn es dir Spass macht.
Aber denk immer an die erste Grundregel der Optimierung:
* Don't do it
Gefolgt von der 2.ten Grundregel
* Don't do it .... yet
Bring erst mal das Bisherige zum Laufen und teste es, ehe du anfängst
den Code zu verändern.
ging nur um die Art zu programmieren
funktion mit ....(*...)
und dann aufruf mit
....(&...);
oder funktion mit ...(char ...)
und dann aufruf mit
....(...);
also ob ich pointer nehme oder direkt die ganzen variablen übergebe.
nach meinem wissensstand übergibt man mit einer ganzen variable ihren
namen, ihren typ, ihren inhalt.
mit zeigern übergibt man doch nur den inhalt, indem man referenziert bzw
dereferenziert, richtig??
Timo P. schrieb:
> ging nur um die Art zu programmieren>> funktion mit ....(*...)> und dann aufruf mit>> ....(&...);>> oder funktion mit ...(char ...)> und dann aufruf mit>> ....(...);>> also ob ich pointer nehme oder direkt die ganzen variablen übergebe.>> nach meinem wissensstand übergibt man mit einer ganzen variable ihren> namen, ihren typ, ihren inhalt.>> mit zeigern übergibt man doch nur den inhalt, indem man referenziert bzw> dereferenziert, richtig??
Halte dich in C an die Regel
*************
Frage: Hat der Aufrufer eine Variable die er an die Funktion übergibt,
und muss diese Funktion in der Lage sein, diese Variable beim
Aufrufer zu ändern?
Ja: Übergib einen Zeiger
Nein: Übergib den Wert der Variablen
Zusatzfrage: Wenn nur eine Variable an eine Funktion übergeben wird UND
die Funktion diese Variable beim Aufrufer ändern können soll:
Was spricht dagegen, der Funktion KEINEN Pointer zu übergeben sondern
wie gehabt einen Wert, die Funktion berechnet einen neuen Wert und
liefert das Ergebnis als Returnwert der Funktion.
Der Aufrufer muss die Funktion dann so benutzen: a = foo( a );
Wenn nichts dagegen spricht, dann löse es über den Returnwert.
****************
Wenn du dieses Schema benutzt, wirst du in den meisten Fällen die
richtige Entscheidung treffen.
NB: Arrays sind da aussen vor, da Arrays sowieso immer per Pointer auf
das erste Element übergeben werden. Aber für alles andere kannst du
dieses Schema benutzen. Einzige Ausnahmen: Strukturen, bei denen eine
Übergabe per Wert ganz einfach eine teure Operation ist, weil das
Erzeugen der Kopie sowohl Laufzeit als auch Speicher frisst. Benutze
dann aber unbedingt einen const-Pointer, damit dir der Compiler
innerhalb der Funktion auf die Finger klopft, wenn du unzulässigerweise
unabsichtlich versuchst, den Wert eines Strukturmembers in der Funktion
zu verändern.
Aber Grundidee ist es immer: Übergib einen Pointer nur dann, wenn du
musst. Übergibst du per Wert, kann die Funktion in deinen Variablen
nichts anstellen. Übergibst du aber einen Pointer, kann die Funktion
beim Aufrufer Variablen verändern wie sie lustig ist. Bewährtes Ziel in
der Programmierung ist es immer, Änderungen in Variablen so lokal wie
möglich zu halten (daher wird auch in der Nicht-µC Programmierung das
Dogma "keine globalen Variablen" ausgegeben), damit Seiteneffekte
überschaubar bleiben.
Aufruf:
s_measure((unsigned char*) &humi_val_i, &checksum , HUMI);
worauf bezieht sich hier der typecast(unsigned char *) ? Auf alle
Parameter??
die funktion hat als parameter:
s_measure( unsigned char a*, unsigned char b*, unsigned char c)
also zwei pointer und eine var.
Timo P. schrieb:
> Aufruf:> s_measure((unsigned char*) &humi_val.i,&checksum,HUMI);> worauf bezieht sich hier der typecast(unsigned char *) ?
Auf &humi_val.i
also die Adresse von i in der union humi_val
Wobei der ganze Ansatz da schon in die Tonne müsste.
Wenn s_measure sowieso einen int haben will, warum nimmt sie dann nicht
einfach einen Pointer auf int.
Wie gesagt: Den Programmierer sollte man mit dem nassen Fetzen
erschlagen.
hm ich hatte die zeile für den funktionsaufruf aus obigem beitrag hier
reinkopiert, ich habe ihn vorhin geändert(meinen letzten beitrag)
es ist ..._i anstelle von .i, also das element einer union gibt es
nicht.
ist aus der :
Application Note
Sample Code
von sensirion selbst!
____________________________________________
double dew_point;
float humi_val,temp_val;
sprintf(s,"temp:%5.1f C humi:%5.1f dew point:%5.1fC\r\n",
temp_val,humi_val,dew_point);
Warning vom Compiler:
5.1f expects double ?!? Wieso das denn? f ist für float, oder muss ich
mir da genauer überlgen, ob 5.1 überhaupt für f möglich ist??
Timo P. schrieb:
> 5.1f expects double ?!? Wieso das denn? f ist für float, oder muss ich> mir da genauer überlgen, ob 5.1 überhaupt für f möglich ist??
Der Code ist grundsätzlich ok, da float an dieser Stelle als double
übergeben werden muss (weil sprintf eine variadische Funktion ist). Wird
wahrscheinlich eine Performance Warnung sein.
Du kannst dich an dieser Stelle mit einem "Ist ok Compiler, machs
einfach"-Cast aus der Äffäre ziehen.
extern int sprintf(char *__s, const char *__fmt, ...);
mehr finde ich nicht zu dieser funktion.
es ist z.b noch eine ansi.h eingebunden, diese finde ich nicht im
compilerverzeichnis. Für die Verwendung von printf ( so habe ich es
übers forum mal erfahren) kann man in den jeweiligen
Projekteigenschaften verschiedene libarys einbinden, je nach wunsch für
die Fließkommazahlen.
mich würde die sprintf-fkt. interessieren, ob sie wirklich ein double
als parameter erwünscht
Timo P schrieb:
> mich würde die sprintf-fkt. interessieren, ob sie wirklich ein double> als parameter erwünscht
Hab ich es in diesem Thread schon mal erwähnt?
Wenn ja, egal, ich sage es nochmal:
Du brauchst unbedingt Literatur! Literatur, die dich systematisch durch
alle die Fallstricke und all das Wissen manövriert, das du benötigst um
C zu programmieren. Solnage du das nicht systematisch angehst, wird dein
Wissen immer nur 'Halbwissen sein'. Egal wieviel du frägst.
Zurück zur Frage
sprintf ist eine variadische Funktion.
In diesem Fall gelten in C dieselben Regeln für die nicht im Protoyp
spezifizierten Paramter, wie sie auch in der Vor-Prototyp-Zeit gegolten
haben, der Compiler also keinen Protoyp einer Funktion kennt und
trotzdem die Parameterübergabe in einer halbwegs sicheren Art und Weise
über die Bühne gehen soll.
* alles was nicht näher spezifiert ist, ist ein int
Das ist eine der Grundregeln in C.
Wenn der Compiler eine Funktion nicht kennt, kennt er auch den
Returntyp der Funktion nicht.
Er nimmt dann an: Es ist ein int
* ein float wird immer als double übergeben
* alles was kleiner als int ist, wird als int übergeben
* für alles was größer als int ist, ist der Programmierer zuständig.
* speziell bei variadischen Funktionen:
Es muss einen Mechanismus geben, mit dem die aufgerufene Funktion die
Anzahl und die Datentypen der übergebenen Argumente feststellen kann.
C hält sich da raus. Es ist Sache des Programmierers sich dafür
etwas einfallen zu lassen. Im Falle der printf/scanf Funktionen
übernimmt der Format-String diese Aufgabe. Die %-Kürzel werden von
der Funktion ausgewertet um Anzahl und Datentyp der übergebenen
Argumente festzustellen. Das ist das Einzige was printf/scanf über
die Datentypen der Argumente weiß! Man sollte daher peinlich darauf
achten, dass die %-Kürzel auch zu den Argumenten passen.
Karl heinz Buchegger schrieb:
> * ein float wird immer als double übergeben
AHA!
> Man sollte daher peinlich darauf> achten, dass die %-Kürzel auch zu den Argumenten passen.
"Peinlich-genau" das habe ich doch gemacht: 5.1f passt zu meinen
variablen:
float humi_val,temp_val;
sprintf(s,"temp:%5.1f C humi:%5.1f dew point:%5.1fC\r\n",
temp_val,humi_val,dew_point);
Timo P. schrieb:
> Karl heinz Buchegger schrieb:>>> * ein float wird immer als double übergeben> AHA!>> Man sollte daher peinlich darauf>> achten, dass die %-Kürzel auch zu den Argumenten passen.>> "Peinlich-genau" das habe ich doch gemacht: 5.1f passt zu meinen> variablen:
Ja, ich weiß.
Mir ist ehrlich gesagt auch nicht wirklich klar, warum es da eine
Warnung gibt. Die Operation ist hier eindeutig definiert unter
Ausschluss aller möglichen Missverständnisse.
Ich schätze daher, diese Warnung bedeutet mehr oder weniger:
"Du bist dir bewusst, dass dein float an dieser Stelle sowieso wie ein
double behandelt wird. Wenn es also nur um hier geht, könntest du
genausogut einen double nehmen"
Es könnte auch sein, dass die Warnung bedeutet:
"Da du hier von einem float ausgehst, musst du dir bewusst sein, dass
einige der hinteren Nachkommastellen aus den Fingern gesaugt sind. Es
macht zb keinen Sinn, hier 10 Nachkommastellen anzuzeigen da in einem
float bei so um die 6 bis 7 Stellen Schluss ist"
Wie gesagt, an dieser Stelle kannst du den Compiler mit einem Cast
ruhigstellen, indem du die Operation, die der Compiler sowieso macht, in
diesem Cast ausdrückst.
1
floathumi_val,temp_val;
2
3
sprintf(s,"temp:%5.1f C humi:%5.1f dew point:%5.1fC\r\n",
4
(double)temp_val,
5
(double)humi_val,
6
(double)dew_point);
damit dokumentierst du dann auch, dass du dir durchaus bewusst bist,
dass hier implizit eine Konvertierung der float nach double erfolgt
(erfolgen muss).
#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void)
{
61 if(send_XPort && protocol[i++] != '\' )
{UCA0TXBUF = protocol[i++];} // TX next character
if (i == sizeof protocol - 1) // TX over?
{
i = 0; // Nach Stringende
send_XPort = 0;
P3OUT &= ~(1<<2);
IE2 &= ~UCA0TXIE;
ready = 1;
}
}
fehlermeldung:
61: missing closing quote und
61: expected a ")"
in meinem CCE kann ich sehen, dass die klammer zu blau geschrieben
erscheint, also glaube ich, der interpretiert das als string, obwohl ich
das abgefragte stringendezeichen wie es sich gehört in '' geschrieben
habe....
Wo ist mein Fehler? Kann ich bei bestem Willen nicht sehen. Klammer zu
ist gemacht, das ist nicht der Fehler!
........habe mich jetzt nicht durch alle Antworten gewühlt, vielleicht
hat es schon einer geschrieben:
- DATA nie als Variablennamen verwenden, ist reserviert für den Compiler
Grüße,
Alex
Timo P. schrieb:
> printf("*argv =**%s** argc(int)=%d",argv,argc);
argv ist kein String.
argv ist ein Array von Pointern, wobei jeder Pointer auf einen String
zeigt.
argv
+-------------+
| o-------------------------->"Projekt1.exe"
+-------------+
| o---------------------+
+-------------+ |
| NULL | +--->"-abc"
+-------------+
> printf("\r\n\n\n\nhier einzelne ZeicheN:");> printf("\n%c\r",argv[0]);
argv[0] ist ein Pointer, der auf den Anfang des ertsen Strings zeigt.
Normalerweise ist das der Name der EXE die gestartet wurde. Kann aber
auch ein Leerstring sein oder auch der komplette Name des EXE inklusive
Pfadangabe, von wo aus das EXE gestartet wurde.
> printf("\n%c\r",argv[1]);
argv[1] ist ein Pointer auf dein erstes Argument. In deinem Fall ein
Pointer auf den String "-abc"
> printf("\n%c\r",argv[2]);
so wie du das EXE aufgerufen hast, ist argv[2] ein NULL Pointer
> printf("\n%c\r",argv[3]);
Du hast kein Recht auf argv[3] zuzugreifen. argc wird bei dir 2 sein.
> printf("\n%c\r",argv[4]);
Du hast kein Recht auf argv[4] zuzugreifen. argc wird bei dir 2 sein.
> Beides sind wirres zeug, zb. ,8$>
Sie sind deshalb wirr, weil du wirres Zeug programmiert hast.
Alex schrieb:
> ........habe mich jetzt nicht durch alle Antworten gewühlt, vielleicht> hat es schon einer geschrieben:>> - DATA nie als Variablennamen verwenden, ist reserviert für den Compiler
Seit wann?
Karl heinz Buchegger schrieb:
> Sie sind deshalb wirr, weil du wirres Zeug programmiert hast.
Ich bin davon ausgegangen, dass argv[0] ein einzelnes Element vom typ
char ist. Wäre dann folgende zeile wirklich "wirres Zeug"?
printf("\n%c\r",argv[0]);
int main(int argc, char *argv[])
{
for(int i = 0; i<argc; i++)
{
printf("\r\n\n argv[%d]:%s\r\n",i,argv[i]);
}
//system("PAUSE");
//return EXIT_SUCCESS;
}
so funzt es jetzt!
Das ist dann kein Wirres Zeug mehr!
@ Karl Heinz Buchegger
Hallo!
Guter Punkt, ist wahrscheinlich Compiler/IDE abhängig!? Verwende selbst
Keil uVision3 und der gibt mir folgende Info:
"The DATA statement assigns an address (in the range 00h-0FFh) to the
specified symbol. The symbol may not be redefined"
Grüße,
Alex