JeffWang 5c6631cc87 新增KFP处理。 2 лет назад
..
Command.cpp bc895bd4ef 删除关于FC单独处理的函数,可合并入之前的处理:cmd处理FC时,要再带一个字节,组成双字节的ucCommand就能符合协议规则。 2 лет назад
Command.h bc895bd4ef 删除关于FC单独处理的函数,可合并入之前的处理:cmd处理FC时,要再带一个字节,组成双字节的ucCommand就能符合协议规则。 2 лет назад
CommandParam.h bc895bd4ef 删除关于FC单独处理的函数,可合并入之前的处理:cmd处理FC时,要再带一个字节,组成双字节的ucCommand就能符合协议规则。 2 лет назад
ReadMe.txt 8fc7cb139e 【软件版本】 3 лет назад
Serial.cpp b05c5036bf ReadIntervalTimeout的设置值:波特率110=9ms,波特率9600=0.1ms 波特率115200=0.008ms,所以设置1ms即可。 2 лет назад
Serial.h 89dcae8dc2 修复读超时的错误用法:ReadTotalTimeoutMultiplier一般情况下设置为0,只设置ReadTotalTimeoutConstant和ReadIntervalTimeout即可。 2 лет назад
TCLCommand.cpp 16e68767ee 1、添加头文件,外部调用; 3 лет назад
TCLCommand.h 16e68767ee 1、添加头文件,外部调用; 3 лет назад
TCLCommand.rc e72e120118 封装成库。 4 лет назад
TCLCommand.vcproj 677abf8c95 补充:生成事件添加复制command.data文件。 4 лет назад
command.data 5c6631cc87 新增KFP处理。 2 лет назад
resource.h e72e120118 封装成库。 4 лет назад
stdafx.cpp e72e120118 封装成库。 4 лет назад
stdafx.h e72e120118 封装成库。 4 лет назад
targetver.h e72e120118 封装成库。 4 лет назад
utils.cpp adffbc1438 【软件版本】 3 лет назад
utils.h bc895bd4ef 删除关于FC单独处理的函数,可合并入之前的处理:cmd处理FC时,要再带一个字节,组成双字节的ucCommand就能符合协议规则。 2 лет назад

ReadMe.txt

========================================================================
动态链接库:TCLCommand 项目概述
========================================================================

应用程序向导已为您创建了此 TCLCommand DLL。

本文件概要介绍组成 TCLCommand 应用程序的
的每个文件的内容。


TCLCommand.vcproj
这是使用应用程序向导生成的 VC++ 项目的主项目文件,
其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。

TCLCommand.cpp
这是主 DLL 源文件。

此 DLL 在创建时不导出任何符号。因此,在生成此 DLL 时
将不会产生 .lib 文件。如果希望此项目
成为其他某个项目的项目依赖项,则需要
添加代码以从 DLL 导出某些符号,
以便产生一个导出库,或者,也可以在项目“属性页”对话框中的
“链接器”文件夹中,将“常规”属性页上的
“忽略输入库”属性设置为“是”。

/////////////////////////////////////////////////////////////////////////////
应用程序向导创建了下列资源:

TCLCommand.rc
这是程序使用的所有 Microsoft Windows 资源的列表。它包括 RES 子目录中存储的图标、位图和光标。
此文件可以直接在 Microsoft Visual C++ 中进行编辑。

Resource.h
这是标准头文件,可用于定义新的资源 ID。
Microsoft Visual C++ 将读取并更新此文件。

/////////////////////////////////////////////////////////////////////////////
其他标准文件:

StdAfx.h, StdAfx.cpp
这些文件用于生成名为 TCLCommand.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。

/////////////////////////////////////////////////////////////////////////////
其他注释:

应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。


/////////////////////////////////////////////////////////////////////////////
读写超时是在 调用 ReadFile 和 WriteFile 函数读写串口的时候系统提供的超时机制

typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout; /* Maximum time between read chars. */
DWORD ReadTotalTimeoutMultiplier; /* Multiplier of characters. */
DWORD ReadTotalTimeoutConstant; /* Constant in milliseconds. */
DWORD WriteTotalTimeoutMultiplier; /* Multiplier of characters. */
DWORD WriteTotalTimeoutConstant; /* Constant in milliseconds. */
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;

读超时 有两只计算方法
1:(间隔超时)ReadIntervalTimeout 指定了在接收字符间的最大时间,如果超过了这个时间,ReadFile立即返回。
2:(总超时)基于要接收的字符数量
ReadTotalTimeoutMultiplier表示平均读一个字节的时间上限
ReadTotalTimeoutConstant表示读数据总时间常量
读数据总超时:ReadTotalTimeoutConstant +(ReadTotalTimeoutMultiplier*要读的字节数)
读数据超时,两种超时同时有效,当出现任何一种超时时,ReadFile都将返回。

写超时:
WriteTotalTimeoutMultiplier表示平均写一个字节的时间上限
WriteTotalTimeoutConstant表示写数据总超时常量

写数据总超时 :WriteTotalTimeoutConstatn +(WriteTotalTimeoutMultiplier *要写的字节数)

具体超时设置
1:有读间隔超时、读总超时、写总超时,将COMMTIMEOUTS结构5个成员设置为对应值。
2:没有读间隔超时,有读总超时和写总超时,将RealIntervalTimeou设置为0,其他参数设置为对应值。
3:不管是否有数据要读取,ReadFile立即返回,将RealIntervalTimeout设置为MAX_DWORD,
将ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant都设置为0
(不立即返回的时候,可以在超时时间内等串口中有新的数据?然后读取,直到超时时间)
4:ReadFile没有超时设置,直到有适当的字符数返回或者错误发生,函数才返回。
将 ReadIntervalTimeout、ReadTotalTimeoutMultiplier、ReadTotalTimeoutConstant都设置为0
5:WriteFile没有超时设置:将WriteTotalTimeoutMultiplier和WriteTotalTimeoutConstant设置为0

/////////////////////////////////////////////////////////////////////////////
COMMTIMEOUTS 结构体被用在SetCommTimeouts和GetCommTimeouts 函数中,以便设置和查询通讯设备的超时参数。这个参数决定ReadFile, WriteFile, ReadFileEx, 和WriteFileEx 操作设备的行为。

typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout;
DWORD ReadTotalTimeoutMultiplier;
DWORD ReadTotalTimeoutConstant;
DWORD WriteTotalTimeoutMultiplier;
DWORD WriteTotalTimeoutConstant;} COMMTIMEOUTS, *LPCOMMTIMEOUTS;
成员
ReadIntervalTimeout
在通讯过程中接收两个字符之间的最长超时时间,按毫秒计算。在ReadFile操作,当接收到第一个字符时,开始一个计时周期。如果接收任意两个字符之间的时隔超过本限制,ReadFile操作将完成并返回任何已缓冲的数据。0代表本参数未设置。
如果设置为MAXDWORD, 并且ReadTotalTimeoutConstant和ReadTotalTimeoutMultiplier成员为0,代表读取操作立即返回那些已接收的数据,即使没有收到任何字符。(两个字符之间的接收间隔)

ReadTotalTimeoutMultiplier
乘数用于计算读取操作的总超时时间,按毫秒计算。对于每个读取操作,这个值将乘以要读取的字节数。(读取单个字符的最大超时)
ReadTotalTimeoutConstant
一个用于计算对于读取操作的总超时周期的常数,按毫秒计算。对每次读取操作,实际总超时时间为ReadTotalTimeoutMultiplier 成员与请求的字节数年的乘积加此值。
ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant成员为0代表总读取总超时时间无效(读取所有字节的时间为ReadTotalTimeoutMultiplier*BytesToRead+ReadTotalTimeoutConstant)。

