“多负载识别监控平台(上位机)”技术细节 之Unit1-Form1主界面

来源:互联网 发布:浙江航天恒嘉数据科技 编辑:程序博客网 时间:2024/06/03 20:53

下面介绍Unit1主界面的实现。


1.Timer2

Timer2是用来显示系统时间用的时钟,每30秒刷新一次,因此系统时间只能显示到分钟了……

procedure TForm1.Timer2Timer(Sender: TObject);{---------------------显示系统时间的 定时中断2}var                                                                                //定时30s  Time:TDateTime;//系统时间begin  Time:=now;  if copy(TimetoStr(time),5,1)=':' then    TeStatusBar1.Panels[4].Text := Datetostr(time)+' '+leftstr(TimeToStr(Time),4)  else    TeStatusBar1.Panels[4].Text := Datetostr(time)+' '+leftstr(TimeToStr(Time),5);//在状态栏显示系统时间end;

为了完整的取出系统时间,在delphi中要使用now函数,参考http://blog.csdn.net/yorkworlddream/article/details/17500683

使用DatetoStr来取出time中的日期,即年月日,使用TimeToStr取出time中的时间,即时分秒。

copy函数举例:Copy(Str,2,2)=el;//从Str字符串变量的中第2个字符开始取长度为2个字符的字符串,即一个从指定位置截取指定长度字符的函数。

举例两种时间:18:26:00和12:3:4,对于第一个时间值,直接使用leftstr(TimeToStr(Time),4);即可直接取出time的时分为18:26,但可以看到第二个时间中的“分”为个位数,要是依然使用前面的语句,那就会取出12:3:这样的显示是不行的,所以要判断time的“分”是不是为个位,即使用语句if copy(TimetoStr(time),5,1)=':' then来判断。

注:copy函数数字符串,起始计数为1,即对于时间18:26中的8是第2位。

2.Timer1

Timer1用来每5分钟刷新一次继电器状态。

procedure TForm1.Timer1Timer(Sender: TObject);{----------------------------------定时器中断1}var                                                                              //定时5分钟  Time:TDateTime;//系统时间  nowDate,nowTime : string;  nowMinute : integer;begin  Time:=now;//只有now才正确,参考http://blog.csdn.net/yorkworlddream/article/details/17500683  nowTime := TimeToStr(Time);  //5分钟自动扫描继电器状态  nowMinute := strtoint(copy(nowTime,4,2));//copy用于截取 http://blog.csdn.net/yorkworlddream/article/details/17500855  if nowMinute > lastMinute then//lastMinute全局变量    begin      sysSendState := 0;//设置全局变量sysSendState为0,即发送 查询继电器状态 帧      timer3.Enabled:=true;//开定时器3,让它负责发送,发完让它自己关掉自己      lastMinute := nowMinute;    end;//  tememo1.Lines.Add(b0cxjdq);//对memo进行操作使用add方法end;
Timer1只负责到时开timer3,自己不负责查询帧的发送,查询帧数据是由Timer3来发送的。

3.Timer3

Timer3用来发送继电器的查询命令帧、继电器的控制命令帧,每500ms被触发一次,每触发一次发送一个表的查询或控制命令帧。Timer3由其他定时器开启,发送完成后被自身关闭。

