Hallo
ich muss ein existierendes programm in vb to c umschreiben.
Da ich von beiden nicht sehr viel ahnung habe dachte ich dass ich hier
richtig bin.
hier nun meine frage wenn ich in visual basic etwas mit chr(230) an
rs232 schike ist es das selbe wie in c printf("%c",*variable mit dem
wert 230*);
oder wie ist es?
Freue mich über jede mögliche antwort.
Ja, aber nur wenn printf() an die serielle Schnittstelle sendet.
Normalerweise sendet printf() auf die Konsole (also den Textbildschirm).
es geht auch wenn ich ihm sage nicht variable mit dem wert 230 sonder
als hexa übergebe? z.b. für 230, E6??
char boot_seq[7]={0xe6,0xf0,0x60,0xfa,0x9a,0xb7,0xfe,0x70};
for(x=0;x<8;x++)
{
printf("%c",boot_seq[x]);
}
weil es irgend wie nicht richtig funktioniert? oder müsste es gehen und
mache etwas grundsetzliches falsch?(möglich wegen meiner vb kenntnissen)
Auf alle Fälle solltest du beachten, dass du beim Initialisieren von
Arrays in C die Anzahl der Elemente in die Klammer schreiben solltest.
Bei VB ist es jeweils der oberste Index.
Schreibt dein printf() denn überhaupt auf die serielle Schnittstelle?
> char boot_seq[7]={0xe6,0xf0,0x60,0xfa,0x9a,0xb7,0xfe,0x70};
Zähle mal die Werte in den geschweiften Klammern und vergleiche die Zahl
mit der in den eckigen.
Rufus t. Firefly wrote:
>> char boot_seq[7]={0xe6,0xf0,0x60,0xfa,0x9a,0xb7,0xfe,0x70};
>
> Zähle mal die Werte in den geschweiften Klammern und vergleiche die Zahl
> mit der in den eckigen.
arrays gehen immer von 0 bis ... also in meinem fall 8 zeichen lang.
und an den rest danke es geht jetzt.
werde mich bad aber noch ma melden...(Bestimmt)
Der Grosse wrote:
> Rufus t. Firefly wrote:
>>> char boot_seq[7]={0xe6,0xf0,0x60,0xfa,0x9a,0xb7,0xfe,0x70};
>>
>> Zähle mal die Werte in den geschweiften Klammern und vergleiche die Zahl
>> mit der in den eckigen.
>
> arrays gehen immer von 0 bis ... also in meinem fall 8 zeichen lang.
In VB ja, in C gehört in die Klammer die ANZAHL der Elemente.
> und an den rest danke es geht jetzt.
Schön, aber komisch.
> arrays gehen immer von 0 bis ... also in meinem fall 8 zeichen lang.
Das stimmt schon. Aber bei der Deklaration eines Arrays wird nicht der
größte Arrayindex, sondern die Anzahl der Elemente spezifiziert.
...
Wobei es in so einem Fall immer das Beste ist, diese
Schmutzarbeit dem Compiler zu überlassen:
1 | // lass den Compiler die Arraygröße aus der Initialisierung
| 2 | // bestimmen. Der macht das nämlich fehlerfrei
| 3 | char boot_seq[] = { 0xe6,0xf0,0x60,0xfa,0x9a,0xb7,0xfe,0x70 };
| 4 |
| 5 | // for(x=0;x<8;x++)
| 6 | // auch hier wieder: die 8 kann auch vom Compiler bestimmt
| 7 | // werden
| 8 | for( x = 0; x < sizeof( boot_seq ); x++ )
| 9 | {
| 10 | printf("%c",boot_seq[x]);
| 11 | }
|
Anstatt den sizeof da im Code zu verstecken, kann man auch
den Präprozessor hier sinnvoll einsetzen
1 | char boot_seq[] = { 0xe6,0xf0,0x60,0xfa,0x9a,0xb7,0xfe,0x70 };
| 2 | #define BOOT_SIZE ( sizeof( boot_seq ) / sizeof( *boot_seq ) )
| 3 |
| 4 | for( x = 0; x < BOOT_SIZE; x++ )
| 5 | {
| 6 | printf("%c",boot_seq[x]);
| 7 | }
|
Hmm. Wer vergibt denn solche Auftraege? Da kann einer nicht
ordentlich C und auch nicht ordentlich VB und soll doch ein
Programm von der einen Sprache in die andere transferieren.
Solche Umsetzungen sind mit das Schwierigste, was die Branche
zu bieten hat, weil man in beiden Sprachen absolut firm sein
muss. Die Probleme entstehen nämlich immer dadurch dass 2
Sprachen sich in Details unterscheiden und nur wenn man ueber
diese Details in beiden Sprachen Bescheid weiss, kann man das
richtig machen.
@Karl heinz Buchegger
kommplet richtig aber was gemacht werden muss das muss halt gemacht
werden...
oder nocht besser
was mich nicht umbringt macht mich stärker...
und ausserdem haben viele andere was davon wenn sie später ma so ne
aufgabe haben und hier im forum nachschauen.
eine korrektur und zwar sende ich ihm nicht
printf("%c",...)
sondern
printf("%X",...);
warum auch immer,
müsste das eigentlich nicht falsch sein? weil so wie ich es in der vb
hilfe verstanden habe macht chr() aus den übergebenen zeichen ein ascii
entsprächendes zeichen und nicht die hex zahl, so wie es in diesem fall
printf ausgibt.
printf ("%c",...) "sendet" ein 8-Bit Datenbyte, nämlich den wert des
parameters.
printf ("%X",...) "sendet" soviele Datenbytes, wie nötig sind, um den
Wert des Parameters hexadezimal in ASCII darzustellen.
printf ("%d",...) "sendet" soviele Datenbytes, wie nötig sind, um den
Wert des Parameters dezimal in ASCII dazustellen.
und was macht chr() in VB ?
printf("%c")
oder nicht?
chr() macht alleine keine Ausgaben, aber es gibt das ASCII-Zeichen des
übergebenen Wertes zurück.
print chr(...); wäre der richtige Ausdruck.
Der Grosse wrote:
> und was macht chr() in VB ?
>
> printf("%c")
>
> oder nicht?
chr wandelt den Datentyp, entspricht also im weitesten
Sinne in C einem cast. Allerdings ist der in C gar nicht
notwendig, da in C ein char zu einem int Zuweisungskompatibel
ist.
Ein VB Konstrukt
DIM c as Character
c = chr( 255 )
kann in C geschrieben werden
char c;
c = 255;
oder aber, wenn man genau sein will:
char c;
c = (char)255;
Guten Morgen!!!
Schaut ma kann ich folgendes machen?
wenn ich ein feld habe hex-zahlen
und ich daraus integer machen mäöchte um sie dann als char auszugeben.
weil in VB kann man ja mit val() verschiedene hex zahlen oder chars nach
int convertieren.
also ich meine es so:
loop_until_bit_is_set(UCSR1A, UDRE);
UDR = (int)lenge;
wenn in lenge z.b. ein 0x10 drin steht.
wird er 16 ausgeben?
oder brauche ich gar nichts zu konvertieren?
macht c automatisch aus hex -> int?
in vb folgendes:
laenge = Val("&H" & Left$(antwort, 2))
Was im Empfangsregister drinsteht, kommt ganz drauf an, was der Sender
gesendet hat.
Hat der Sender print chr(16) bzw chr (&h10) gesendet, wurde ein byte mit
dem wert 16 empfangen. Die Wandlung nach Hexadezimal verändert den Wert
dieser Zahl nicht; es ist eine reine Darstellungssache, wie ich diesen
Wert repräsentiere. 0x10 und 16 und 0b010000 sind von ihrer Wertigkeit,
also inhalt der Speicherzelle, absolut identisch.
Hat der Sender "0x10" (als String) gesendet, wurden 4 Byte gesendet mit
den Werten 0x30, 0x78, 0x31, 0x30 gesendet. In diesem Fall reicht einmal
UDR auslesen nicht aus, um den übermittelten Wert zu erfassen, sondern
die Werte müssen in einem Buffer erfasst und dann geparst werden.
Ich habe jetzt folgendes ich kriege zwar einen string zurück muss aber
nur das erste zeichen daraus auswerten.
vb:
If Hex$(Asc(antwort)) = "55" Then List1.AddItem "8xC166 µC gefunden!"
wie kann ich es den in c realisieren?
ich habe folgendes gemacht
aber funktionalität noch nciht ausprobiert kann es den überhaupt gehen?
if((char)b == (char)85)
{
lcd_print("Codierer Found",4,22,0,Schwarz,Gruen);
}
else if(b == 0)
{
lcd_print("Kein Codierer",4,22,0,Schwarz,Gruen);
getkey();
menue();
}
else
{
lcd_print("Falsche Antwort",4,22,0,Schwarz,Gruen);
getkey();
menue();
}
oder muss ich mehr mals auslesen und den string dann bearbeiten? in vb
lese ich es ja auch nur einmal ein:
antwort = MSComm1.Input
und was sende ich wenn ich sage chr(0) == (char)NULL
Der Grosse wrote:
> vb:
>
> If Hex$(Asc(antwort)) = "55" Then List1.AddItem "8xC166 µC gefunden!"
>
> wie kann ich es den in c realisieren?
>
> ich habe folgendes gemacht
>
> aber funktionalität noch nciht ausprobiert kann es den überhaupt gehen?
>
> if((char)b == (char)85)
> {
> lcd_print("Codierer Found",4,22,0,Schwarz,Gruen);
> }
Ja, die übersetzung entspricht funktional ungefähr dem
VB-vorbild...(vorrausgesetzt in 'b' ist das empfangene Zeichen, genauso
wie "antowort" ein einzelnes empfanges Zeichen entspricht)
ich bins noch mal
Als erstes Danke für die schnellen und präziesen antworten... Ich fülle
mich immer deprimiert das ich selbst nicht darauf komme weil es ja
eigentlich voll einfach ist.
Danke schön...
habe jetzt ma folgende frage in vb kann man ja aus einem string wo sagen
wir ma Hex zahlen drin stehen 2 zeichen einlesen und dann als einzelnes
zeichen benutzen
beispiel:
puffer = Input(2, #1)
laenge = Val("&H" & puffer)
dadurch habe ich je den wert des Hex wertes der im string als z.b 01
drin steht.
kann ich es in C so realisieren?
adrL = (int)strcat(Buffer[d+5],Buffer[d+6]);
adrL = (int)adrL;
Der Grosse wrote:
> habe jetzt ma folgende frage in vb kann man ja aus einem string wo sagen
> wir ma Hex zahlen drin stehen 2 zeichen einlesen und dann als einzelnes
> zeichen benutzen
>
> beispiel:
>
> puffer = Input(2, #1)
> laenge = Val("&H" & puffer)
>
> dadurch habe ich je den wert des Hex wertes der im string als z.b 01
> drin steht.
>
> kann ich es in C so realisieren?
>
> adrL = (int)strcat(Buffer[d+5],Buffer[d+6]);
> adrL = (int)adrL;
nein.
strcat macht was anderes.
http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F
Aber warum machst du nicht eine 1:1 Umsetzung deiner Beschreibung?
Lass uns die nochmal etwas strukturieren
* Gegeben sei ein String
* An einer bekannten Position in diesem String steht die
ASCII Repräsentierung einer HEX Zahl (sprich: 2 aufeinanderfolgende
Zeichen ergeben die Hex Zahl)
* Um die Zahl zu erhalten, reicht es aus der ASCII Repräsentierung
jedes einzelnen Zeichens die jeweilige Ziffer zu erzeugen
* Liegen beide Ziffern vor, werden die beiden Ziffern zu Zahl montiert.
Die Umwandlung eines Zeichens (im Bereich 0..9, A..F) in die
korrespondierende Ziffer, ist es uns wert, dafür eine eigene
Funktion zu schreiben:
1 | void ToNumber( char c )
| 2 | {
| 3 | // war c im Bereich 'A' bis 'F'?
| 4 | // wenn ja, dann in eine Ziffer 10 .. 15 wandeln
| 5 | if( c >= 'A' && c <= 'F' )
| 6 | return c - 'A' + 10;
| 7 |
| 8 | // c muss im Bereich '0' bis '9' liegen
| 9 | return c - '0';
| 10 | }
|
Soweit, so gut. Damit ist es jetzt aber nicht mehr
schwer, jeweils einen char in seine korrespondierende
Ziffer umzuwandeln, für die beiden hintereinander folgenden
Character lautet das zb. so
1 | unsigned char High;
| 2 | unsigned char Low;
| 3 |
| 4 | High = ToNumber( Buffer[5] );
| 5 | Low = ToNumber( Buffer[6] );
|
und da jetzt beide Ziffern in numerischer Form vorliegen, kann
dann auch die Hex-Zahl in seiner Gesamtheit bestimmt werden:
1 | unsigned char Zahl;
| 2 |
| 3 | Zahl = 16 * High + Low;
| 4 |
| 5 | // oder andere Schreibweise
| 6 | // Zahl = (High << 4) | Low;
|
Fragt sich natürlich noch, wozu eigentlih die beiden Zwischen-
variablen gebraucht werden. Eigentlich braucht die ja kein
Mensch:
1 | unsigned char Zahl;
| 2 |
| 3 | Zahl = ( ToNumber( Buffer[5] ) << 4 ) | ToNumber( Buffer[6] );
|
und weil wir heute einen guten Tag haben, packen wir das
ganze in eine Funktion:
1 | unsigned char ToHex( char* String )
| 2 | {
| 3 | // wertet die ersten beiden char im String aus und wandelt
| 4 | // sie in eine Hex-Zahl.
| 5 | // Es wird davon ausgegangen, dass dort auch wirklich
| 6 | // eine Hex Zahl gespeichert ist
| 7 |
| 8 | return ( ToNumber( String[0] ) << 4 ) | ToNumber( String[1] );
| 9 | }
|
und wird dann so verwendet
1 | int main()
| 2 | {
| 3 | char Test[] = "HalloAF";
| 4 | unsigned char Number;
| 5 |
| 6 | Number = ToHex( &Test[5] );
| 7 | }
|
Was du mitnehmen solltest:
In C sind char (also Character) auch nichts anderes als ein
numerischer Datentyp, mit dem man durchaus auch rechnen kann.
In einem char ist einfach nur der jeweilige ASCII Code eines
Zeichens gespeichert. Und mit diesem ASCII Code kann man
rechnen. Einzig und alleine die Ein/Ausgabe ist bei einem
char anders. Anstelle der Textreräsentierung der in der Variblen
gespeicherten Zahl, wird die Zahl selbst ausgegeben. Enthält
also ein char den Wert 65, so wird bei einer Ausgabe nicht
'6' '5' an das Ausgabegerät geschickt (also die Codes für
'6' bzw. '5'), sondern 65 ist bereits der Code, der an
das Ausgabegerät weitergegeben wird. Das malt daraufhin,
in Übereinstimmung mit der ASCII Code Tabelle ein 'A' auf
seine Ausgabefläche.
Aber abgesehen davon, sind char ganz normale numerische Objekte
in C, mit denen man rechnen kann. Man rechnet dann halt mit
Codezahlen. Aber 65 / 2 ist auch bei einem char immer noch 32.
> kann ich es in C so realisieren?
>
> adrL = (int)strcat(Buffer[d+5],Buffer[d+6]);
> adrL = (int)adrL;
Eher nein. strcat liefert dir einen Zeiger zurück, wenn du den nach int
castest, steht in adrL &Buffer[d+5] als Adresse. Für sowas solltest du
atoi() (Ascii to integer) verwenden. Allerdings müsstest du dazu erst
einen String aus zwei Zeichen erstellen 1 | char temp[3];
| 2 | memcpy(temp, &Buffer[d+5], 2);
| 3 | temp[2] = 0;
| 4 | int adr = atoi(temp);
|
oder aber, falls du "Buffer" nachher nicht mehr brauchst, den Puffer
eben direkt anpassen: 1 | Buffer[d+7] = 0;
| 2 | int adr = atoi(Buffer[d+5]);
|
Philipp Burch wrote:
> 1 | > Buffer[d+7] = 0;
| 2 | > int adr = atoi(Buffer[d+5]);
| 3 | >
|
Das hat nur einen klitzekleinen Schönheitsfehler.
Es war von Hex-Zahlen die Rede. atoi() kann mit
Hex nichts anfangen.
Ups, nicht bedacht. Dann halt strtoi() oder sowas. Für den Zweck
allerdings bestimmt Overkill.
Danke für eure antworten
da ich ja auch schon etwas schlauer geworden bin habe ich etwas anderes
gemacht.
Ich weiss nicht ob das kommplet richtig ist ABER es funktioniert(Sieht
zumindest danach aus):
//Rechne die erste zahl *0x10 dadurch bekomme ich z.b aus 4 -> 40
adr = (Buffer[d]*0x10);
//addire die zweite zahl dazu wenn es z.b. F ist dann bekomme ich 4F
adr = adr+Buffer[d+4];
//und mit dem cast operator kann man jetzt den entsprächenden integer
machen
adr = (int)adr;
Der Grosse wrote:
> adr = (Buffer[d]*0x10);
> adr = adr+Buffer[d+4];
was ist d+4 ?!?
Nein, das funktioniert so nicht. ascii Zeichen "0" hat den wert 48 und
"1"=49.
Deine Funktion würde für "0x10" (wenn d auf die '1' zeigt)
wert=49*16 + 48
Damit wäre das ergebnis 832.
Du kommt nicht drumherum, zur Wandlung eines einzelnen Hexzeichens nach
Dezimal eine Funktion zu schrieben. Beispielsweise:
uint8_t toNumber (char *buf)
{
if (buf>=48 && buf<=57) // 0 - 9
{
return buf-48;
}
if (buf>=65 && buf<=70) // A - F
{
return buf-55;
}
if (buf>=97 && buf<=102) // a - f
{
return buf-87;
}
return 255; // illegales Zeichen in buf
}
die Wandlung für "0x10" in Buffer sähe dann so aus: (d zeigt auf '1')
adr=toNumber(Buffer[d])*16;
adr+=toNumber(Buffer[d+1]);
so´n mist habt ihr recht...
man man man
Das macht mich richtig deprimierend ich weiss es alles was ihr schreibt
aber von selbst komme ich irgend wie nicht drauf.. :-((
Danke für eure hilfe.
(Was nicht heissen soll das es schon alles ist.)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|