下面介紹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);//Longint
var
iStart,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打開timer1
end;
因爲軟件串口的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。