procedure TForm1.Timer3Timer(Sender: TObject);{------用于串口发数,每500ms触发一次 定时中断3}begin                                                                             //定时500ms{0}  if sysSendState =0  then//发送 查询继电器状态 帧  begin    if bhindex = 9 then      begin        comport1.WriteStr(Hexstrtostr(b9cxjdq));//调用Hexstrtostr函数        tememo1.Text:= b9cxjdq;//显示要发出的数据        bhIndex := 0;//表号归0,=0表示下次要发送表号0的帧数据,即从新开始了        timer3.Enabled:=false;//自己关断自己,它的开要由timer1来决定        timer1.Enabled:=true;//打开timer1      end    else if bhindex = 8 then      begin        comport1.WriteStr(Hexstrtostr(b8cxjdq));//调用Hexstrtostr函数        tememo1.Text:= b8cxjdq;//显示要发出的数据        bhIndex := bhIndex +1;//表号加1,=9表示下次要发送表号9的帧数据      end    else if bhindex = 7 then      begin        comport1.WriteStr(Hexstrtostr(b7cxjdq));//调用Hexstrtostr函数        tememo1.Text:= b7cxjdq;//显示要发出的数据        bhIndex := bhIndex +1;//表号加1,=8表示下次要发送表号8的帧数据      end    else if bhindex = 6 then      begin        comport1.WriteStr(Hexstrtostr(b6cxjdq));//调用Hexstrtostr函数        tememo1.Text:= b6cxjdq;//显示要发出的数据        bhIndex := bhIndex +1;//表号加1,=7表示下次要发送表号7的帧数据      end    else if bhindex = 5 then      begin        comport1.WriteStr(Hexstrtostr(b5cxjdq));//调用Hexstrtostr函数        tememo1.Text:= b5cxjdq;//显示要发出的数据        bhIndex := bhIndex +1;//表号加1,=6表示下次要发送表号6的帧数据      end    else if bhindex = 4 then      begin        comport1.WriteStr(Hexstrtostr(b4cxjdq));//调用Hexstrtostr函数        tememo1.Text:= b4cxjdq;//显示要发出的数据        bhIndex := bhIndex +1;//表号加1,=5表示下次要发送表号5的帧数据      end    else if bhindex = 3 then      begin        comport1.WriteStr(Hexstrtostr(b3cxjdq));//调用Hexstrtostr函数        tememo1.Text:= b3cxjdq;//显示要发出的数据        bhIndex := bhIndex +1;//表号加1,=4表示下次要发送表号4的帧数据      end    else if bhindex = 2 then      begin        comport1.WriteStr(Hexstrtostr(b2cxjdq));//调用Hexstrtostr函数        tememo1.Text:= b2cxjdq;//显示要发出的数据        bhIndex := bhIndex +1;//表号加1,=3表示下次要发送表号3的帧数据      end    else if bhindex = 1 then      begin        comport1.WriteStr(Hexstrtostr(b1cxjdq));//调用Hexstrtostr函数        tememo1.Text:= b1cxjdq;//显示要发出的数据        bhIndex := bhIndex +1;//表号加1,=2表示下次要发送表号2的帧数据      end    else if bhIndex = 0 then      begin        comport1.WriteStr(Hexstrtostr(b0cxjdq));//调用Hexstrtostr函数        tememo1.Text:= b0cxjdq;//显示要发出的数据        bhIndex := bhIndex +1;//表号加1,=1表示下次要发送表号1的帧数据      end;  end;{1}  if sysSendState = 1 then//发送 开关继电器 帧  begin    if gI=0 then    begin      if jdqRadioBtn0k.Checked = true then//00表设置为开        begin          comport1.WriteStr(Hexstrtostr(b0kjdq)); //调用Hexstrtostr函数          tememo1.Text:= b0kjdq;//显示要发出的数据        end//---------------------------------------------------------------注意else前无分号      else        begin          comport1.WriteStr(Hexstrtostr(b0gjdq));          tememo1.Text:= b0gjdq;        end;    end    else if gI=1 then    begin      if jdqRadioBtn1k.Checked = true then//01表设置为开        begin          comport1.WriteStr(Hexstrtostr(b1kjdq)); //调用Hexstrtostr函数          tememo1.Text:= b1kjdq;//显示要发出的数据        end      else        begin          comport1.WriteStr(Hexstrtostr(b1gjdq));          tememo1.Text:= b1gjdq;        end;    end    else if gI=2 then    begin      if jdqRadioBtn2k.Checked = true then//02表设置为开        begin          comport1.WriteStr(Hexstrtostr(b2kjdq)); //调用Hexstrtostr函数          tememo1.Text:= b2kjdq;//显示要发出的数据        end      else        begin          comport1.WriteStr(Hexstrtostr(b2gjdq));          tememo1.Text:= b2gjdq;        end;    end    else if gI=3 then    begin      if jdqRadioBtn3k.Checked = true then//03表设置为开        begin          comport1.WriteStr(Hexstrtostr(b3kjdq)); //调用Hexstrtostr函数          tememo1.Text:= b3kjdq;//显示要发出的数据        end      else        begin          comport1.WriteStr(Hexstrtostr(b3gjdq));          tememo1.Text:= b3gjdq;        end;    end    else if gI=4 then    begin      if jdqRadioBtn4k.Checked = true then//04表设置为开        begin          comport1.WriteStr(Hexstrtostr(b4kjdq)); //调用Hexstrtostr函数          tememo1.Text:= b4kjdq;//显示要发出的数据        end      else        begin          comport1.WriteStr(Hexstrtostr(b4gjdq));          tememo1.Text:= b4gjdq;        end;    end    else if gI=5 then    begin      if jdqRadioBtn5k.Checked = true then//05表设置为开        begin          comport1.WriteStr(Hexstrtostr(b5kjdq)); //调用Hexstrtostr函数          tememo1.Text:= b5kjdq;//显示要发出的数据        end      else        begin          comport1.WriteStr(Hexstrtostr(b5gjdq));          tememo1.Text:= b5gjdq;        end;    end    else if gI=6 then    begin      if jdqRadioBtn6k.Checked = true then//06表设置为开        begin          comport1.WriteStr(Hexstrtostr(b6kjdq)); //调用Hexstrtostr函数          tememo1.Text:= b6kjdq;//显示要发出的数据        end      else        begin          comport1.WriteStr(Hexstrtostr(b6gjdq));          tememo1.Text:= b6gjdq;        end;    end    else if gI=7 then    begin      if jdqRadioBtn7k.Checked = true then//07表设置为开        begin          comport1.WriteStr(Hexstrtostr(b7kjdq)); //调用Hexstrtostr函数          tememo1.Text:= b7kjdq;//显示要发出的数据        end      else        begin          comport1.WriteStr(Hexstrtostr(b7gjdq));          tememo1.Text:= b7gjdq;        end;    end    else if gI=8 then    begin      if jdqRadioBtn8k.Checked = true then//08表设置为开        begin          comport1.WriteStr(Hexstrtostr(b8kjdq)); //调用Hexstrtostr函数          tememo1.Text:= b8kjdq;//显示要发出的数据        end      else        begin          comport1.WriteStr(Hexstrtostr(b8gjdq));          tememo1.Text:= b8gjdq;        end;    end    else if gI=9 then    begin      if jdqRadioBtn9k.Checked = true then//09表设置为开        begin          comport1.WriteStr(Hexstrtostr(b9kjdq)); //调用Hexstrtostr函数          tememo1.Text:= b9kjdq;//显示要发出的数据        end      else        begin          comport1.WriteStr(Hexstrtostr(b9gjdq));          tememo1.Text:= b9gjdq;        end;      timer1.Enabled:=true;//发送完成,打开timer1      timer3.Enabled:=false;//发送完成,timer3关闭自己      gI := 0;      sysSendState :=0;//初始的系统发送状态归为0,即 查询继电器 帧    end;    gI := gI + 1;  end;end;
由于查询继电器状态和控制继电器是由不同的控件触发的,所以为了区分是查询还是控制,使用了一个全局变量sysSendState来进行判断,当sysSendState=0时代表查询,=1时为控制。

gI的左右就是Timer3被触发一次,自己加1,可以保证每次发送的只是一个表的数据,因为我在刚开始写这段程序的时候怕上位机发的太快,下面下位机抢占485总线,使发送与应答冲突,就想着隔500ms发一个帧,由于开始用的不熟练,只想到了这个办法,现在看,只要编写一个delay函数即可。函数如下:

procedure Delay(dwMilliseconds:DWORD);//LongintvariStart,iStop:DWORD;begin    iStart :=   GetTickCount;    repeat    iStop  :=   GetTickCount;    Application.ProcessMessages;    until (iStop  -  iStart) >= dwMilliseconds;end;
在Timer3中发送的帧代码使用的全局字符串变量,直接将帧写好,发的时候直接发字符串名即可,当然,这个方法也很浪费代码,没办法,最先写的Form1的程序,才入门也只能这样了,帧的字符串变量如下:

  b0gjdq   : string[44]=  '68 00 30 00 00 00 00 68 04 03 e6 83 00 13 16';//关继电器  b0kjdq   : string[44]=  '68 00 30 00 00 00 00 68 04 03 e6 83 01 13 16';//开继电器  b0cxjdq  : string[41]=  '68 00 30 00 00 00 00 68 01 02 e7 83 13 16';   //查询继电器  b0cxdn   : string[41]=  '68 00 30 00 00 00 00 68 01 02 44 c3 13 16';   //查询电能  b0cxgl   : string[41]=  '68 00 30 00 00 00 00 68 01 02 64 e9 13 16';   //查询功率  //表1  b1gjdq   : string[44]=  '68 01 30 00 00 00 00 68 04 03 e6 83 00 13 16';//关继电器  b1kjdq   : string[44]=  '68 01 30 00 00 00 00 68 04 03 e6 83 01 13 16';//开继电器  b1cxjdq  : string[41]=  '68 01 30 00 00 00 00 68 01 02 e7 83 13 16';   //查询继电器  b1cxdn   : string[41]=  '68 01 30 00 00 00 00 68 01 02 44 c3 13 16';   //查询电能  b1cxgl   : string[41]=  '68 01 30 00 00 00 00 68 01 02 64 e9 13 16';   //查询功率  //表2  b2gjdq   : string[44]=  '68 02 30 00 00 00 00 68 04 03 e6 83 00 13 16';//关继电器  b2kjdq   : string[44]=  '68 02 30 00 00 00 00 68 04 03 e6 83 01 13 16';//开继电器  b2cxjdq  : string[41]=  '68 02 30 00 00 00 00 68 01 02 e7 83 13 16';   //查询继电器  b2cxdn   : string[41]=  '68 02 30 00 00 00 00 68 01 02 44 c3 13 16';   //查询电能  b2cxgl   : string[41]=  '68 02 30 00 00 00 00 68 01 02 64 e9 13 16';   //查询功率  //表3  b3gjdq   : string[44]=  '68 03 30 00 00 00 00 68 04 03 e6 83 00 13 16';//关继电器  b3kjdq   : string[44]=  '68 03 30 00 00 00 00 68 04 03 e6 83 01 13 16';//开继电器  b3cxjdq  : string[41]=  '68 03 30 00 00 00 00 68 01 02 e7 83 13 16';   //查询继电器  b3cxdn   : string[41]=  '68 03 30 00 00 00 00 68 01 02 44 c3 13 16';   //查询电能  b3cxgl   : string[41]=  '68 03 30 00 00 00 00 68 01 02 64 e9 13 16';   //查询功率  //表4  b4gjdq   : string[44]=  '68 04 30 00 00 00 00 68 04 03 e6 83 00 13 16';//关继电器  b4kjdq   : string[44]=  '68 04 30 00 00 00 00 68 04 03 e6 83 01 13 16';//开继电器  b4cxjdq  : string[41]=  '68 04 30 00 00 00 00 68 01 02 e7 83 13 16';   //查询继电器  b4cxdn   : string[41]=  '68 04 30 00 00 00 00 68 01 02 44 c3 13 16';   //查询电能  b4cxgl   : string[41]=  '68 04 30 00 00 00 00 68 01 02 64 e9 13 16';   //查询功率  //表5  b5gjdq   : string[44]=  '68 05 30 00 00 00 00 68 04 03 e6 83 00 13 16';//关继电器  b5kjdq   : string[44]=  '68 05 30 00 00 00 00 68 04 03 e6 83 01 13 16';//开继电器  b5cxjdq  : string[41]=  '68 05 30 00 00 00 00 68 01 02 e7 83 13 16';   //查询继电器  b5cxdn   : string[41]=  '68 05 30 00 00 00 00 68 01 02 44 c3 13 16';   //查询电能  b5cxgl   : string[41]=  '68 05 30 00 00 00 00 68 01 02 64 e9 13 16';   //查询功率  //表6  b6gjdq   : string[44]=  '68 06 30 00 00 00 00 68 04 03 e6 83 00 13 16';//关继电器  b6kjdq   : string[44]=  '68 06 30 00 00 00 00 68 04 03 e6 83 01 13 16';//开继电器  b6cxjdq  : string[41]=  '68 06 30 00 00 00 00 68 01 02 e7 83 13 16';   //查询继电器  b6cxdn   : string[41]=  '68 06 30 00 00 00 00 68 01 02 44 c3 13 16';   //查询电能  b6cxgl   : string[41]=  '68 06 30 00 00 00 00 68 01 02 64 e9 13 16';   //查询功率  //表7  b7gjdq   : string[44]=  '68 07 30 00 00 00 00 68 04 03 e6 83 00 13 16';//关继电器  b7kjdq   : string[44]=  '68 07 30 00 00 00 00 68 04 03 e6 83 01 13 16';//开继电器  b7cxjdq  : string[41]=  '68 07 30 00 00 00 00 68 01 02 e7 83 13 16';   //查询继电器  b7cxdn   : string[41]=  '68 07 30 00 00 00 00 68 01 02 44 c3 13 16';   //查询电能  b7cxgl   : string[41]=  '68 07 30 00 00 00 00 68 01 02 64 e9 13 16';   //查询功率  //表8  b8gjdq   : string[44]=  '68 08 30 00 00 00 00 68 04 03 e6 83 00 13 16';//关继电器  b8kjdq   : string[44]=  '68 08 30 00 00 00 00 68 04 03 e6 83 01 13 16';//开继电器  b8cxjdq  : string[41]=  '68 08 30 00 00 00 00 68 01 02 e7 83 13 16';   //查询继电器  b8cxdn   : string[41]=  '68 08 30 00 00 00 00 68 01 02 44 c3 13 16';   //查询电能  b8cxgl   : string[41]=  '68 08 30 00 00 00 00 68 01 02 64 e9 13 16';   //查询功率  //表9  b9gjdq   : string[44]=  '68 09 30 00 00 00 00 68 04 03 e6 83 00 13 16';//关继电器  b9kjdq   : string[44]=  '68 09 30 00 00 00 00 68 04 03 e6 83 01 13 16';//开继电器  b9cxjdq  : string[41]=  '68 09 30 00 00 00 00 68 01 02 e7 83 13 16';   //查询继电器  b9cxdn   : string[41]=  '68 09 30 00 00 00 00 68 01 02 44 c3 13 16';   //查询电能  b9cxgl   : string[41]=  '68 09 30 00 00 00 00 68 01 02 64 e9 13 16';   //查询功率

