VC中的串口编程与调试

how_warm 2000-09-14 08:32:00
在VC中运行WriteFile函数写串口时就死机,或者总是返回0,为什么?
非常急,请各位高手雪中送炭!多谢!多谢!
...全文
237 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Kevin_qing 2000-09-15
  • 打赏
  • 举报
回复
给你一个现成的东西研究研究吧,会有启发的。
// Serial.h

#ifndef __SERIAL_H__
#define __SERIAL_H__

#define FC_DTRDSR    0x01
#define FC_RTSCTS    0x02
#define FC_XONXOFF   0x04
#define ASCII_BEL    0x07
#define ASCII_BS    0x08
#define ASCII_LF    0x0A
#define ASCII_CR    0x0D
#define ASCII_XON    0x11
#define ASCII_XOFF   0x13

class CSerial
{

public:
CSerial();
~CSerial();

BOOL Open( int nPort = 2, int nBaud = 9600 );
BOOL Close( void );

int ReadData( void *, int );
int SendData( const char *, int );
int ReadDataWaiting( void );

BOOL IsOpened( void ){ return( m_bOpened ); }

protected:
BOOL WriteCommByte( unsigned char );

HANDLE m_hIDComDev;
OVERLAPPED m_OverlappedRead, m_OverlappedWrite;
BOOL m_bOpened;

};

#endif


// Serial.cpp


#include "Serial.h"


CSerial::CSerial()
{

memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
m_hIDComDev = NULL;
m_bOpened = FALSE;

}

CSerial::~CSerial()
{

Close();

}

BOOL CSerial::Open( int nPort, int nBaud )
{

if( m_bOpened ) return( TRUE );

char szPort[15];
char szComParams[50];
DCB dcb;

wsprintf( szPort, "COM%d", nPort );
m_hIDComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
if( m_hIDComDev == NULL ) return( FALSE );

memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );

COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 5000;
SetCommTimeouts( m_hIDComDev, &CommTimeOuts );

wsprintf( szComParams, "COM%d:%d,n,8,1", nPort, nBaud );

m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );

dcb.DCBlength = sizeof( DCB );
GetCommState( m_hIDComDev, &dcb );
dcb.BaudRate = nBaud;
dcb.ByteSize = 8;
unsigned char ucSet;
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_DTRDSR ) != 0 );
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_RTSCTS ) != 0 );
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_XONXOFF ) != 0 );
if( !SetCommState( m_hIDComDev, &dcb ) ||
!SetupComm( m_hIDComDev, 10000, 10000 ) ||
m_OverlappedRead.hEvent == NULL ||
m_OverlappedWrite.hEvent == NULL ){
DWORD dwError = GetLastError();
if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
CloseHandle( m_hIDComDev );
return( FALSE );
}

m_bOpened = TRUE;

return( m_bOpened );

}

BOOL CSerial::Close( void )
{

if( !m_bOpened || m_hIDComDev == NULL ) return( TRUE );

if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
CloseHandle( m_hIDComDev );
m_bOpened = FALSE;
m_hIDComDev = NULL;

return( TRUE );

}

BOOL CSerial::WriteCommByte( unsigned char ucByte )
{
BOOL bWriteStat;
DWORD dwBytesWritten;

bWriteStat = WriteFile( m_hIDComDev, (LPSTR) &ucByte, 1, &dwBytesWritten, &m_OverlappedWrite );
if( !bWriteStat && ( GetLastError() == ERROR_IO_PENDING ) ){
if( WaitForSingleObject( m_OverlappedWrite.hEvent, 1000 ) ) dwBytesWritten = 0;
else{
GetOverlappedResult( m_hIDComDev, &m_OverlappedWrite, &dwBytesWritten, FALSE );
m_OverlappedWrite.Offset += dwBytesWritten;
}
}

return( TRUE );

}

int CSerial::SendData( const char *buffer, int size )
{

if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );

DWORD dwBytesWritten = 0;
int i;
for( i=0; i<size; i++ ){
WriteCommByte( buffer[i] );
dwBytesWritten++;
}

return( (int) dwBytesWritten );

}

int CSerial::ReadDataWaiting( void )
{

if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );

DWORD dwErrorFlags;
COMSTAT ComStat;

ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );

return( (int) ComStat.cbInQue );

}

int CSerial::ReadData( void *buffer, int limit )
{

if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );

BOOL bReadStatus;
DWORD dwBytesRead, dwErrorFlags;
COMSTAT ComStat;

ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
if( !ComStat.cbInQue ) return( 0 );

dwBytesRead = (DWORD) ComStat.cbInQue;
if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit;

bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
if( !bReadStatus ){
if( GetLastError() == ERROR_IO_PENDING ){
WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
return( (int) dwBytesRead );
}
return( 0 );
}

return( (int) dwBytesRead );

}
xzou 2000-09-15
  • 打赏
  • 举报
回复
串口通讯难吗?
haitian99 2000-09-15
  • 打赏
  • 举报
回复
加上一些错误处理, 或者 TRACE("提示信息")
试验一下。
chn 2000-09-15
  • 打赏
  • 举报
回复
关注!
halbert 2000-09-15
  • 打赏
  • 举报
回复
关注
amethyst 2000-09-15
  • 打赏
  • 举报
回复
如果你使用异步方式打开串口
那你writefile后返回的就是0,但数据已经发出去了
写串口就死机,可能是你串口打开的不对,要么是你的硬件上有问题,前者可能性较大
仔细看一下你的CreateFile的参数和返回值
zxi666 2000-09-15
  • 打赏
  • 举报
回复
最大的可能是您没有成功的打开这个串口,请检查CreateFile或者CFile::Open的返回值;另外,请检查是否设定了正确的波特率、数据位、停止位、校验位等参数;最后,如果您是往一个设备发串口命令,请检查该设备在相邻串口指令之间需要的间隔时间,我象您一定没有通过检查串口上的各种信号是否OK就一股脑的发命令了。
希望对您有用!
Holly 2000-09-14
  • 打赏
  • 举报
回复
你是怎么写的?贴出来看看,包括如何调用CreateFile的?

16,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