串口通讯时,所发字节为何有断节现象?(100分)

  • 主题发起人 主题发起人 ausable
  • 开始时间 开始时间
A

ausable

Unregistered / Unconfirmed
GUEST, unregistred user!
我在做电脑与单片机通讯的软件时,不知道为什么,到了串口发出去的字节组会象打字机一样慢,求救:
for i:=0 to sflen-1 do
begin
writefile(ahcomm,outBuffer,1,len,nil);
end;
receivestart;//收
 
这样发送不是更好吗?
size:=strlen(OutBuffer);
TelCom.WriteCommData(OutBuffer,Size);
 
建议采用MSCOMM控件,那样省心多啦.也好用.
 
to:linqulsk
MSCOMM控件制作的软件已 经过多次测试OK;
但本软件还要通过MODEM单片机通讯,用MSCOMM无法检测出MODEM是否断线等,还要手动设置串口,逼于无奈才选用该死的API,结果就出来这样的问题。
to:qcchan
试过后如果OK,即时给分。

总之谢了。
 
to:qcchan
telcom??是什么东东?怎么样才能调出来?
 
to:qcchan
才明白,感情你用的是SPCOMM吧?
 
MSCOMM控件制作的软件已 经过多次测试OK;
但本软件还要通过MODEM单片机通讯,用MSCOMM无法检测出MODEM是否断线等,还要手动设置串口,逼于无奈才选用该死的API,结果就出来这样的问题。
to:qcchan
试过后如果OK,即时给分。

总之谢了。

用MSCOMM可以完全控制MODEM的状态,你这样程序我早五六年前就做了,如果需要请要,请直接加我QQ12269150来讨论,这样的问题容易解决
 
还是希望可以用API来控制MODEM,目前用MSCOMM还没有解决。
help me ....
 
to
ausable
你的问题对我来说是小意思,如果想知道请加我的qq12269150
 
建议直接写入串口,这样提高速度,无论是用控件还是API都要直接写到串口中,同时检查下位机的接收机制是否为中断方式
 
to:hqkjack
关键是不知道如何直接写入端口呀.请赐教.
 
to:all
原来用MSCOMM通过MODEM发出去,远端MODEM发到的还是出现断节现象,有何解决办法,
各位大虾,救我呀。
我的发送方式为:(拨通后)MSComm.Output:=FBuffer;
接收用MSCOMM的oncomm触发。
 
是啊,直接写串口,多好,用控件不如直接写。我这里有个cbuilder的com类,你可以看着改,

#include <Classes.hpp>

//---------------------------------------------------------------------------
class TCom32
{
//__published: // IDE-managed Components

private: // User declarations
public: // User declarations
HANDLE m_ComHandle; //串口句柄
AnsiString sComName; //串口名称
int iBaudRate; //通讯频率
int iByteSize; //通讯字节
int iParityNum; //校验
int iStopBitsNum; //停止位

__fastcall TCom32();
//初始化串口的方法
void __fastcall initCom(AnsiString comName,int BaudRate,int byteSize,
int iParity,int iStopBits);
void __fastcall closeCom(); //关闭串口
//写数据
void __fastcall writeCom(byte* writeMsg,int len);
void __fastcall writeCom(char* writeMsg,int len);
//修改校验方式
void __fastcall changeParity(int iParity);
};
//---------------------------------------------------------------------------
#endif
#include &quot;Comm32.h&quot;
__fastcall TCom32::TCom32()
{
m_ComHandle=NULL; //串口句柄
sComName=&quot;COM1&quot;; //串口名称
iBaudRate=9600; //通讯频率
iByteSize=8; //通讯字节
iParityNum=4; //校验
iStopBitsNum=0; //停止位
}