由于帧字符串是用字符串来表示十六进制,即“68”表示0x68,这样直接下传是不对的,所以要使用到HexStrToStr函数,将“68”真正的转为0x68

HexStrToStr:

{16进制字符串转换成字符串}function HexStrToStr(const S:string):string;//16进制字符串转换成字符串var  t:Integer;  ts:string;  M,Code:Integer;begin  t:=1;  Result:='';  while t<=Length(S) do  begin    while not (S[t] in ['0'..'9','A'..'F','a'..'f']) do      inc(t);    if (t+1>Length(S))or(not (S[t+1] in ['0'..'9','A'..'F','a'..'f'])) then      ts:='$'+S[t]    else      ts:='$'+S[t]+S[t+1];    Val(ts,M,Code);    if Code=0 then      Result:=Result+Chr(M);    inc(t,2);  end;end;


4.Timer4

Timer4用于记录存储用户的电量到数据库中。

4.1若数据库中没有本日的数据,那么就要在每个表的数据表Table中新建一行当日的数据。

  ibquery1.SQL.Clear;  ibquery1.SQL.Add('select count(*) from BH0 where U_year=:A and U_month=:B and U_day=:D');  ibquery1.Params.ParamByName('A').Value := pNowYear;  ibquery1.Params.ParamByName('B').Value := pNowMonth;  ibquery1.Params.ParamByName('D').Value := pNowDay;  ibquery1.Open;  tempInt1 := ibquery1.FieldByName('count').Asinteger;//查询看是否有用现在的年月做的行  if tempInt1 = 0 then //如果等于0 说明没有现在年月日的行  begin    for i := 0 to 9 do    begin      tempStr1 := inttoStr(i);//i代表表号      ibquery1.SQL.Clear;      ibquery1.SQL.Add('Insert into BH'+tempStr1+' Values(:B,:C,:D,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)');      ibquery1.Params.ParamByName('B').Value := pNowYear;      ibquery1.Params.ParamByName('C').Value := pNowMonth;      ibquery1.Params.ParamByName('D').Value := pNowDay; ibquery1.ExecSQL; end;//部分代码,不全

