hex-Wert inkrementieren ohne a.f

Gast #3040859
Lesenswert?

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!?
Gast #3040875
Lesenswert?

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;
#3040892
Lesenswert?

>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)
Gast #3040900
Lesenswert?

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!
#3040912
Lesenswert?

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.
Gast #3040941
Lesenswert?

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
Gast #3040981
Lesenswert?

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.
Persönliche Seite #3040996
Lesenswert?

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.
Gast #3041022
Lesenswert?

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...
#3041038
Lesenswert?

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)
#3041051
Lesenswert?

>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...)
Gast #3041072
Lesenswert?

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
Persönliche Seite #3041102
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren