junrong 发表于 2013-1-3 21:00:37

delphi串口接收数据有错误

本人想利用delphi接收单片机采样得到的数据,然后进行绘图。但是根据delphi接收的数据发现几个问题,由于刚开始接触所以询问下阿莫论坛的各位坛友了:
问题1:定时器定时不准,timer1.Interval:=125;定时125或是250的时候记录的定时时间是比较准确的;但是改用100或其他数据时候,定时的时间出现偏差;
问题2:delphi记录的数据,一个数据重复几次,之后该出现的数据连续丢失几个,该现象一直都是这样;比如:102102102105105105105   107107107...
希望大家能帮个忙,这个元旦都在调试这个程序,实在是没有招了我,具体的delphi程序如下:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, TeEngine, Series, ExtCtrls, TeeProcs, Chart,
SPComm,DateUtils,math, ComCtrls;

type
TForm1 = class(TForm)
    Button1: TButton;
    Chart1: TChart;
    Label1: TLabel;
    Series1: TFastLineSeries;
    BitBtn1: TBitBtn;
    Edit1: TEdit;
    Label2: TLabel;
    Timer1: TTimer;
    BitBtn2: TBitBtn;
    Shape1: TShape;
    Label3: TLabel;
    Label4: TLabel;
    UpDown1: TUpDown;
    Label7: TLabel;
    Edit2: TEdit;
    Comm1: TComm;
    Label9: TLabel;
    Label10: TLabel;
    ComboBox2: TComboBox;
    Label11: TLabel;
    Edit4: TEdit;
    Label12: TLabel;
    Edit5: TEdit;
    ComboBox1: TComboBox;
    Edit3: TEdit;
    Edit6: TEdit;
    Button2: TButton;
    Label5: TLabel;
    Label6: TLabel;
    Series2: TFastLineSeries;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
      BufferLength: Word);
    procedure Timer1Timer(Sender: TObject);
    procedure BitBtn2Click(Sender: TObject);
    procedure UpDown1Changing(Sender: TObject; var AllowChange: Boolean);
    procedure Edit4Change(Sender: TObject);
    procedure ComboBox2Change(Sender: TObject);
    procedure ComboBox1Change(Sender: TObject);
    procedure Button2Click(Sender: TObject);

private
    { Private declarations }
public
    { Public declarations }
end;

var
Form1: TForm1;

implementation
var //设置全局变量
starttime:TDatetime;
   starttime1:TDatetime;
filename:string;
picturename:string;
xuhao:integer;
real_bxz:double;
//real_hw:double;
//real_dl:double;
real_time:double;
bottom_adj:integer;
Inadata:Integer;
zt:integer=0;
{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);//过程

//var
//temp:array of byte;

begin
Comm1.StartComm;
timer1.Enabled:=true;
starttime:=now();    //
edit3.Text:=datetimetostr(now);   //显示程序开始的日期和时间
//edit3.Text:=timetostr(now());// 显示程序的开始时间
Inadata:=StrToint(Edit4.Text);//接受输入的初始值
filename:=extractfiledir(Application.ExeName)+'\data'+'\'+edit1.Text+'.txt';//创建txt文件
picturename:=extractfiledir(Application.ExeName)+'\data'+'\'+edit1.Text+'_'+inttostr(xuhao)+'.bmp';
//创建照片
end;
//初始化对应的程序
procedure TForm1.FormCreate(Sender: TObject);
begin
chart1.LeftAxis.Automatic:=false;   //设置左边不自动变化长短
chart1.BottomAxis.Automatic:=false; //设置底部不自动变化长短
chart1.LeftAxis.Maximum:=400;//量程为400
chart1.LeftAxis.Minimum:=0;
//chart1.RightAxis.Automatic:=false;
//chart1.RightAxis.Maximum:=40;
//chart1.RightAxis.Minimum:=0;
//chart1.BottomAxis.Automatic:=false;
chart1.BottomAxis.Maximum:=10; //底部最大值10,也就是为10s时间
chart1.BottomAxis.Minimum:=0; //底部最小值0;
series1.Clear;//曲线1清除
series2.Clear;//曲线2清除
timer1.Enabled:=false; //定时器1不使能
timer1.Interval:=125;//定时器1每隔0.125s触发一次
xuhao:=1;
try
   // EnumcomPorts(ComboBOX1.Items);
    Comm1.stopComm;
    ComboBOX1.ItemIndex:=0;
    Form1.Comm1.CommName:=ComboBox1.Text;//默认'COM1';
    ComboBOX2.ItemIndex:=3;            //默认波特率9600
    Form1.Comm1.BaudRate:=StrToInt(ComboBox2.Text);//9600;
    Comm1.ByteSize:=_8;
    Comm1.StopBits:=_1;
    Comm1.ParityCheck:=false;
    Comm1.Parity:=none;
    sleep(1); //SLEEP是停止工作的意思 SLEEP(1000)就是停止1秒
except
    showmessage('信号处理器串口打开异常');
    exit;//退出程序
end;
real_bxz:=0;
// real_hw:=0;
real_time:=0;
bottom_adj:=0;
end;
//退出按钮
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
Comm1.stopComm;
comm1.Free;
timer1.Enabled:=false;
sleep(2);
close;
end;

procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
   i:integer;
   rece_array:arrayof byte;
   data_array:array of byte;