其中,为SQL语句输入变量的方法如上代码段

      ibquery1.SQL.Add('Insert into BH'+tempStr1+' Values(:B,:C,:D,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)');      ibquery1.Params.ParamByName('B').Value := pNowYear;      ibquery1.Params.ParamByName('C').Value := pNowMonth;      ibquery1.Params.ParamByName('D').Value := pNowDay;      ibquery1.ExecSQL;

语句ibquery1.Params.ParamByName('B').Value :=?;中的?只需与数据表中的类型一致即可,不要求必须是字符型。
举例来看:

    Form1.IBQuery1.sql.Add('Insert into loadmatrix(loadIndex,loadname,phase,har1,har3,har5,har7,har9)');    Form1.IBQuery1.sql.Add('Values(:A,:B,:C,:D,:E,:F,:G,:H)');    Form1.IBQuery1.Params.ParamByName('A').Value:=(maxIndex+1) ;//integer型    Form1.IBQuery1.Params.ParamByName('B').Value:=editname.Text ;//char型    Form1.IBQuery1.Params.ParamByName('C').Value:=strtofloat(editphase.Text) ;//float型

从这段代码中不仅可以看出ibquery1.Params.ParamByName('B').Value :=?;语句的使用,也可以发现,使用IBQuery进行SQL语句传输时,还可以拆成两句来书写。

