fox37
Messages postés23Date d'inscriptiondimanche 24 août 2003StatutMembreDernière intervention11 février 2007
-
4 mars 2006 à 18:23
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 2014
-
10 mars 2006 à 21:34
Bonjour a tous,
Comment faire pour convertir un caractère en code ascii?
Je m'explique : Je recois 3 caractères codés sur 1 octet chacuns par le port serie.
Je peux visualiser ces caractères dans un tedit.
Mais je voudrais en fait visualiser le code binaire de ce caractère afin de pouvoir obtenir sa valeur réelle.
par ex : je recois les caractères 1,2,3 qui correspondent normalement a 00110001,00110010,00110011
à partir de ce momment je voudrais pouvoir obtenir la conversion en décimal mais sur 3 octets : 001100010011001000110011 ==>2e0+2e1+2e4+2e5+2e9+2e12+2e13+2e16+2e20+2e21= à mon resultat qui s'affichera à l'ecran
Voila j'espère avoir été à peu près clair
Merci
Fabrice
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202234 7 mars 2006 à 01:40
Type
// quelques types utile...
TStr2 = string[2]; // hexa 1 octet
TStr3 = string[3]; // chaine de 3 caracteres
TStr6 = string[6]; // hexa 3 octet
TStr8 = string[8]; // binaire 8 bits
TStr24 = string[24]; // binaire 3*8 bits
// permet de stocker les trois caracteres
TTriChar = array[1..3] of char;
// permet de stocker les trois valeurs decimale
TTriByte = array[1..3] of byte;
// permet de stocker les trois representations binaire
TTriBin = array[1..3] of TStr8;
// permet de stocker les trois representations hexadecimale
TTriHex = array[1..3] of TStr2;
// permet de créer des variables pratique a utiliser
TPortMessage = record
Chaine : string;
Chars : TTriChar;
Bytes : TTriByte;
Bins : TTriBin;
Hexs : TTriHex;
end;
// fonctions permettant de remplir rapidement une variable de type TPortMessage
// peu importe les données qu'on vas lui envoyer.
function PortMessage(const A,B,C : char) : TPortMessage; overload;
function PortMessage(const A,B,C : byte) : TPortMessage; overload;
function PortMessage(const ABC : TStr3) : TPortMessage; overload;
function PortMessage(const ABC : integer): TPortMessage; overload;
implementation
// convertis un string vers un TTriChar
function StringToTriChar(const S : TStr3) : TTriChar; forward;
// convertis un TTriChar vers un string
function TriCharToString(const TC : TTriChar) : TStr3; forward;
// convertis un TTriChar vers un TTriByte
function TriCharToTriByte(const TC : TTriChar) : TTriByte; forward;
// convertis un TTriChar vers un TTriBin (binaire)
function TriCharToTriBin(const TC : TTriChar) : TTriBin; forward;
// convertis un TTriChar vers un TTriHex (hexa)
function TriCharToTriHex(const TC : TTriChar) : TTriHex; forward;
// convertis un TTriChar vers une chaine representant la valeur hexadecimale de l'ensemble
function TriCharToLongHex(const TC : TTriChar) : TStr6; forward;
// convertis un TTriChar vers une chaine representant la valeur binaire de l'ensemble
function TriCharToLongBin(const TC : TTriChar) : TStr24; forward;
// convertis un TTriChar vers un entier 32 bit signé representant la vleur decimale de l'ensemble
function TriCharToLongDec(const TC : TTriChar) : integer; forward;
function PortMessage(const A,B,C : byte) : TPortMessage;
begin
PortMessage(chr(A),chr(B),chr(C));
end;
function PortMessage(const ABC : TStr3) : TPortMessage;
begin
PortMessage(ABC[1],ABC[2],ABC[3]);
end;
function PortMessage(const ABC : integer): TPortMessage;
begin
PortMessage(chr(byte(ABC shr 16)), chr(byte(ABC shr 8)), chr(byte(ABC)));
end;
{ ---------------- }
function StringToTriChar(const S : TStr3) : TTriChar;
var x : integer;
begin
for x := 1 to 3 do result[x] := S[x];
end;
function TriCharToString(const TC : TTriChar) : TStr3;
begin
result := TC;
end;
function TriCharToTriByte(const TC : TTriChar) : TTriByte;
var x : integer;
begin
for x := 1 to 3 do result[x] := ord(TC[x]);
end;
function TriCharToTriBin(const TC : TTriChar) : TTriBin;
var x,y : integer;
R : TStr8;
S : TStr2;
begin
{ super algorythme de convertion char > binaire... yoplaboum! ;) }
for X := 1 to 3 do begin
R := '';
S := format('%.2x',[ord(TC[X])]);
for Y := 1 to 2 do begin
case S[Y] of
'0' : R := R + '0000'; '1' : R := R + '0001';
'2' : R := R + '0010'; '3' : R := R + '0011';
'4' : R := R + '0100'; '5' : R := R + '0101';
'6' : R := R + '0110'; '7' : R := R + '0111';
'8' : R := R + '1000'; '9' : R := R + '1001';
'A' : R := R + '1010'; 'B' : R := R + '1011';
'C' : R := R + '1100'; 'D' : R := R + '1101';
'E' : R := R + '1110'; 'F' : R := R + '1111';
end;
end;
result[X] := R;
end;
end;
function TriCharToTriHex(const TC : TTriChar) : TTriHex;
var x : integer;
begin
for x := 1 to 3 do
result[x] := format('%.2x',[ord(TC[x])]);
end;
function TriCharToLongHex(const TC : TTriChar) : TStr6;
var TH : TTriHex;
begin
TH := TriCharToTriHex(TC);
result := TH[1]+TH[2]+TH[3];
end;
function TriCharToLongBin(const TC : TTriChar) : TStr24;
var TB : TTriBin;
begin
TB := TriCharToTriBin(TC);
result := TB[1]+TB[2]+TB[3];
end;
function TriCharToLongDec(const TC : TTriChar) : integer;
begin
result := (ord(TC[1]) shl 16) + (ord(TC[2]) shr 8) + ord(TC[3]);
end;
et voila, tu n'as plus qu'a créer une variable type TPortMessage, recuperer le message de ton truc et l'envoyer dans la variable, exemple :
var
PM : TPortMessage;
procedure TForm1.Port1ReceptData(parametres);
begin
PM := PortMessage(P1,P2,P3);
// affichage dans les captions etc...
end;
La theorie c'est quand on sait tout, mais que rien ne fonctionne.
La pratique c'est quand tout fonctionne, mais que personne ne sait pourquoi.
<hr>
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 5 mars 2006 à 12:48
Salut,
essaye d'être un peut plus précis c'est un peut l'embrouille et je crois que c'est pour ça que tu n'as pas encore de réponse
parce que ton problème doit être simple a résoudre.
@+
Cirec
Vous n’avez pas trouvé la réponse que vous recherchez ?
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 5 mars 2006 à 13:15
un début de piste :
Var Resultat : Integer;
// on met les trois valeurs dans une seul
procedure TForm1.Button1Click(Sender: TObject);
Var a, b, c : Byte;
begin a := 49; // 1
b := 50; // 2
c := 51; // 3
Resultat := (a or (b shl 8) or (c shl 16)); // C'est ici que la magie opère
Memo1.Lines.Add(Format('%d', [Resultat])); // on affiche le résultat
end ;
// et on les récupères
procedure TForm1.Button2Click(Sender: TObject);
Var a, b, c : Byte;
begin a : = Byte(Resultat); // et on
b := Byte(Resultat shr 8); // les récupères
c := Byte(Resultat shr 16); // une à une
Memo1.Lines.Add(Format('%d, %d, %d', [a, b, c])); // on affiche pour contrôler
end;
fox37
Messages postés23Date d'inscriptiondimanche 24 août 2003StatutMembreDernière intervention11 février 2007 5 mars 2006 à 13:26
ok c'est un peu confus.
En fait : Actuellement , je recois sur le port serie une valeur qui correspond à un caractère ascii.Donc sur le port serie je recois une séquence de 0 et 1 qui corresponde à la valeur 52 en décimal(==>caractère 4 en ascii).
J'affiche ce caractère dans un Tedit.
Maintenant je voudrais convertir cette valeur 52(ou caractère 4) en code binaire ==> 52 = 00110100 et l'afficher dans une autre zone Tedit.
Ensuite le traitement de cette valeur(00110100) doit etre traitée afin de revenir a la valeur decimal ==>52 (conversion binaire -- décimal)
Vous me direz que cela ne sert a rien car en finalité je me retrouverais toujours avec la même valeur (soit 52)
Et bien non car le problème est que la séquence recue sur le port serie est composé de 3 caractères : ex 52,53,54 soit en ascii 4,5,6 et en binaire 00110100,00110101,00110110
Donc à ce momment dans la zone Tedit1 je lis la valeur 4,5,6(les virgules ne sont là que pour faciliter la lecture) et dans la zone Tedit2 il faudait que j'obtienne 00110100,00110101,00110110
Ensuite le traitement de cette valeur(00110100,00110101,00110110) doit être traitée afin de revenir à la valeur décimal ==>3421494 (conversion binaire des 3 octets a la suite -- décimal)(001101000011010100110110bin = 3421494dec).
J'espère avoir été un peu plus clair , sinon n'hésitez pas à me le dire
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 5 mars 2006 à 14:11
Bon alors voici deux fonctions qui permettent les convertions IntToBin et BinToInt elles ne sont pas de moi je les avais récupérer sur le net mais je ne sais plus ou.
function BinToInt(binval : string) : integer;
var i : integer;
res : variant;
h : string;
bin : string;
begin bin := binval ;
res := 0 ;
for i : = 0 to Length(bin)-1 do // boucle pour i depart 0 jusque taille de Binval -1
begin h := copy(bin,length(bin)-i,1); // Place dans H le Caractre partir de length(bin)-i de taille 1
if i = 0 then // si i egale 0 donc pour le premier caractre il effectue la procdure ci dessous
beginif h '1' then res : res + 1 ; // alors il ajoute 1 res si H = 1
h := '0'; // on place H=0 pour eviter d'effectuer la procdure suivante
end ;
if h = '1' then res := res + Exp(i*Ln(2)) ; //Si H= 1 alors on utilise cette Fonction
end ; // qui est une adaptation de 2^I
BinToInt : = res; // on transmet la valeur de sortie de la fonction
end;
Function IntToBin(nombre: longint; Const Long: Integer = 32): String ;
Var
C : PChar;
Begin SetLength(Result, 32);
FillMemory(@Result[1], 32, 48);
C : = @Result[32];
Repeat C^ := chr(48 + Nombre And 1);
Dec(C);
Nombre := Nombre Shr 1;
Until Nombre = 0;
If (Long < 32) And (Long > 0) Then Result := Copy(Result, 32 - Long + 1, 32);
End;
fox37
Messages postés23Date d'inscriptiondimanche 24 août 2003StatutMembreDernière intervention11 février 2007 5 mars 2006 à 17:46
Tous d'abord merci pour votre aide
Le code de cirec correspond en partie a ce que je recherche.Apres de multiples essai sur les différents codes que vous m'avez fournis j'en arrive à ce point.
Lorsque une valeur numérique se trouve dans les variables a b et c tous se passe bien.
Mon pb reside toujours dans le fait de convertir le caractère ascii recupéré sur le port serie(codé sur 8 bits) en décimal, de la transferer dans les varibles a b et c et après le code de cirec se charge du reste.
Merci de votre aide
Fabrice
Ps: je vous rappele que je débute dans la prog alors indulgence :o))
fox37
Messages postés23Date d'inscriptiondimanche 24 août 2003StatutMembreDernière intervention11 février 2007 5 mars 2006 à 22:02
Parfait et si je veux remplacer (caractère) par une variable. ?
En clair ayant 3 caracteres qui arrive il faudrait que valeur:=ord(caractere) soit "mis a jour" par mes caractères.Je pensais declaré 3 variables a b et c (type byte).lorsque les caractères arrivent sur le port serie je les lis et les stockent dans les variables a b et c .Ensuite je leur appliquent la fonction ord(le pb pour l'instant est que je n'arrive pas a assigner une variable dans cette fonction) et je recupere le resultat pour le traiter.
Voici la fonction tel que je l'utilise : decimal := inttostr(ord('r'))
Avec cela j'obtiens bien la valeur decimal de r mais maintenant je voudrais remplacer r par un des caractères recus sur le port serie.
fox37
Messages postés23Date d'inscriptiondimanche 24 août 2003StatutMembreDernière intervention11 février 2007 5 mars 2006 à 23:18
effectivement ca doit marcher mais je dois pas utiliser la bonne procédure.Voici la partie de code.Peu tu me dire si j'emploi la bonne methode?
procedure TForm1.Button2Click(Sender: TObject);
begin
labelededit1.text := '4' ; //J'affiche le caractère 4 dans le labelededit1.text
test1 := labelededit1.Text ; //J'assigne la valeur que contient labelededit.text dans la variable test1
edit2.Text := test1 ; //J'affiche la valeur contenue dans test1 (donc le caractère 4)
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
move(test1,test,sizeof(test)); //je copie la valeur de test1 dans test . Ceci afin de pouvoir changer le type ==>test1 est un char et test un integer
decimal := IntToStr(Ord(test)); //J'assigne le resultat de la conversion de test(ascii en decimal)
Edit1.Text := decimal ; //J'affiche la valeur de decimal dans edit1.text
end;
Voili voila mon bout de code qui doit etre faux car il ne marche pas comme voulu.
Je clique sur bouton2,j'affiche bien la valeur 4 dans labelededit1.text et edit2.text.
J'apuis sur le bouton1 et j'obtiens une valeur dans la zone edit1.text qui change a chaque appuis de bouton2+bouton1 ==> Valeur 0 16 et 32 alors que je devrais obtenir la valeur decimal du contenu de test(soit le caractère 4 qui vaut 52 en decimal)
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 5 mars 2006 à 23:40
salut
ton code ne marche pas car tu copies ton string par un move or le
string est un tableau qui commence à l'indice 1. pour copier un tableau
soit on utilise la fonction copy ou adresse directement le tableau
fais plutot comme cela:
procedure TForm1.Button1Click(Sender: TObject);
var test:char;
begin
test:=edit1.text[1];// tu copies le 1er caractere dans test (un
string est un tableau de caracteres il suffit d'adresser l'indice du
caractère que veux copier)
label1.Caption:=inttostr(ord(test));//tu affiches la valeur ordinale du caractere
<style>
<!--
@page { size: 21cm 29.7cm; margin: 2cm }
PRE { font-family: "Nimbus Roman No9 L" }
P { margin-bottom: 0.21cm }
-->
</style>
procedure TForm1.Button2Click(Sender: TObject);
Var a, b, c : Byte;
begin
test:=edit1.text[1];
label1.Caption:=inttostr(ord(test));
test1:=edit1.text[2];
if test1='' then
begin
label2.Caption:='0'
end
else
label2.Caption:=inttostr(ord(test1));
if edit1.Text[3]='' then
begin
label3.Caption:=''
end
else
test2:=edit1.text[3];
label3.Caption:=inttostr(ord(test2));
Move(test, a, SizeOf(a));
Move(test1, b, SizeOf(b));
Move(test2, c, SizeOf(c));
Resultat := (c or (b shl 8) or (a shl 16));
Memo1.Lines.Add(Format('%d', [Resultat]));
Memo2.Lines.add(FloatToStr(Resultat1));
end;
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 6 mars 2006 à 17:46
salut,
procedure TForm1.Button2Click(Sender: TObject);
Var a, b, c : Byte;
begin
test:= edit1.text[1];
label1.Caption:=inttostr(ord(test));
test1:=edit1.text[2];
if test1='' then
begin
label2.Caption:='0'
end
else label2.Caption:=inttostr(ord(test1));
if edit1.Text[3]='' then label3.Caption:=''
else test2:=edit1.text[3];
label3.Caption:=inttostr(ord(test2));
Move(test, a, SizeOf(a));
Move(test1, b, SizeOf(b));
Move(test2, c, SizeOf(c));
Resultat := (c or (b shl 8) or (a shl 16));
Memo1.Lines.Add(Format('%d', [Resultat]));
Memo2.Lines.add(FloatToStr(Resultat1));
end;
end.
tu aurais du mettre des sauts de lignes
si ton edit est vide tu ne peux pas accéder a edit1.text[2]; en effet c'est une variable dynamique qui remet sa taille à jour
à chaque modification
il faut tester la edit1.text avant d'affaecter l'indice
-->if length( edit1.text)<2 then
begin
label2.caption: ='0';
test:1= '0';//mets le caractere par défaut que tu veux
end;
-->if length( edit1.text)<3 then
begin
label3.caption: ='0';
test:2= '0';//mets le caractere par défaut que tu veux
end;
d'autre part plutot que d'utiliser des move() si tu as déclaré test,test1 et test2 en char fait plutot:
a: =ord(test);
b:=ord(test1);
c:=ord(test2);
ton code sera plus lisible, plus compact et plus rapide.
fox37
Messages postés23Date d'inscriptiondimanche 24 août 2003StatutMembreDernière intervention11 février 2007 6 mars 2006 à 22:11
J'avais bien compris pour la longuer merci.
Par contre j'y arrive pas .........
En effet maintenant je teste la longueur de mon champ edit et j'arrive a mettre à zero mes valeurs qui vont bien.Mais par contre a chaques appuis sur le bouton buttonclick il ne me remet pas mes trois variables test test1 et test2 a "zero"
ce qui fait que dans les zone label je vois que mes valeurs ont disparue mais dans mon calcul final il prend encore en compte la valeur precedente des test.
Je m'explique : mon champ edit est vide.Je clique sur le bouton et là il me donne un resultat =0,Je rentre une valeur dans edit de 2 caracteres, il me calcul bien la valeur mis sur 2octets et ramener en décimal.Par contre après je rentre un caractère dans le edit il me calcul le resultat en gardant la variable contenu precedement dans test1,alors qu'il ne devrait me le calculer uniquement avec test(1 carcatère)(puisque test1 est normallement vide)
En vous remerciant
Fabrice