我作了一个串口通讯的程序,要求把计算结果(十进制数)以“16进制浮点数”格式送给单片机,怎样实现,繁请各位高手帮忙。多谢。

解决方案 »

  1.   

    计算机发送的数据形式与单片机接收无关。
    比如single型数为4字节数据,发到单片机后接受到4个字节,至于是整型还是浮点型,与你的协议和单片机处理有关系,单片机会根据你的需要,赋值给int型,还是float型
      

  2.   

    单片机中
    定义
    float(double) x;
    x=07C80000;后x就是浮点数了
      

  3.   

    你用什么组件发送?
    procedure TForm1.Button1Click(Sender: TObject);
    var
      x: single;
      ii:longword;
      s:string;
    begin
      x:=100;
      move(x,ii,sizeof(x));
      s:=inttohex(ii,4);
      showmessage(s);
    end;
     
      

  4.   

    你可以先将single 转换为longword型,将longword型一个一个字节发送就行了
      

  5.   

    我用SPCOMM组件发送,现在还有问题是,实数转换成2进制浮点数(以十六进制表示),多谢帮助解决。
      

  6.   

    //十进制转换为二进制
    function IntToBin(x:extended):string;
    var
    i,d,k,n:integer;
    dd:extended;
    s:string;
    begin
    /////////计算整数部分///////
       d:=trunc(x);
       s:='';
       while d>0 do
       begin
       k:=d shr 1;
       i:=d-(k shl 1);
       s:=inttostr(i)+s;
       d:=k;
       end;
    /////////如果有小数的话计算小数部分////////////
    if HasXiaoShu(x) then //有小数
       begin
       s:=s+'.';
       n:=GetNTen(GetXiaoShuWidth(x));
       d:=trunc((x-trunc(x))*n);
       i:=0;
       while (d>0)AND(i<8) do
          begin
          k:=d shl 1;
          if k>=n then begin s:=s+'1';k:=k-n; end else s:=s+'0';
          d:=k;
          inc(i);
          end;
       end;
    result:=s;
    end;
      

  7.   

    function HasXiaoShu(x:extended):boolean; //判断十进制是否有小数
       begin
       result:=false;
       if (x-trunc(x))>0 then
          result:=true;
       end;
       function GetNTen(n:integer):integer;//根据十进制小数部分长度得求最近的10的倍数
       var
       i:integer;
       begin
       result:=1;
       for i:=1 to n do
       result:=result*10;
       end;
    这是用到的两个函数
      

  8.   

    十进制和十六进制在内存中是一样的,
    procedure TForm1.Button1Click(Sender: TObject);
    var
      x: single;
      b: array[0..3] of byte;
      s:string;
    begin
      x:=100;
      move(x,b,sizeof(x));//b[3] 高字节,b[2],b[1],b[0]低字节
    end;
      

  9.   

    我这有一段上次写的代码,没时间给你解释了,你自己看下应该明白的:
    function HexToFloat(buff:Array of byte):Single; //Single是32位浮点数类型
    var
      P:PByte;
      i:Byte;
    begin
      P:=@Result;
      for i:=0 to Length(buff)-1 do
      begin
        P^:=buff[i];
        Inc(P);
      end;
    end;
      

  10.   

    多谢指教,能把HasXiaoShu(x)这个函数给出来吗? 
      

  11.   

    上面不是吗,给你贴出来了
    function HasXiaoShu(x:extended):boolean; //判断十进制是否有小数 
      begin 
      result:=false; 
      if (x-trunc(x))>0 then 
          result:=true; 
      end; 
      

  12.   

    能把这个函数GetXiaoShuWidth(x)给出来吗,谢谢。
      

  13.   

    function GetXiaoShuWidth(x:extended):integer;  //得到十进制小数部分的长度
       var
       s:string;
       len:integer;
       begin
       s:=floattostr(x);
       len:=length(s)-pos('.',s);
       result:=len;
       end;
      

  14.   

    function HasXiaoShu(x:extended):boolean; //判断十进制是否有小数
      begin
      result:=false;
      if (x-trunc(x))>0 then
          result:=true;
      end;
      function GetNTen(n:integer):integer;//根据十进制小数部分长度得求最近的10的倍数
      var
      i:integer;
      begin
      result:=1;
      for i:=1 to n do
      result:=result*10; 
      end;   function GetXiaoShuWidth(x:extended):integer;  //得到十进制小数部分的长度 
      var 
      s:string; 
      len:integer;
      begin 
      s:=floattostr(x); 
      len:=length(s)-pos('.',s); 
      result:=len; 
      end;//十进制转换为二进制
    function IntToBin(x:extended):string;
    var 
    i,d,k,n:integer; 
    dd:extended; 
    s:string; 
    begin 
    /////////计算整数部分/////// 
      d:=trunc(x); 
      s:='';
      while d>0 do 
      begin 
      k:=d shr 1;
      i:=d-(k shl 1);
      s:=inttostr(i)+s;
      d:=k;
      end;
    /////////如果有小数的话计算小数部分////////////
    if HasXiaoShu(x) then //有小数
      begin
      s:=s+'.'; 
      n:=GetNTen(GetXiaoShuWidth(x)); 
      d:=trunc((x-trunc(x))*n); 
      i:=0;
      while (d>0)AND(i <8) do 
          begin 
          k:=d shl 1; 
          if k>=n then begin s:=s+'1';k:=k-n; end else s:=s+'0'; 
          d:=k;
          inc(i); 
          end; 
      end; 
    result:=s; 
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
    showmessage(IntToBin(3.5));
    end;你再试试,我这儿好着呢,十进制转二进制不管是整数还是实数都可以的
      

  15.   

    你固执的很呀,
    procedure TForm1.Button1Click(Sender: TObject); 
    begin 
    showmessage(IntToBin(3.5)); 
    end; 
    3.5是不是一个实数
    显示出来的结果11.1是不是一个二进制浮点数? 真气煞人也!
      

  16.   

    你好hys_427:  有技术问题还要请教你,十进制3600变成0CE10000是作了什么转换,我的用户告诉我是十进制(3600)转成二进制浮点数的十六进制表示(0CE10000),我要完成的就是作一个通用的函数作这样的转换,请烦劳你在帮助解决一下。
      

  17.   

    你好hys_427:  只要能解决就给你分,你要多少的分,把我的分都给你。
      

  18.   

    再给你个东西,十进制转16进制的
    系统自带的那个inttohex只能够实现十进制整数到16进制的转换
    使用下面给你的函数就可以想怎么转换就怎么转换了
    函数我已经给你了,加不加分是你的权利,很多人看到你这点分,都很不情愿看下去的另外你说的
    十进制3600变成0CE10000
    如果是十进制转16进制的话,答案是肯定是错误的,因为后面那个16进制数要比3600大的多
    正常答案应该是E10下面是给你的函数function GetHexfromInt(n:integer):string;//根据0-15之间的数得到对应的十六进制符号
      begin
      case n of
      0..9:result:=inttostr(n);
      10:result:='A';
       11:result:='B';
        12:result:='C';
         13:result:='D';
          14:result:='E';
           15:result:='F';
      end;
      end;function FloatToHex(x:extended):string;//十进制转换为十六进制
    var
    d,k,i:integer;
    dd:extended;
    s:string;
    begin
    d:=trunc(x);
    s:='';
    while d>0 do
       begin
       k:=d shr 4;
       i:=d-(k shl 4);
       s:=GetHexfromInt(i)+s;
       d:=k;
       end;
       /////////如果有小数的话计算小数部分////////////
    if HasXiaoShu(x) then //有小数
       begin
       s:=s+'.';
       dd:=x-trunc(x);
       i:=0;
       while (dd>0)AND(i<6) do
          begin
          dd:=dd * 16;
          d:=trunc(dd);
          s:=s+GetHexfromInt(d);
          dd:=dd-trunc(dd);
          inc(i);
          end;
       end;
    result:=s;
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
    showmessage(FloatToHex(3600.88));
    end;
      

  19.   

    你好hys_427:  你给的函数很好,分一定给你加,但我还没解决3600转换成0CE10000的函数问题,请问怎样能给你加分,我是第一次加入咱们的论坛的,不懂这里的规则,请多多指教。
      

  20.   

    我想协议总不至于是
    procedure TForm1.Button1Click(Sender: TObject); 
    begin 
    showmessage('0C'+FloatToHex(3600)+'000'); 
    end; 
    吧,呵呵
      

  21.   

    3600-> OCE10000
    100->07C80000
    10->04A0
    5.101->03A33b64
    怎么办
    //问到了,用户用的是MCS-51/196系列单片机,IEEE浮点数标准设计的协议。
    哪为能解决,不胜感激。
      

  22.   

    各位老师好:  MCS-51单片机十进制定点数转换为二进制浮点数的问题,用钱买能解决此问题的小程序,
    测试数据是:100—>07C80000;3600—>0CE10000;5.101—>03A33B64;
      

  23.   

    几块钱?不少于RMB2000的话就帮你写一个。:)
    999按你的单片机的算法转换的话应该是0AF9C000,没错的话应该就是我推测出来的算法了。
      

  24.   

    网上找的 三字节 浮点数协议:三字节 浮点数二进制浮点操作数:用三个字节表示,第一个字节的最高位为数符,其余七位为阶码(补码形式),第二字节为尾数的高字节,第三字节为尾数的低字节,尾数用双字节纯小数(原码)来表示
    当尾数的最高位为1时,便称为规格化浮点数,简称操作数
    在程序说明中,也用[R0]或[R1]来表示R0或R1指示的浮点操作数,例如:当[R0]=-6.000时,则二进制浮点数表示为83C000H
    若(R0)=30H,则(30H)=83H,(31H)=0C0H,(32H)=00H你的可能是四字节浮点数 与 IEEE 格式不一样FUNCTION FloatToIEEEFloat(Value:SINGLE):AnsiString ;
    TYPE FLOATRE=RECORD
        CASE INTEGER OF
       0: (F1:Single);
       1: (I1:Integer);
       2: (a1:Array[0..3]of BYTE)
    END;
    var a1:FLOATRE; C1:ShortInt;
    BEGINa1.F1 :=Value;C1:=  ((a1.a1[3] AND $7F) SHL 1) OR
                 (( a1.a1[2] AND $80) SHR 7)
                 -126   ;            //重新计算阶码a1.a1[2]:=a1.a1[2] OR $80;     //填充尾数的最高位if c1>63 then        //超过可以表示的最大数
     a1.I1:=a1.I1 OR $7FFFFFFFelse if c1>=-64 then  //正常范围内
     a1.a1[3]:=(a1.a1[3] AND $80)
          OR (C1 AND $7F)else           //超过可以表示的最小数if -64-c1<23 then
     a1.I1 :=(a1.I1 AND $80000000 )OR
         $40000000 OR
          ( (a1.I1 AND $00FFFFFF) shr (-64-c1))
    else a1.I1 :=0;
    FloatToIEEEFloat:= IntToHex(a1.I1,8);
    END;
    procedure TForm1.Button1Click(Sender: TObject);beginMemo1.Lines.Add(FloatToIEEEFloat(5.101));end;
      

  25.   

    你的意思是不是要将十六进制的数 转换为 十六进制的字符串发送出去啊。给你个函数:
    function hextostring(s:string):string;
    var
      j,i: integer;
      s2: string;
    begin
      s2 := '';
      j := trunc((Length(s)/2))-1;
      for i:= 0 to j do
      s2 := s2 + chr(strtoint('$'+(copy(s, 2*i+1, 2))));
      result := s2;
    end;