5.“开始”

工具栏中的“开始”按钮,用来开启串口,并且使能那些与串口有关的控件。

//==========================================================================================procedure TForm1.toolButtonkaishiClick(Sender: TObject);{-----------------工具栏 开始 button}begin  comport1.Port := form4.ckCombo.Items[form4.ckCombo.ItemIndex];//由unit4选择串口号  comport1.BaudRate := br9600;  ComPort1.Open;  TeStatusBar1.Panels[1].Text := '运行';//在状态栏显示运行状态  timer3.Enabled:=true;  timer4.enabled:=true;  jdqButton.Enabled:=true;  glckButton.Enabled:=true;  glckjdqButton.Enabled:=true;//timer1.Enabled:=true;//上面这句在timer3中实现,即首次点击“开始”,先发送一次数据,由timer3打开timer1end;

因为软件串口的COM口和波特率是在form4(软件设置)中设置的,因此串口控件Comport的port号要从form4中获取,这里我们看到了如何去下拉菜单的参数的方法。

从整体看,语句为 Items[ ItemIndex ];

6.串口中断

参考:http://blog.csdn.net/yorkworlddream/article/details/17384801

即自己编写一个过程,将这个过程与ComPort1.ComPRxChar进行连接



之后在这个过程中对串口接收到的数进行处理即可。

这里需要注意一下几点:

1.若串口接收的是16进制数据,那么使用ComPort1.ReadStr(Str, Count);语句将comport自动计数的count个数据存入了str中,comport的存储方法是转每一个16进制数为一个字符,即收到十六进制68,存入str中的为字符h,而不是字符串68。因此在后面使用copy的时候,要copy出68,只要copy(?,1);即可。

举例,按照645规约的帧结构,取出表号的代码为:

  ComPort1.ReadStr(Str, Count);  bhStr := copy(Str,2,1);//获取表号。68算一个数,从第2个计算一个数,即为表号00或01

2.对于功率等传过来的4个字节16进制数,要转为float型,要使用一下函数:

  //64 e9 查功率帧返回  if ansiSameText('64 e9',StrtoHexStr(orderStr)) then  begin    dataStr := copy(str,13,4);//取得该表数据字段,即功率    dataStr := spaceprocess(StrToHexStr(dataStr));//先将16进制转成字符串,之后去空格    teedit1.Text := floattostr(HextoFloat(dataStr));//将十六进制字符转成float,再成字符型进行显示  end;