begin
//starttime:=now();
sleep(2);
move(buffer^,rece_array,bufferlength);
if (bufferlength=2)then //信号处理器
begin
    for i:=0 to (bufferlength-1) do
    begin
      data_array:=rece_array;
    end;
    real_bxz:=(data_array*256+data_array)/1.0;
    //series1.Addxy(real_time,real_bxz);
   // Edit2.Text:=FloatToStr(real_bxz);
   // real_bxz:=data_array/1.0;
    { real_time:=roundto(secondspan(now,starttime),-3);//四舍五入,保留三位小数

    // 画图
if real_time>100 then
begin
    chart1.BottomAxis.Maximum:=real_time+100; //满图之后,开始左移
end;
series1.Addxy(real_time,real_bxz);
   starttime1:=now();
   edit6.Text:=timetostr(starttime1);}
    //real_hw:=(data_array*256+data_array)/10.0;
end;
end;
//定时器1设置
procedure TForm1.Timer1Timer(Sender: TObject);
var
   txtfile:textfile;
begin
Timer1.Enabled:=false;
real_time:=roundto(secondspan(now,starttime),-3);//四舍五入,保留三位小数
    // 画图
if real_time>10 then// 当时间大于10s
begin
    chart1.BottomAxis.Maximum:=real_time+10; //满图之后,开始左移
    //chart1.BottomAxis.Minimum:=real_time-5;
end;

edit2.Text:=floattostr(roundto(real_bxz,-1));
series1.Addxy(real_time,real_bxz);
   starttime1:=now();
   edit6.Text:=datetimetostr(starttime1);
series2.Addxy(real_time,Inadata);
// edit3.Text:=floattostr(roundto(real_hw,-1));
// 保存为TXT
if not FileExists(filename) then
   begin
    AssignFile(TxtFile,filename);
    rewrite(TxtFile);
    //try ... finally 的作用在于:如果出错误了,不管前面的错误如果,
    //都将执行finally块的代码,这样代码可能更健壮
    try
      Writeln(TxtFile,'时间      表显值');
    finally
      closefile(txtfile);
   end;
end
else
begin
   //try ... finally 的作用在于:如果出错误了,不管前面的错误如果,
   //都将执行finally块的代码,这样代码可能更健壮
    try
      assignfile(txtfile,filename);
      Append(txtfile);//打开存在的文件并把文件指针定位在文件尾
      writeln(txtfile,format('%.3f',)+'   '+format('%.1f',));
    finally
      closefile(txtfile);
    end;
end;
   Timer1.Enabled:=true;
end;

procedure TForm1.BitBtn2Click(Sender: TObject);
begin
BitBtn2.Enabled:=false;
chart1.SaveToBitmapFile(picturename);
xuhao:=xuhao+1;
picturename:=extractfiledir(Application.ExeName)+'\data'+'\'+edit1.Text+'_'+inttostr(xuhao)+'.bmp';
BitBtn2.Enabled:=true;
end;

procedure TForm1.UpDown1Changing(Sender: TObject;
var AllowChange: Boolean);
begin
bottom_adj:=UpDown1.Position*10;
if bottom_adj<(real_time-10) then
begin
    chart1.BottomAxis.Minimum:=bottom_adj;
end;
end;

procedure TForm1.Edit4Change(Sender: TObject);
begin
//real_dl:=StrToFloat(Edit4.Text);
end;

procedure TForm1.ComboBox2Change(Sender: TObject);
var
BaudRate: Integer;
begin
if ComboBox2.Text = 'Custom' then
begin
    ComboBox2.Style := csDropDown;
    ComboBox2.SetFocus;
   // unit1.Form1.Button2.Enabled := false;
end
else
begin
    if ComboBox2.ItemIndex > 0 then
      ComboBox2.Style := csDropDownList;
      //下面是自定义波特率的
    if TryStrToInt(ComboBox2.Text, BaudRate) then
    begin
   Form1.Comm1.BaudRate := BaudRate;
   //Form1.Button2.Enabled := true;
    end
    else
    // unit1.Form1.Button2.Enabled := false;
end;
end;


procedure TForm1.ComboBox1Change(Sender: TObject);
begin
Form1.Comm1.CommName := '//./'+ComboBox1.Text;

end;
//暂停程序
procedure TForm1.Button2Click(Sender: TObject);
begin
zt:=zt+1;
if zt Mod 2=1 then
   begin
   sleep(5000);
   end;
end;
end.

wind2100 发表于 2013-1-3 21:09:16

学VC的飘过 曾经想学D语言

junrong 发表于 2013-1-3 21:14:41

wind2100 发表于 2013-1-3 21:09 static/image/common/back.gif
学VC的飘过 曾经想学D语言

呵呵,据说VC难学些,所以就学DELPHI了...不过相信很多东西都是相通的...

wind2100 发表于 2013-1-3 21:31:13

因为会C所以 学C++就容易 VC就顺水推舟了对PASCAL的概念 还不是很明白 好像和C差不多 只是关键字不一样

junrong 发表于 2013-1-3 21:36:19

wind2100 发表于 2013-1-3 21:31 static/image/common/back.gif
因为会C所以 学C++就容易 VC就顺水推舟了对PASCAL的概念 还不是很明白 好像和C差不多 只是关键字不一样...

是么...我一直都是用的C,用了3年吧...那看来下次的该学C++了...

wind2100 发表于 2013-1-4 21:17:54

应该还有人在用 找找QQ群 或是论坛 也算是非主流 了

junrong 发表于 2013-1-8 20:28:00

wind2100 发表于 2013-1-4 21:17 static/image/common/back.gif
应该还有人在用 找找QQ群 或是论坛 也算是非主流 了

嗯,主要是我刚开始学。所以对线程什么的不懂!等我在看看书的...
页: [1]
查看完整版本: delphi串口接收数据有错误