void __fastcall TCom32::initCom(AnsiString comName,int BaudRate,
int byteSize,int iParity,int iStopBits)
{
sComName=comName; //串口名称
iBaudRate=BaudRate; //通讯频率
iByteSize=byteSize; //通讯字节
iParityNum=iParity; //校验
iStopBitsNum=iStopBits; //停止位
COMMTIMEOUTS m_CommTimeouts;
DCB m_Dcb;
unsigned char Parity[]={NOPARITY,ODDPARITY,EVENPARITY,MARKPARITY,SPACEPARITY};
unsigned char StopBits[]={ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS};

if(m_ComHandle != NULL){
CloseHandle(m_ComHandle);
}

//打开串口
m_ComHandle = CreateFile(sComName.c_str(),
GENERIC_WRITE|GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);

if(m_ComHandle == INVALID_HANDLE_VALUE){ //串口句柄无效
return;
}
//清空串口缓冲区,退出所有相关操作
PurgeComm(m_ComHandle,PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);

//超时设置
m_CommTimeouts.ReadIntervalTimeout = MAXDWORD;
m_CommTimeouts.ReadTotalTimeoutMultiplier = 0;
m_CommTimeouts.ReadTotalTimeoutConstant = 0;
m_CommTimeouts.WriteTotalTimeoutMultiplier = 10;
m_CommTimeouts.WriteTotalTimeoutConstant = 1000;

SetCommTimeouts(m_ComHandle,&m_CommTimeouts); //设置超时参数
SetupComm(m_ComHandle,4096,4096); //设置缓冲区大小

//DCB配置
GetCommState(m_ComHandle,&m_Dcb); //获得COMM DCB信息
m_Dcb.BaudRate = iBaudRate;
m_Dcb.ByteSize = iByteSize;
m_Dcb.Parity = Parity[iParityNum];
m_Dcb.StopBits = StopBits[iStopBitsNum];

//硬件流控制
m_Dcb.fDtrControl = DTR_CONTROL_ENABLE; //启用DTR线
m_Dcb.fRtsControl = RTS_CONTROL_ENABLE; //启用RTS线
m_Dcb.fOutxCtsFlow = false; //串行端口的输出由CTS线控制
m_Dcb.fOutxDsrFlow = false; //开启串行端口的DSR流控制

//软件流控制
m_Dcb.fInX = false; //设为TRUE指定XON/XOFF控制被用于控制串行输入
m_Dcb.fOutX = false; //设为TRUE指定XON/XOFF控制被用于控制串行输出
m_Dcb.fNull = false; //设为TRUE将使串行驱动程序忽略收到的空字节
m_Dcb.XonChar = (char)0xFF;
m_Dcb.XoffChar = (char)0XFF;
m_Dcb.XonLim = 100;
m_Dcb.XoffLim = 100;
m_Dcb.EvtChar = 0x0d;
m_Dcb.fBinary = true ;
m_Dcb.fParity = true ;

SetCommState(m_ComHandle,&m_Dcb); //设置DCB信息
SetCommMask(m_ComHandle,EV_TXEMPTY|EV_RXCHAR); //设置事件掩码

//设置端口上指定信号的状态
EscapeCommFunction(m_ComHandle,SETDTR);
// SETDTR: 发送DTR (data-terminal-ready)信号
EscapeCommFunction(m_ComHandle,SETRTS);
// SETRTS: 发送RTS (request-to-send)信号
Sleep(200);
}

//关闭串口
void __fastcall TCom32::closeCom()
{
if(m_ComHandle != NULL){
CloseHandle(m_ComHandle);
}
}

//写数据
void __fastcall TCom32::writeCom(byte* writeMsg,int len)
{
if(m_ComHandle == INVALID_HANDLE_VALUE){ //串口句柄无效
return;
}
OVERLAPPED m_WriteOP;
DWORD m_Written = 0,ErrorCode;

//初始化化异步读写结构
memset(&m_WriteOP, 0, sizeof(m_WriteOP));

//参数设置
m_WriteOP.Offset = 0;
m_WriteOP.InternalHigh = 0;
m_WriteOP.hEvent = CreateEvent(NULL,true,false,NULL);
WriteFile(m_ComHandle,
writeMsg,
len,
&m_Written,
&m_WriteOP);
Sleep(len); //把这个去掉或者减少看看
}

void __fastcall TCom32::writeCom(char* writeMsg,int len)
{
if(m_ComHandle == INVALID_HANDLE_VALUE){ //串口句柄无效
return;
}
OVERLAPPED m_WriteOP;
DWORD m_Written = 0,ErrorCode;

//初始化化异步读写结构
memset(&m_WriteOP, 0, sizeof(m_WriteOP));

//参数设置
m_WriteOP.Offset = 0;
m_WriteOP.InternalHigh = 0;
m_WriteOP.hEvent = CreateEvent(NULL,true,false,NULL);
WriteFile(m_ComHandle,
writeMsg,
len,
&m_Written,
&m_WriteOP);
Sleep(len);
}


//修改校验方式
void __fastcall TCom32::changeParity(int iParity)
{
if(m_ComHandle == INVALID_HANDLE_VALUE){ //串口句柄无效
return;
}
initCom(sComName,iBaudRate,iByteSize,iParity,iStopBitsNum);
}


×××××××××××
使用,,,,,
//初始化串口
byte bSend[10] = {0x00};
TCom32 *com = new TCom32();
com->initCom(Parameters[0],9600,8,3,0);
com->changeParity(3); // 改变校验设置
com->writeCom(bSend,10);
 
别要流控制,可以试试,如果要流控制的话,当发送00字符时,误认为你发送的字符串到结尾,所以出现字节断节现象
 
to:章译文
非常感谢,用你提供的程序之后,发送时确实没有了断码现象,只是不知怎么,收信息时只能收到一部份,(注:单片机返回18个字节,只能收到中间的8个,前后的东东根本就没有出来,WHY??,返回来的东东我用串口监视过确实是18个字节)
 
呵呵呵,非常感谢大家,尤其是章译文,原来用异步方式就可以搞掂。
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
后退
顶部