先取出4字节的十六进制数据,之后将字符串转成十六进制字符串,因为就像上面说的,得到的十六进制68存的是h,并不是字符串68,因此要转换一下,使用StrToHexStr,

之后去除字符串中的空格,比如C1 48 00 00字符串即被转为C1480000,

之后再使用十六进制字符串转float函数,HexToFloat,将十六进制转为浮点型,

为了显示用,可以再将float转为字符串。

用流程表示上述转换过程: 

收到的16进制数据---comport1.readStr---->

ascii对应的字符串----StrToHexStr----->

“68 00”这样的字符串---spaceprocess---->

"6800"这样的字符串----HexToFloat---->

float型数据------floatToStr------->

将float转成字符串用于显示

粘上各个函数的代码:

StrToHexStr:

{字符串转换成16进制字符串}function StrToHexStr(const S:string):string;//字符串转换成16进制字符串var  I:Integer;begin  for I:=1 to Length(S) do  begin    if I=1 then      Result:=IntToHex(Ord(S[1]),2)    else Result:=Result+' '+IntToHex(Ord(S[I]),2);  end;end;

spaceprocess:

{去字符串中的空格}function SpaceProcess(S: String): String;var  i : Integer;begin  Result := '';  for i := 1 to Length(S) do  begin    if S[i] <> ' ' then    begin      Result := Result + S[i];    end;  end;end;
HexToFloat:

{二进制 to 十进制}function BintoInt(Value: String): LongInt;var  i,Size: Integer;begin  Result:=0;  Size:=Length(Value);  for i:=Size downto 1 do  begin    if Copy(Value,i,1)='1' then    Result:=Result+(1 shl (Size-i));  end;end;function floatBintoInt(Value: String): real;var  i,Size: Integer;begin  Result:=0;  Size:=Length(Value);  for i:=Size downto 1 do  begin    if Copy(Value,i,1)='1' then    Result:=Result+1/(1 shl i);  end;end;{十六进制 to 二进制}function HextoBinary(Hex:string):string;const  BOX: array [0..15] of string =  ('0000','0001','0010','0011',  '0100','0101','0110','0111',  '1000','1001','1010','1011',  '1100','1101','1110','1111');var  i:integer;begin  for i:=Length(Hex) downto 1 do    Result:=BOX[StrToInt('$'+Hex[i])]+Result;end;{十六进制 to 十进制 浮点型}function HextoFloat(s:string):real;var  b,temp:string;  e:integer;  f:real;begin  b:=HextoBinary(s);  temp := copy(b,2,8);  e:=BintoInt(temp)-127;  temp := copy(b,10,23);  f := 1+floatBintoInt(temp);  if(copy(b,1,1)='0')then    result := power(2,e)*f //------------------------------------------------要引用单元math  else    result :=-power(2,e)*f;end;

7.数据库连接

参考:http://blog.csdn.net/yorkworlddream/article/details/17473913

Char显示数据参考:http://blog.csdn.net/yorkworlddream/article/details/17469487

还是笨方法:

