hi, ich programmiere mit c# und versuche gerade einen Wert von 0 bis 0x10000 zu inkrementieren, ohne dass die Werte 0xA bis 0xF beachtet werden. ich muss also nach 0x09 den Umbruch auch 0x10 machen, das aber für 10er, 100er und 1000er. Mein erster Versuch war mit einem if (x == 0x9) x=0x10, aber wie mache ich das bei den 1000er? dann muss ich die Zahl in 10er, 100er und 1000er zerlegen!? Das wird dann recht groß mit mehreren "if's" verschachtelt, geht das auch 'irgendiwe' eleganter!?
warum zählst du nicht einfach ein int hoch? 0 1 2 3 4 5 6 7 8 9 10 11 12 und schreibst dann 0x davor?
James schrieb: > hi, > ich programmiere mit c# und versuche gerade einen Wert von 0 bis 0x10000 > zu inkrementieren, ohne dass die Werte 0xA bis 0xF beachtet werden. auf deutsch: du willst mit BCD-Zahlen zählen/rechnen.
Verstehe ich nicht! wenn ich eine Zahl inkrementiere wird aus 9 doch 10. 10 in hex sind 0xA und das steht in meiner Variable. ich frage jetzt ab und zähle entsprechend 6 dazu, denke aber dass es "schneller" oder sauberere gehen muss!?
1 | if ((SerNo & 0xF) == 0xA) |
2 | SerNo += 6; |
3 | |
4 | if ((SerNo & 0xF0) == 0xA0) |
5 | SerNo += 0x60; |
6 | |
7 | if ((SerNo & 0xF00) == 0xA00) |
8 | SerNo += 0x600; |
Vlad Tepesch schrieb: >auf deutsch: >du willst mit BCD-Zahlen zählen/rechnen. RICHTIG, BCD war das Stichwort, danke!
die frage ist doch, was willst du erreichen. Intern mit BCD zu rechnen ist quatsch. MAch deine Rechnerreien und Zählerreihen ganz normal und konvertiere die Zahl für die Ausgabe
In C# BCD verwenden zu wollen verstehe ich wirklich nicht. Was hast du vor? Irgend ein Gerät ansprechen, welches dieses Format braucht oder irgendein merkwürdiges Dateiformat? Wenn es nicht C# wäre hätte ich ja gesagt inline ASM und DAA :D
>Intern mit BCD zu rechnen ist quatsch. (ist ja vermutlich eher eine Hausaufgabe) aber für "irgendwas" wurde BCD mal erfunden ich erinnere mich auch schwach an CPUs die das direkt unterstützten (C64?? oder ein taschenrechner, weiß ich jetzt nicht mehr) früher war >und konvertiere die >Zahl für die Ausgabe nämlich "sehr" aufwändig... (bei BCD natürlich easy)
Das ganze rührt daher dass ich hier ein paar (einige!?) Geräte habe, deren Seriennummer auch die Deviceadresse an einem Bussystem ist. Die Geräteadresse wurde damals zwar dezimal einprogrammiert, aber als Hex-wert abgespeichert. Nach der Seriennummer 0x9 kommt also die Seriennummer 0x10. Wenn ich nun die Geräte ansprechen möchte, muss ich zuerst deren Seriennummer suchen. (Die Teile sind sehr alt und das Typenschild kann man z.T. nicht mehr lesen). Also schließe ich die Geräte einzeln an den bus an und lass' mein Programm nach der Seriennummer suche. Jedes Gerät wird einzeln angesprochen und ich warte auf eine Antwort. Bei der Suche wäre es eignetlich egal die Werte 0xA bis 0xF auch abzuscannen, wenn ich aber 0xA bis 0xF aus der Suche heraus nehme, spare ich mir über die Hälfte der Zeit!
Nun, dann zähle dezimal, erzeuge einen String aus der Dezimalzahl und konvertiere den wiederum in einen Int, aber hexadezimal interpretiert. Also: int x = 1234 -> "1234" -> 0x1234 Oder besuch das Internet, ob da vielleicht jemand eine C#-Klasse für BCD-Arithmetik geschrieben hat.
Mach es dir nicht zu kompliziert. Du nimmst deine Integer und wandelst sie nach ASCII String. z.B mit itoa Dann hast du deinen ASCII String. Bei den einzelnen Ziffern im ASCII Format loescht du die oberen 4Bits und schon hast du deine BCD Zahlen. Die Frage ist jetzt nur noch ob sie je einzeln in einem Byte stehen oder zu zweit im gepackten Format. Und kein Sorge dein PC macht das schneller als du die aussenden kannst zu dem Geraet.
alles klar, dann mach ich das mit dem String. Es geht mir nicht um die Geschwindigkeit sondern um die Lesbarkeit. Das alte Programm läuft noch unter DOS und ich habe nur den Bustrace, keinen sourcecode. Nun möchte ich selbige Funktion unter Win implementieren. Vermutlich muss ich dann in ein paar Jahren nochmal hin und schauen wie ich es damals (also heute!?) gemacht habe.... Andere steigen schon auf Win8 um und ich muss noch mit MS DOS arbeiten :-( ...wobei, unter DOS habe ich wenigstens noch eine ordentliche Umschaltzeit bei RS232, bei Win7 benötige ich jetzt einen USB-Seriell-Wandler... Grüße
James schrieb: > bei Win7 benötige ich jetzt einen > USB-Seriell-Wandler... warum das? Win7 kannst genau mit echten COM ports umgehen.
Ich benütze einen 485-Wandler und die Umschaltzeiten von Rx zu Tx sind eher willkürlich als definiert. Ausserdem hat heute nicht jeder PC noch eine serielle Schnittstelle. Dem USB-Seriell-Wandler kann ich elegant mitteilen dass er nach dem Senden von 12 Bytes sofort wieder auf Empfangen schalten soll, so geht mir die Antwort nicht verloren. An der seriellen Schnittstelle meines PCs habe ich die meisten Antworttelegramme verloren weil das Umschalten von Tx auf Rx zu lange gedauert hat. Windows macht das irgendwann mal wenn sonst nichts anderes ansteht, bis dahin sind dann aber schon 2 oder 3 Bytes verloren gegangen. der µC in der Gegenstelle ist etwas zu schnell.
James schrieb: > Ich benütze einen 485-Wandler und die Umschaltzeiten von Rx zu Tx sind > eher willkürlich als definiert. Das ist kein Problem, wenn man es richtig macht, d.h. eine USB-Seriell-Bridge mit Hardwareunterstützung für RS485 verwendet. Dann muss man sich auf der Softwareseite überhaupt nicht mehr um die Sender-/Empfänger-Umschaltung kümmern. Ein Beispiel ist der altbekannte FT232; wie ein RS485-Treiber an den anzuschließen ist, damit die vollautomatische Sender-/Empfänger-Umschaltung funktioniert, ist im Datenblatt beschrieben. Nein, die Kombination fertig gekaufter USB-RS232-Wandler mit daran angeschlossenem RS232-zu-RS485-Wandler ist hier nicht verwendbar, weil da die vom FT232 vorgesehene Steuerleitung nicht herausgeführt wird.
James schrieb: > An der seriellen Schnittstelle meines PCs habe ich die meisten > Antworttelegramme verloren weil das Umschalten von Tx auf Rx zu lange > gedauert hat. also mein Wandler macht das von selber, da muss ich nicht umschalten. Habe auch noch nie Daten verloren.
Rufus Τ. Firefly schrieb: > Das ist kein Problem, wenn man es richtig macht, d.h. eine > USB-Seriell-Bridge mit Hardwareunterstützung für RS485 verwendet. Dann > muss man sich auf der Softwareseite überhaupt nicht mehr um die > Sender-/Empfänger-Umschaltung kümmern. Sowas ähnliches habe ich jetzt ja! mein alter (serieller) 232-485-Wandler konnte das nicht, das war rein nur hardware mit einem MAX485. nun habe ich mir aus einer vorhandenen Platine mit MSP430 und FTDI selbst einen Wandler gebastet. Da war aus einem anderen Projekt schon fast alles fertig und ich musste nur noch die Telegrammlänge anpassen. Der Rest geht als COM an den PC. Nur wollte ich jetzt, wenn ich schon was neues mache, nicht auf das alte Steckenpferd der seriellen Schnittstelle setzen sondern am PC gleich per USB heraus fahren, das ist für die Zukunft sicherlich sinnvoller...
Rufus Τ. Firefly schrieb: > Also: > > int x = 1234 -> "1234" -> 0x1234 warum über String funktionen? so eine umrechnung lässt sich doch leicht aus dem Ärmel schütteln:
1 | uint32_t intToBCD(uint32_t input) |
2 | {
|
3 | uint32_t res=0; |
4 | uint32_t factor = 1; |
5 | while(intput>0){ |
6 | uint32_t rem = input%10; |
7 | intput = input/10; |
8 | res = rem*factor; |
9 | factor *= 16 ; |
10 | }
|
11 | return res; |
12 | }
|
(hoffe ich hab jetzt keinen Denkfehler drin, aber das Prinzip sollte klar sein. ich lese eine Dezimalstelle (Rest von Div10) und konvertiere sie in eine hexadezimalstelle (*faktor)
>warum über String funktionen?
weil er Rechenpower ohne ende hat
da nimmt man code bei dem man nicht nachdenken muss und
einfach zu lesen ist
man schließt damit die Ungewissheit eines "Denkfehlers" aus...
(wenn man schon den "besten"/schnellsten code haben will, dann würde ich
in diesem fall, so wie vom TO gefrag, das inkrementieren um eins machen,
das ist WESENTLICH schneller als die ganzen divisionen in deinem
code...)
James schrieb: > nicht auf das alte > Steckenpferd der seriellen Schnittstelle setzen sondern am PC gleich per > USB heraus fahren Deswegen kannst du ja trotzdem sowas wie den FTDI einsetzen, nur eben im Gerät - das ist um einiges einfacher als einen USB-Stack im Controller zu implementieren, du kannst die Software im wesentlichen weiterbenutzen. Kommt auf den Controller an, aber ich vermute mal stark, dass der vorhandene keinen USB-Anschluss hat. Ausserdem ist ev. zu beachten, dass du mit USB längst nicht so weit kommst wie mit RS485, normalerweise 5m. Gruss Reinhard
Vlad Tepesch schrieb: > warum über String funktionen? Weil hier in C# programmiert wird, und --wie ich gerade an anderer Stelle von einem Java-Programmierer mitbekomme-- so etwas selten die, sagen wir mal, Nähe zur Realität bietet, die die nicht-String-Variante fordert. Wenn die nicht-String-Variante so auch in C# umsetzbar ist, ist gut, dann kann (und sollte) man das natürlich so machen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.