?? unit1.~pas
字號:
can.Pen.Color := clBlack;
can.Pen.Style := psSolid;
can.MoveTo(0,h div 2);
can.LineTo(wid,h div 2);
can.MoveTo(wid div 2,0);
can.LineTo(wid div 2, h);
can.Font.Height := 10;
can.Font.Name := 'Arial';
{
繪制坐標的最大刻度值
}
can.TextOut(0,h div 2 +1,IntToStr(-1*round(maxV)));
can.TextOut(wid-can.TextWidth(IntToStr(round(maxV))),
h div 2 +1,IntToStr(round(maxV)));
can.TextOut(wid div 2+3,
h-can.TextHeight(IntToStr(-1*round(maxV))),IntToStr(-1*round(maxV)));
can.TextOut(wid div 2+1,0,IntToStr(round(maxV)));
{
繪制坐標的刻度,每個座標軸上有21條刻線
}
pstep := wid / 20;
for i:=0 to 21 do
begin
can.MoveTo(round(pstep*i),h div 2 - 2);
can.LineTo(round(pstep*i),h div 2);
can.MoveTo(wid div 2,round(pstep*i));
can.LineTo(wid div 2 + 2, round(pstep*i));
end;
{
繪制載入的軌跡,顏色為紅色
}
if posLengthLoad > 0 then
begin
can.Pen.Color := clRed;
ratio := h / maxV / 2;
x := round(posXArrayLoad[0]*ratio + wid/2);
y := round(h/2-posYArrayLoad[0]*ratio);
can.MoveTo(x,y);
can.Pixels[x,y] := clRed;
for i:= 1 to posLengthLoad-1 do
begin
x := round(posXArrayLoad[i]*ratio + wid/2);
y := round(h/2 - posYArrayLoad[i]*ratio);
can.LineTo(x,y);
end;
end;
{
繪制當前試驗的軌跡,顏色為藍色
}
if posLength > 0 then
begin
can.Pen.Color := clBlue;
ratio := h / maxV / 2;
x := round(posXArray[0]*ratio + wid/2);
y := round(h/2-posYArray[0]*ratio);
can.MoveTo(x,y);
can.Pixels[x,y] := $0000ff;
for i:= 1 to posLength-1 do
begin
x := round(posXArray[i]*ratio + wid/2);
y := round(h/2 - posYArray[i]*ratio);
can.LineTo(x,y);
end;
can.RoundRect(x,y,x+6,y+6,x-6,y-6);//在模型飛機的當前位置繪制一個較小的圓
end;
can.Free; //釋放 TMetaFileCanvas對象,把繪制的圖像傳遞給gpsMeta
Form1.ImgTrace.Picture.Assign(gpsMeta);//顯示軌跡圖像
end;
/////////////////////////////////////////////////////////////////
{
從用戶界面的讀取發送的數據和指令,保存到線程的內部變量或是全局變量中
}
procedure TSerialOutThread.GetData ;
begin
DataOrCode:=(Form1.rdgrpDataCode.ItemIndex=1);
Seriallength:=Length(Form1.RchdtSerialOut.Text);
SerialOutput:=Form1.RchdtSerialOut.Text;
CodeOutStr[1]:=Form1.dtCode1.Text ;
CodeOutStr[2]:=Form1.dtCode2.Text;
CodeOutStr[3]:=Form1.dtCode3.Text;
CodeOutStr[4]:=Form1.dtCode4.Text;
end;
/////////////////////////////////////////////////////////////////
{
用戶在編輯欄中輸入格式為01_12_34_56_...
首字符不能空格,必須把高位的0補上,
即確定了輸出16進制的數據0x01,0x12,0x34,0x56,...
}
procedure TSerialOutThread.PackData;
var
tmpStr:String;
MaxCount,Count,tmpInt,i:Integer;
begin
Count:=1; //動態Byte類型矩陣tmpVar的j記數變量
MaxCount:=1;//動態Byte類型矩陣tmpVar的大小
CheckOk:=True;
{使用互斥實現線程的同步,主要是為了防止數據流順序的發生錯誤}
if WaitForSingleObject(hMutex2,InFinite) =WAIT_OBJECT_0 then
begin
if Seriallength >0 then
begin
i:=1;
tmpVar:=VarArrayCreate([1,1],varByte);
while(i<Seriallength) do
begin
tmpStr:=Copy(SerialOutput,i,2);
tmpStr:=LowerCase(tmpStr);
tmpInt:=HexToInt(tmpStr);
if tmpInt<>-1 then
begin
if Count=(MaxCount+1) then
begin
MaxCount:=MaxCount+1;
VarArrayRedim(tmpVar,MaxCount);
end;
tmpVar[Count]:=tmpInt;
Count:=Count+1;
end else
begin
CheckOk:=False;//數據格式有問題,無法解讀
break; //停止while循環
end;
i:=i+3;//跳過3個字符
end;
end;
end;
ReleaseMutex(hMutex2);
end;
/////////////////////////////////////////////////////////////////
{
需要按照協議打包數據,發送幾個0x55,然后是0x24,指令代碼,結束符號0x0d,0x0a
}
procedure TSerialOutThread.PackCode;
var
tmpInt,i:Integer;
begin
tmpVar:=VarArrayCreate([1,22],varByte);
CheckOk:=True;
if WaitForSingleObject(hMutex2,InFinite) =WAIT_OBJECT_0 then
begin
for i:=1 to 15 do
begin
tmpVar[i]:=85;//0x55
end;
tmpVar[10]:=12;
tmpVar[16]:=36; //0x24=36
for i:=1 to 4 do
begin
tmpInt:=HexToInt(CodeOutStr[i]);
if tmpInt<>-1 then
tmpVar[16+i]:= tmpInt
else
begin
CheckOk:=False;
Break;
end;
end;
tmpVar[21]:=13;//0x0d
tmpVar[22]:=10;//0x0a
End;
ReleaseMutex(hMutex2);
end;
/////////////////////////////////////////////////////////////////
{
由于有調試目的,如果要求發送字符格式的數據,就直接發送用戶輸入的字符串
其他情況下,都是發送打包好的數據矩陣
}
procedure TSerialOutThread.PostData ;
begin
if CheckOk=True then
begin
// Form1.MSCommOut.Output:=tmpVar; //以16進制發送數據或指令
Form1.MSCommIn.Output:=tmpVar; //以16進制發送數據或指令
end
else
ShowMessage('數據格式有問題,發送失敗'); //一旦發現有任何錯誤,都不會發送數據
Form1.btSendOut.Enabled:=True; //串口發送線程即將結束,運行新的發送
end;
/////////////////////////////////////////////////////////////////
{
調用其它函數實現發送串口數據的功能。
注意函數GetData還沒有實現線程的互斥,
目的是把發送的數據保存在各個線程中
}
procedure TSerialOutThread.Execute;
begin
FreeOnTerminate:=True; //線程執行完后自動釋放資源
// Synchronize(GetData);
GetData;
if DataOrCode=True then
PackData //發送數據
else
PackCode;//發送指令
{
提交給串口控件實現數據的發送
嘗試調用Synchronize
}
// Synchronize(PostData);
PostData;
end;
/////////////////////////////////////////////////////////////////
{
保存串口數據,便于后面進行處理
}
procedure TSerialInThread.GetData ;
begin
Seriallength:=Form1.MSCommIn.InBufferCount;
if ReceiveCharFlag then //以文本格式接受串口數據
begin
SerialStr:=Form1.MSCommIn.Input;
end
else
begin
SerialInput:=Form1.MSCommIn.Input; //以數據格式接受串口數據
SerialStr:='';
end;
end;
/////////////////////////////////////////////////////////////////
{
根據下傳的數據轉換為適合于顯示的字符串形式
}
procedure TSerialInThread.TransToStr ;
var
i:Integer;
tmpSInt,tmpSInt1:SmallInt;
tmpDbl:double;
begin
if ADNewDataFlag =True then
begin
ADDataDblArray[0]:=0.182*(5.0/4095.0)*((15 and ADDataArray[0])*256+ADDataArray[1]-(15 and ADDataArrayMean[0])*256-ADDataArrayMean[1]);
ADStrArray[0]:=FloatToStrF(ADDataDblArray[0],ffFixed,4,3);//陀螺X
ADDataDblArray[1]:=0.182*(5.0/4095.0)*((15 and ADDataArray[2])*256+ADDataArray[3]-(15 and ADDataArrayMean[2])*256-ADDataArrayMean[3]);
ADStrArray[1]:=FloatToStrF(ADDataDblArray[1],ffFixed,4,3);//陀螺Y
ADDataDblArray[2]:=0.182*(5.0/4095.0)*((15 and ADDataArray[4])*256+ADDataArray[5]-(15 and ADDataArrayMean[4])*256-ADDataArrayMean[5]);
ADStrArray[2]:=FloatToStrF(ADDataDblArray[2],ffFixed,4,3);//陀螺Z
ADDataDblArray[3]:=(5.0/4095.0)*((15 and ADDataArray[6])*256+ADDataArray[7]-(15 and ADDataArrayMean[6])*256-ADDataArrayMean[7]);
ADStrArray[3]:=FloatToStrF(ADDataDblArray[3],ffFixed,4,3);//加速度0
ADDataDblArray[4]:=(5.0/4095.0)*((15 and ADDataArray[8])*256+ADDataArray[9]-(15 and ADDataArrayMean[8])*256-ADDataArrayMean[9]);
ADStrArray[4]:=FloatToStrF(ADDataDblArray[4],ffFixed,4,3);//加速度1
ADDataDblArray[5]:=(5.0/4095.0)*((15 and ADDataArray[10])*256+ADDataArray[11]-(15 and ADDataArrayMean[10])*256-ADDataArrayMean[11])/0.046;
ADStrArray[5]:=FloatToStrF(ADDataDblArray[5],ffFixed,4,3);//高度計
ADDataDblArray[6]:=(5.0/4095.0)*((15 and ADDataArray[12])*256+ADDataArray[13]-(15 and ADDataArrayMean[12])*256-ADDataArrayMean[13]);
ADStrArray[6]:=FloatToStrF(ADDataDblArray[6],ffFixed,4,3);//空速計
ADDataDblArray[7]:=0.00244*((15 and ADDataArray[14])*256+ADDataArray[15]);
ADStrArray[7]:=FloatToStrF(ADDataDblArray[7],ffFixed,4,3);//系統電壓
end;
if GpsNewDataFlag =True then
begin
GpsStrArray[0]:=IntToStr(256*GpsDataArray[0]+GpsDataArray[1]);//是否定位
GpsStrArray[1]:=IntToStr(GpsDataArray[3])+':'
+IntToStr(GpsDataArray[4])+':'+IntToStr(GpsDataArray[5]);//時間
tmpSInt:=GpsDataArray[6]*256+GpsDataArray[7];
GpsStrArray[2]:=IntToStr(tmpSInt); //速度,有符號16進制整數
tmpSInt:=GpsDataArray[8]*256+GpsDataArray[9];
GpsStrArray[3]:=IntToStr(tmpSInt); //方位 ,有符號16進制整數
tmpDbl:=0.1*(GpsDataArray[10]*256+GpsDataArray[11]);//高度,無符號16進制整數
GpsStrArray[4]:=FloatToStrF(tmpDbl,ffFixed,4,1);;
tmpSInt:=GpsDataArray[12]*256+GpsDataArray[13];//動向 x,有符號16進制整數
tmpSInt1:=GpsDataArray[14]*256+GpsDataArray[15];//北向 y,有符號16進制整數
GpsStrArray[5]:=IntToStr(tmpSInt);
GpsStrArray[6]:=IntToStr(tmpSInt1);
{
由于傳輸系統總會有一定的吳碼率,那么為了避免軌跡圖出現問題,例如坐標范圍過大
需要除去粗大誤差,考慮到模型飛機的飛行速度不會超過10m/s,考慮到數子傳輸系統
的下傳速度,設定如果位置變化超過20m就去掉。
}
if (abs(tmpSInt-posXArray[posLength-1])<20) and (abs(tmpSInt1-posYArray[posLength-1])<20) then
begin
posXArray[posLength] := tmpSInt;
posYArray[posLength] := tmpSInt1;
inc(posLength);
DrawAxis;
if posLength = Length(posXArray) then
begin
SetLength(posXArray,posLength+1000);
SetLength(posYArray,posLength+1000);
end;
end;
CodeInStr[0]:=LowerCase(IntToHex(GpsDataArray[16],2));
CodeInStr[1]:=LowerCase(IntToHex(GpsDataArray[17],2));
CodeInStr[2]:=LowerCase(IntToHex(GpsDataArray[18],2));
CodeInStr[3]:=LowerCase(IntToHex(GpsDataArray[19],2));
end;
end;
/////////////////////////////////////////////////////////////////
{
顯示數據
}
procedure TSerialInThread.PostData ;
var
tmpDbl:double;
i:integer;
begin
DownStr:=DownStr+SerialStr; //保存串口的數據到全局變量中
// Form1.RchdtSerialIn.Text:=SerialStr; //文本只是顯示最新的數據
Form1.RchdtSerialIn.Text:=Form1.RchdtSerialIn.Text+chr(13)+char(10)+SerialStr;//顯示下傳的所有數據
{
如果數據量比較大,執行完上面的代碼后,控件總是會調整后顯示最初的文本。
為了將最新的數據顯示給用戶,這里調用了控件的Perform函數,使得控件顯
示當前插入符所在的位置,而事先設置插入符的位置為上一次接受文本的末尾。
}
if Seriallength>0 then
begin
Form1.RchdtSerialIn.SelStart := Length(Form1.RchdtSerialIn.Text)-Seriallength;
Form1.RchdtSerialIn.Perform(EM_SCROLLCARET, 0, 0);
end;
if ADNewDataFlag =True then//顯示新的傳感器數據包
begin
ADNewDataFlag:=False;
Form1.lbShowAd0.Caption:=ADStrArray[0];
Form1.lbShowAd1.Caption:=ADStrArray[1];
Form1.lbShowAd2.Caption:=ADStrArray[2];
Form1.lbShowAd3.Caption:=ADStrArray[3];
Form1.lbShowAd4.Caption:=ADStrArray[4];
Form1.lbShowAd5.Caption:=ADStrArray[5];
Form1.lbShowAd6.Caption:=ADStrArray[6];
Form1.lbShowAd7.Caption:=ADStrArray[7];
Form1.srsGyroX .AddY(ADDataDblArray[0]);
Form1.srsGyroY .AddY(ADDataDblArray[1]);
Form1.srsGyroZ .AddY(ADDataDblArray[2]);
Form1.srsAcc1 .AddY(ADDataDblArray[3]);
Form1.srsAcc2 .AddY(ADDataDblArray[4]);
Form1.srsHeight .AddY(ADDataDblArray[5]);
end;
if GpsNewDataFlag =True then //顯示新的GPS數據包
begin
GpsNewDataFlag:=False;
Form1.lbShowGps0.Caption:=GpsStrArray[0];
Form1.lbShowGps1.Caption:=GpsStrArray[1];
Form1.lbShowGps2.Caption:=GpsStrArray[2];
Form1.lbShowGps3.Caption:=GpsStrArray[3];
Form1.lbShowGps4.Caption:=GpsStrArray[4];
Form1.lbShowGps5.Caption:=GpsStrArray[5];
Form1.lbShowGps6.Caption:=GpsStrArray[6];
Form1.lbCode1.Caption:=CodeInStr[0]; //顯示下傳的4個指令代碼
Form1.lbCode2.Caption:=CodeInStr[1];
Form1.lbCode3.Caption:=CodeInStr[2];
Form1.lbCode4.Caption:=CodeInStr[3];
end;
if ParaNewDataFlag then //顯示新的參數數據包
begin
ParaNewDataFlag:=False;
Form1.lbShowPara0.Caption:=IntToStr(ParaDataArray[0]);
Form1.lbShowPara1.Caption:=IntToStr(ParaDataArray[1]);
Form1.lbShowPara2.Caption:=IntToStr(ParaDataArray[2]);
Form1.lbShowPara3.Caption:=IntToStr(ParaDataArray[3]);
Form1.lbShowPara4.Caption:=IntToStr(ParaDataArray[4]);
Form1.lbShowPara5.Caption:=IntToStr(ParaDataArray[5]);
Form1.lbShowPara6.Caption:=IntToStr(ParaDataArray[6]);
Form1.lbShowPara7.Caption:=IntToStr(ParaDataArray[7]);
Form1.lbShowModel.Caption:=IntToHex(ParaDataArray[8],2);
end;
end;
/////////////////////////////////////////////////////////////////
{
這是執行數據接受,截取數據包的過程。調用其它函數獲取數據、轉換格式和進行顯示
}
procedure TSerialInThread.Execute;
var
tmpInt,i:Integer;
curStr:String;
begin
FreeOnTerminate:=True; //線程執行完后自動釋放資源
// Synchronize(GetData);
GetData; //獲取串口數據
if not ReceiveCharFlag then
begin
if WaitForSingleObject(hMutex,InFinite) =WAIT_OBJECT_0 then
begin
if Seriallength >0 then
begin
for i:= 0 to Seriallength-1 do //逐一處理串口數據
begin
tmpInt:=SerialInput[i]; //獲取當前一個數據
curStr:=LowerCase(IntToHex(tmpInt,2));//轉換為16進制的字符
SerialStr :=SerialStr + curStr+' '; //便于顯示和保存
{
發現參數數據包
}
if (curStr='fe') and (not ADDataFlag)
and (not GpsDataFlag) and (not ParaDataFlag)then
begin
ParaDataFlag:=True;
ParaDataCount:=0;
end
{
發現GPS數據包
}
else if (curStr='fc') and (not ADDataFlag)
and (not GpsDataFlag)and (not ParaDataFlag) then
begin
GpsDataFlag:=True;
GpsDataCount:=0;
GpsStr:=GpsStr+chr(13) + chr(10);//保存數據
end
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -