高分求援,关于串口通讯。难度偏大。(300分)

  • 主题发起人 主题发起人 11111
  • 开始时间 开始时间
1

11111

Unregistered / Unconfirmed
GUEST, unregistred user!
之前从来没有接触过串口通讯,上周接到一个项目偏偏是串口的。
我在论坛里找了很多资料,装了SPCOMM,可还是实现不了读取串口设备。

1、串口设备为一个“数据采集器F-20”,里面存储了几十条内码,通过串口与
PC连接将内码读取到数据库中。现在要做的就写一个数据库程序将这些数据读取
、处理、生成报表。问题就是读取这一块。自己做了一周了,时间将尽,向大家求援。

2、下面是仅有的技术资料,串口通讯协议。
=============================================================================
手机的详细通讯数据如下:
F16A/F16B F18/F18M F20/F20M
通讯协议 9600, N, 8, 1 9600, N, 8, 1 115200, N, 8, 1
Command 10进制 10进制 10进制
年 0~99:1996~2095 0~99:1996~2095 0~99:1996~2095
月 1~12 1~12 1~12
日 1~31 1~31 1~31
时 0~23 0~23 0~23
分 0~59 0~59 0~59
秒 0~59 0~59 0~59
卡片内码 16进制 16进制 16进制

F18(M)使用128KBytes 的内存,
F20(M) 使用256KBytes 的内存,前128K为F18所用,后128K为F20所用。
全部区分为1024 Bank,每一Bank为256 Bytes ,F20的数据存放在最后512~1023 Bank。


每一笔传输数据:Bank(2 bytes) + Data(256 bytes)+ Checksum (1 byte),共259 bytes。

Data所代表格式如下:
年 + 月 + 日 + 时 + 分 + 秒 + 表号 + “#” + 表值 + &HEF(0xEF) + … …

每一笔抄表记录数据为:
年 + 月 + 日 + 时 + 分 + 秒 + 表号 + “#” + 表值 + &HEF(0xEF),
表号最长8Byte,表值最长16Byte。

因为表号及表值无一定长度限制,所以读取F20的抄表记录时要特别注意以下事项:
1、PC要将所有资料都取回重整合并后再根据以上规则(每一笔抄表记录数据)处理。
2、表号最长8Bytes,表值最长16Bytes,超出部分需舍去。
3、年、月、日、时、分、秒为BCD,各为1Byte(参考上表)。
4、抄表记录、区隔数据为文字符串,最长为32Bytes(含年、月、日、时、分、秒)。
================================================================================
3、现在我用的是DELPHI6.0+SPCOMM来读取。那位朋友做过这方面的开发,请提出宝贵建议或代码。
不胜感激。
 
这种仪器是主动发送数据还是被动发送数据?
 
好象是被动发送数据,因为我做了一周的测试。都一点反应都没有。
就是用代码来控制的,厂商并没有提供DLL。
 
如果是开发手机短信.
例如发一条短信
首先,用spcomm的write方法向串口写入AT回车,
手机就会返回OK字符串.
然后再输入命令AT+CMGS=138...................
就可以发送短信了

你必须先了解你的终端是否提供这样的指令集来操作
 
你首先要搞清楚,仪器在什么情况下发送数据:
1.你发送一条指令,它返回一条数据-------(被动式)
2.当这个仪器检测到数据时自动发送给PC。(主动式)
 
是被动式的。是PC发送指令给终端,然后终端返回数据。但厂商没有任何DLL或指令集。
看到过一段代码是用BC++写的。完全是代码的。在下一页我贴上来。
 
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit5.h"
#include "Unit8.h"
#include "Unit3.h"
#include "Unit4.h"
#include "Unit6.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "ComPort"
#pragma link "ComPort"
#pragma link "ComPort"
#pragma link "ComPort"
#pragma resource "*.dfm"
TForm5 *Form5;
String read_str,clear,clear_str[100];
String str1,str_num[120000],str_date,str_time,str_data[15],str_year,str_month,str_daty,str_hour,str_min,str_second,str_event,str_id;