//==========================================================================================procedure TForm1.dlcxButtonClick(Sender: TObject);{-----------------电量曲线查询 确定 button}var  i : integer;  adayhour : array [1..24] of real;//设一个数组,用来放24小时的数据  Time:TDateTime;//系统时间  nowDate,nowYear,nowMonth,nowDay : string;//用来存放当前的系统时间begin  Time := now;//取当前时间  nowDate := DateToStr(Time);  nowYear:=leftStr(nowDate,4);//取年  nowMonth:=copy(nowDate,6,2);//取月  nowDay:=copy(nowDate,9,2);//取日//  tememo2.Text := nowDate;//  tememo1.Text := nowYear+nowMonth+nowDay;  IBdatabase1.Connected:=true;  IBquery1.Close;  ibquery1.SQL.Clear;  case dlcxCombo.ItemIndex of    0:ibquery1.SQL.Add('select * from BH0 where u_day='+ nowDay +                        'and u_month=' + nowMonth + 'and u_year=' + nowYear);//查询当年月日的数据    1:ibquery1.SQL.Add('select * from BH1 where u_day='+ nowDay +                        'and u_month=' + nowMonth + 'and u_year=' + nowYear);    2:ibquery1.SQL.Add('select * from BH2 where u_day='+ nowDay +                        'and u_month=' + nowMonth + 'and u_year=' + nowYear);    3:ibquery1.SQL.Add('select * from BH3 where u_day='+ nowDay +                        'and u_month=' + nowMonth + 'and u_year=' + nowYear);    4:ibquery1.SQL.Add('select * from BH4 where u_day='+ nowDay +                        'and u_month=' + nowMonth + 'and u_year=' + nowYear);    5:ibquery1.SQL.Add('select * from BH5 where u_day='+ nowDay +                        'and u_month=' + nowMonth + 'and u_year=' + nowYear);    6:ibquery1.SQL.Add('select * from BH6 where u_day='+ nowDay +                        'and u_month=' + nowMonth + 'and u_year=' + nowYear);    7:ibquery1.SQL.Add('select * from BH7 where u_day='+ nowDay +                        'and u_month=' + nowMonth + 'and u_year=' + nowYear);    8:ibquery1.SQL.Add('select * from BH8 where u_day='+ nowDay +                        'and u_month=' + nowMonth + 'and u_year=' + nowYear);    9:ibquery1.SQL.Add('select * from BH9 where u_day='+ nowDay +                        'and u_month=' + nowMonth + 'and u_year=' + nowYear);  end;  ibquery1.Open;  //这时值已经放到IBQuery中了  adayhour[1] := ibquery1.FieldByName('H1').AsFloat ;//按字段名取出数据,分别放到数组中  adayhour[2] := ibquery1.FieldByName('H2').AsFloat ;//因为数据类型不一样,所以要加.asfloat  adayhour[3] := ibquery1.FieldByName('H3').AsFloat ;  adayhour[4] := ibquery1.FieldByName('H4').AsFloat ;  adayhour[5] := ibquery1.FieldByName('H5').AsFloat ;  adayhour[6] := ibquery1.FieldByName('H6').AsFloat ;  adayhour[7] := ibquery1.FieldByName('H7').AsFloat ;  adayhour[8] := ibquery1.FieldByName('H8').AsFloat ;  adayhour[9] := ibquery1.FieldByName('H9').AsFloat ;  adayhour[10] := ibquery1.FieldByName('H10').AsFloat ;  adayhour[11] := ibquery1.FieldByName('H11').AsFloat ;  adayhour[12] := ibquery1.FieldByName('H12').AsFloat ;  adayhour[13] := ibquery1.FieldByName('H13').AsFloat ;  adayhour[14] := ibquery1.FieldByName('H14').AsFloat ;  adayhour[15] := ibquery1.FieldByName('H15').AsFloat ;  adayhour[16] := ibquery1.FieldByName('H16').AsFloat ;  adayhour[17] := ibquery1.FieldByName('H17').AsFloat ;  adayhour[18] := ibquery1.FieldByName('H18').AsFloat ;  adayhour[19] := ibquery1.FieldByName('H19').AsFloat ;  adayhour[20] := ibquery1.FieldByName('H20').AsFloat ;  adayhour[21] := ibquery1.FieldByName('H21').AsFloat ;  adayhour[22] := ibquery1.FieldByName('H22').AsFloat ;  adayhour[23] := ibquery1.FieldByName('H23').AsFloat ;  adayhour[24] := ibquery1.FieldByName('H24').AsFloat ;  series1.Clear;//要先清空series,要不他会总add  with series1 do  begin    for i := 1 to 24 do      add(adayhour[i]);  end;end;

取出数据库返回的值使用语句 ibquery1.FieldByName('?'),要是返回的是 float 则加入 .AsFloat 即可。

8.IOComp工控指示灯

这个指示灯的关闭状态和激发状态是由

来控制的

使用语句

jdqled0.Active:=ansiSameText('01',strtohexstr(dataStr));//若数据字段为01则说明jdq开

就可以开关指示灯,函数ansiSameText是字符串比较函数,返回值为true或者false。



0 0