WriteTotalTimeoutMultiplier
乘数用来计算写操作的总超时周期,按毫秒计算。对每个写操作,这个值将乘以要写入的字节数。(写单个字符的最大超时)
WriteTotalTimeoutConstant
一个用于计算写入操作的总超时周期的常数,按毫秒计算。对于每一次写入操作,实际总超时时间为WriteTotalTimeoutMultiplier 成员与要写入字节的乘积再加此值.
WriteTotalTimeoutMultiplier和WriteTotalTimeoutConstant成员为0代表总写入时间无效(写入所有字节的时间为WriteTotalTimeoutMultiplier*BytesToWrite+WriteTotalTimeoutConstant)。

备注
如果一个应用程序设置ReadIntervalTimeout和ReadTotalTimeoutMultiplier为 MAXDWORD并且设置ReadTotalTimeoutConstant 为一个大于零且小于MAXDWORD的值, 在调用ReadFile时将会发生如下现象:

如果在输入缓冲区中有任何字符,ReadFile 立即返回缓冲区中的内容。
如果在缓冲区中没有任何字符,ReadFile 将等待接收到一个字符并立即返回.
如果在ReadTotalTimeoutConstant指定的时间值内无任何字节返回,ReadFile超时.


/////////////////////////////////////////////////////////////////////////////
串口读取事件分为两个阶段(我以Win32 API函数ReadFile读取串口过程来说明一下)
第一个阶段是:串口执行到ReadFile()函数时,串口还没有开始传输数据,所以串口缓冲区的第一个字节是没有装数据的,这时候总超时起作用,如果在总超时时间内没有进行串口数据的传输,ReadFile()函数就返回,当然 没有读取到任何数据。而且,间隔超时并没有起作用。
第二阶段:假设总超时为20秒,程序运行到ReadFile(),总超时开始从0 计时,如果在计时到达10秒时,串口开始了数据的传输,那么从接收的第一个字节开始,间隔超时就开始计时,假如间隔超时为1ms,那么在读取完第一个字节后,串口开始等待1ms,如果1ms之内接收到了第二个字节,就读取第二个字节,间隔超时重置为0并计时,等待第三个字节的到来,如果第三个字节到来的时间超过了1ms,那么ReadFile()函数立即返回,这时候总超时计时是没到20秒的。如果在20秒总计时时间结束之前,所有的数据都遵守数据间隔为1ms的约定并陆陆续续的到达串口缓冲区,那么就成功进行了一次串口传输和读取;如果20秒总计时时间到,串口还陆陆续续的有数据到达,即使遵守字节间隔为1ms的约定,ReadFile()函数也会立即返回,这时候总超时就起作用了。
总结起来,总超时在两种情况下起作用
第一:串口没进行数据传输,等待总超时时间那么长ReadFile()才返回。非正常数据传输
第二:数据太长,总超时设置太短,数据还没读取完就返回了。读取的数据是不全的
间隔超时触发是有条件的
第一:在总超时时间内。
第二:串口进行了数据的传输。
成功的进行一次串口数据的传输和读取,只有总超时和间隔超时相互参与配合才能完成

/////////////////////////////////////////////////////////////////////////////
Command.data文件格式说明,键值对形式存在[key=value]:
Key说明:
name 表示命令名称;
option 表示命令类型
1、Get 表示指令用于查询,不用传入外部数据,需要返回查询结果。
2、Set 表示指令用于设置,需要传入外部数据,需要返回设置结果。
3、None 表示指令不是查询指令,不用传入外部数据,无查询结果返回;也不是设置指令,不用传入外部数据,无设置结果返回。

更确切的说,Get不用传数据,Set要传入数据;
Get和Set都要返回除“AB 05 0A DF 4E”外的第二段串口数据(失败除外),而None只返回一段“AB 05 0A DF 4E”的数据。

head 表示命令的协议头,以十六进制字符表示,多个字节以空格隔开;
cmd 表示命令的具体指令,以十六进制字符表示,只有有且一个字节;
param 表示命令的具体指令所附加参数,以十六进制字符表示,多个字节以空格隔开;
returnParam 与param关联使用,表示指令返回结果时,是否会将param一起返回。
readWaitTime 表示指令在串口Write之后,多久才开始串口Read指令结果
cmdWaitTime 表示当前指令完成串口Read后,等待多久进行下一条指令操作。
/////////////////////////////////////////////////////////////////////////////