int record=0,record1=0,i=0,loop=0,jj=0;
bool flag_wake=false,flag_read=false,flag_clear=false,loop1=true,loop2=true;
//---------------------------------------------------------------------------
__fastcall TForm5::TForm5(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm5::ComPort1RxChar(TObject *Sender)
{
ComPort1->BaudRate=br115200;
str1=ComPort1->ReadByte();
loop++;
str_num[record]=str1;

}
//---------------------------------------------------------------------------
void __fastcall TForm5::Button1Click(TObject *Sender)
{
ShowMessage("请先激活手机(按手机按键)!");
ComPort2->Active =false;
ComPort1->Active =true;
record=0;
ComPort1->BaudRate=br115200;
ComPort1->WriteByte(64);
}
//---------------------------------------------------------------------------



void __fastcall TForm5::FormClose(TObject *Sender, TCloseAction &amp;Action)
{
ComPort1->Active=false;
record=0;
}
//---------------------------------------------------------------------------

void __fastcall TForm5::ComPort1AfterRead(TObject *Sender, Pointer Buffer,
int Length, bool WaitOnCompletion)
{
if(str_num[0]=="25" || str_num[1]=="25" || str_num[1]=="123" || str_num[1]=="255" || str_num[0]=="123" || str_num[0]=="255" )
{
record=0;
ShowMessage("没有记录或通信出错!");
}
else if(record<1)
{

ComPort1->WriteByte(66);

}
else if(record>=1 &amp;&amp; (str1!=35 || loop%15!=2))
{

ComPort1->WriteByte(67);

}
else
{
ShowMessage("读取完毕,请将记录及时存入数据总库,以防丢失!");
Table1->Active=true;
Table1->First();
for(int l=2;l<record-1;l++)
{
if((record-1-l)>=14)
{
for(int m=0;m<15;m++)
{
str_data[m]=str_num[l];
l++;
}
}
else break;

str_year=IntToStr(StrToInt(str_data[0])+1996)+"/";
if(StrToInt(str_data[1])<10) str_month="0"+str_data[1]+"/";
else str_month=str_data[1]+"/";
if(StrToInt(str_data[2])<10) str_daty="0"+str_data[2];
else str_daty=str_data[2];
if(StrToInt(str_data[3])<10) str_hour="0"+str_data[3]+":";
else str_hour=str_data[3]+":";
if(StrToInt(str_data[4])<10) str_min="0"+str_data[4]+":";
else str_min=str_data[4]+":";
if(StrToInt(str_data[5])<10) str_second="0"+str_data[5];
else str_second=str_data[5];
if(StrToInt(str_data[6])<10) str_event="0"+str_data[6];
else str_event=str_data[6];
str_id=str_data[7]+str_data[8]+str_data[9]+str_data[10]+str_data[11]+str_data[12]+str_data[13]+str_data[14];
str_date=str_year+str_month+str_daty;
str_time=str_hour+str_min+str_second;

// try{
Table1->Append();
Table1->FieldByName("巡逻日期")->AsString=str_date;
Table1->FieldByName("巡逻时间")->AsString=str_time;
Table1->FieldByName("事件代码")->AsString=str_event;
Table1->FieldByName("卡片编号")->AsString=str_id;
l--;

// } catch (...) {ShowMessage("读取数据有错,请重试!");record=0; return;}

}
Table1->Post();

}


record++;
 
各位关注!!!。关于终端的网址如下:
http://www.smtco.com.tw/gb/pro_2.htm
用朋友做过吗?
 
我看了此终端在网上的通信协议,应该是一个很容易的通信的东西.
你设置好com口的参数:波特率为115200,数据位为8,停止位为1,同位位为NONE。然后
open串口,然后设置RTS,DTR为true,然后发送64到终端,应该就能接收到32(表示有资料)
或25(表示无资料)了。
 
TO LIUYING771129
都设置好了。然后在一个按钮输如下代码
comm1.WriteCommData('64',1);

Comm1ReceiveData事件中输入如下代码
var
s: string;
begin
SetLength(S, BufferLength);
Move(Buffer^, PChar(S)^, BufferLength);
Memo1.Lines.Add(S);
Memo1.Invalidate;
end;

不行,没反应?
可能我的代码有问题,你会如何写?请指教。这个终端设备是被动式的吧。
 
对,这个终端是被动式的
你给我个email地址,我写一个测试软件给你传过去吧
 
to LIUYING771129
真的感谢你。
sunplay@263.net
job2002@sohu.com
两个都可以。要不要请你吃饭啊:)
 
拜托,写一下读取一条资料的代码。有了这些后,其它的事就好办了。谢谢。
 
查了一个文档。发送66为读取资料。
 
请高手继续观注。谢谢。
 
是手机短信群发工具吗??????
如果是,害人的东西!
坚决不给这种人提供技术支持!!!!!!!!!
 
[red]"来自:刘李子, 时间:2003-4-18 13:13:00, ID:1780586
是手机短信群发工具吗??????
如果是,害人的东西!
坚决不给这种人提供技术支持!!!!!!!!!""[/red]


[:)]您老看看清楚,不要给我扣大帽子,是做一种“巡逻式数据采集器”,在上边都有
厂商产品介绍。因为是台湾的厂子,所以他们都叫“手机".话说回来,手机群发软件技术含量
高,我也做不出来啊。

 
http://www.torry.net/vcl/comms/modems/async32.zip

换个控件组用用吧。我能帮你的只有这个了。
 
谢谢楼上的朋友。
 
后退
顶部