SerialPort ClosePort()

南有乔木cc 2020-12-08 10:44:48
在LONG CSerialPortTestDlg::OnCommunication(WPARAM ch, LPARAM port) 函数中接受结束后立即关闭串口m_Com.ClosPort();
没有彻底关闭。 第二次再打开改串口就卡死了。 各位大佬求解!
...全文
264 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
zgl7903 2020-12-08
  • 打赏
  • 举报
回复
引用 楼主 南有乔木cc 的回复:
在LONG CSerialPortTestDlg::OnCommunication(WPARAM ch, LPARAM port) 函数中接受结束后立即关闭串口m_Com.ClosPort(); 没有彻底关闭。 第二次再打开改串口就卡死了。 各位大佬求解!
意思是在 OnCommunication 中关闭端口? 这一般是回调函数,在里面关闭端口,因为回调还没完成而不能完成某些关闭释放操作, 建议投递一个关闭消息或启动一个定时器,用于关闭端口操作
schlafenhamster 2020-12-08
  • 打赏
  • 举报
回复
// close Comm PurgeComm(m_idComDev,PURGE_TXABORT | PURGE_RXABORT| PURGE_TXCLEAR | PURGE_RXCLEAR); // CloseHandle(m_idComDev);
呈上头文件部分信息 注释的也很详细的 COPYRIGHT NOTICE Copyright c 2009 华中科技大学tickTick Group (版权声明) All rights reserved @file SerialPort h @brief 串口通信类头文件 本文件完成串口通信类的声明 @version 1 0 @author 卢俊 @E mail:lujun hust@gmail com @date 2010 03 19 修订说明: #ifndef SERIALPORT H #define SERIALPORT H #include <Windows h> 串口通信类 本类实现了对串口的基本操作 例如监听发到指定串口的数据 发送指定数据到串口 class CSerialPort { public: CSerialPort void ; CSerialPort void ; public: 初始化串口函数 @param: UINT portNo 串口编号 默认值为1 即COM1 注意 尽量不要大于9 @param: UINT baud 波特率 默认为9600 @param: char parity 是否进行奇偶校验 "Y"表示需要奇偶校验 "N"表示不需要奇偶校验 @param: UINT databits 数据位的个数 默认值为8个数据位 @param: UINT stopsbits 停止位使用格式 默认值为1 @param: DWORD dwCommEvents 默认为EV RXCHAR 即只要收发任意一个字符 则产生一个事件 @return: bool 初始化是否成功 @note: 在使用其他本类提供的函数前 请先调用本函数进行串口的初始化       n本函数提供了一些常用的串口参数设置 若需要自行设置详细的DCB参数 可使用重载函数 n本串口类析构时会自动关闭串口 无需额外执行关闭串口 @see: bool InitPort UINT portNo 1 UINT baud CBR 9600 char parity "N" UINT databits 8 UINT stopsbits 1 DWORD dwCommEvents EV RXCHAR ; 串口初始化函数 本函数提供直接根据DCB参数设置串口参数 @param: UINT portNo @param: const LPDCB & plDCB @return: bool 初始化是否成功 @note: 本函数提供用户自定义地串口初始化参数 @see: bool InitPort UINT portNo const LPDCB& plDCB ; 开启监听线程 本监听线程完成对串口数据的监听 并将接收到的数据打印到屏幕输出 @return: bool 操作是否成功 @note: 当线程已经处于开启状态时 返回flase @see: bool OpenListenThread ; 关闭监听线程 @return: bool 操作是否成功 @note: 调用本函数后 监听串口的线程将会被关闭 @see: bool CloseListenTread ; 向串口写数据 将缓冲区中的数据写入到串口 @param: unsigned char pData 指向需要写入串口的数据缓冲区 @param: unsigned int length 需要写入的数据长度 @return: bool 操作是否成功 @note: length不要大于pData所指向缓冲区的大小 @see: bool WriteData unsigned char pData unsigned int length ; 获取串口缓冲区中的字节数 @return: UINT 操作是否成功 @note: 当串口缓冲区中无数据时 返回0 @see: UINT GetBytesInCOM ; 读取串口接收缓冲区中一个字节的数据 @param: char & cRecved 存放读取数据的字符变量 @return: bool 读取是否成功 @note: @see: bool ReadChar char &cRecved ; private: 打开串口 @param: UINT portNo 串口设备号 @return: bool 打开是否成功 @note: @see: bool openPort UINT portNo ; 关闭串口 @return: void 操作是否成功 @note: @see: void ClosePort ; 串口监听线程 监听来自串口的数据和信息 @param: void pParam 线程参数 @return: UINT WINAPI 线程返回值 @note: @see: static UINT WINAPI ListenThread void pParam ; private: 串口句柄 HANDLE m hComm; 线程退出标志变量 static bool s bExit; 线程句柄 volatile HANDLE m hListenThread; 同步互斥 临界区保护 CRITICAL SECTION m csCommunicationSync; < 互斥操作串口 }; #endif SERIALPORT H ">呈上头文件部分信息 注释的也很详细的 COPYRIGHT NOTICE Copyright c 2009 华中科技大学tickTick Group (版权声明) All rights reserved @file SerialPort h @brief [更多]
/*=============================================================================================================================================================================================================*/ /*======================================================================================================== 如何使用? 1.引入DLL文件,引入头本文件,就已声明了导入函数 //要引入DLL的方法 //1、把SERIALPORTDLL1.dll和SERIALPORTDLL1.lib拷贝到工程目录下 //2、然后在 工程->设置->连接->分类->常规->对象/库模块输入:SERIALPORTDLL1.lib 2.调用Init初始化串口 3.调用SetReceiveFuntion(&ReveveChar);指定接收和处理数据的函数 4.实现void ReveveChar(WPARAM data, LPARAM port)这个函数 5.调用SendData发送数据 6.ClosePort(); ========================================================================================================*/ /*======================================================================================================= 函 数 名: Init 功 能: 打开并初始化串口 参数说明: UINT port //端口号 UINT baud //波特率 char parity = 'N' //校验位,默认为无校验位 UINT databits = 8 //数据位,一个字节的位数,默认为8位 UINT stopbit = 1 //停止位,默认为1位 使用例子: Init(2,9600); //打开串口2,波特率9600,其它值为默认值(无奇偶校验、数据位为8、停止位为1) Init(4,4800,'N',10);//打开串口4,波特率为4800,无奇偶校验,数据位为10,(停止位默认为1) ... ... ======================================================================================================*/ extern "C" __declspec(dllimport) void Init( UINT port, //端口号 UINT baud, //波特率 char parity = 'N', //校验位 UINT databits=8 , //数据位 UINT stopbit=1 //停止位 ); /*========================================================================================================== 函 数 名: SendData 功 能: 向串口发送数据,使用之前必须先调用Init函数初始化串口 参数说明: char data[] //要发送的数据 int datalen //发送数据的长度 使用例子: 例1: char a[] = {0x01,0x03,0x00,0x03,0x00,0x02,0x34,0x0B};//准备要发送的十六进制:01 03 00 03 00 02 34 0B SendData(a,8); //向串口发送十六进制数:01 03 00 03 00 02 34 0B 例2: char a[] = "$01001000020110*" //准备要发送的字符串$01001000020110* SendData(a,16); //向串口发送:$01001000020110* ============================================================================================================*/ extern "C" __declspec(dllimport) void SendData( char data[], int datalen ); /*=================================================================================================================== 函 数 名: SetReceiveFuntion 功 能: 指定接收数据的函数,指定好后,串口接收缓冲区每有一个字节的数据时会自动触发和调用所指定的函数 参数说明: a、参数需要一个函数指针, b、该指针指向一个用于接收数据的函数(该函数由用户自己声明、定义和实现), c、用户定义该函数时必须要满足一下条件: 1、该函数为全局函数 2、返回值为void 3、形参为两个,类型为:形参为UINT,LONG 使用例子: 1、void ReveveChar(WPARAM data, LPARAM port);//声明一个用于接收数据的全局函数,本头文件已默认声明这个函数,用户无需再次声明 2、 CString strTemp; void ReveveChar(WPARAM data, LPARAM port)//实现这个接收数据并处理数据的函数 { static int RecevCount = 0; //用于接收字节数的计数 char str[512] = ""; sprintf(str,"%02x",data); //接收十六进制数,并格式化为字符形式 strTemp += str; RecevCount++; if (RecevCount >= 8) //接收到数据长度等于了协议长度,则开始进行协议的处理 { RecevCount = 0; strTemp = "接收到得数据协议为" + strTemp; AfxMessageBox(strTemp); strTemp = ""; } } 3、SetReceiveFuntion(&ReveveChar);//指定void ReveveChar(WPARAM data, LPARAM port);该函数接收和处理数据 =========================================================================================================================*/ extern "C" __declspec(dllimport) void SetReceiveFuntion(void (*pfCallBack)(WPARAM data, LPARAM port)); /*================================================= 函 数 名: ClosePort 功 能: 关闭由Init函数打开的串口 参数说明: 无需参数 调用例子: ClosePort(); =================================================*/ extern "C" __declspec(dllimport) void ClosePort(); /*=============================================================================================================== 函 数 名: ReveveChar 功 能: 每当串口接收到一个字符(字节)时就会自动触发和调用这个函数, 用户只需实现不必也不能去亲自调用, 注意:打开串口后,必须要调用SetReceiveFuntion(ReveveChar) 参数说明: data //接收到的是串口中的一个字节数据 port //端口号,表明是哪个端口接收到的数据 调用例子: 只要实现,无需自己调用。 实现处理数据可参考如下简单的例子,思想是边接收数据边处理 void ReveveChar(WPARAM data, LPARAM port) { static int RecevCount = 0; //用于接收字节数的计数 char str[512] = ""; sprintf(str,"%02x",data); //接收十六进制数,并格式化为字符形式 strTemp += str; RecevCount++; if (RecevCount >= 8) //接收到数据长度等于了协议长度,则开始进行协议的处理 { RecevCount = 0; strTemp = "接收到得数据协议为" + strTemp; AfxMessageBox(strTemp); strTemp = ""; } } 说明:本函数并非为导出函数,写在这里仅仅是起到声明一个函数的作用,用户也可以删除掉,自己声明和实现! ===============================================================================================================*/ void ReveveChar(WPARAM data, LPARAM port);

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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