社区
嵌入开发(WinCE)
帖子详情
串口通讯死机现象
wqm_44944
2007-10-10 12:05:19
我的系统出现死机现象:打开应用程序(EVC开发)通过串口与控制器通讯。刚开始没有问题。应用程序发出命令后,控制器收到后解析并响应请求。通讯一段时间后系统出现死机现象。但是,当我把控制器断电重启一下,这时候系统又好了。通讯一段时间又死机了。这是怎么回事??谁遇到过这种情况!救救我!(我确定控制器没问题,我用.net 开发的应用与其通讯一直没问题) 我的板子是2410开发板。硬件应该没问题。平台为wince 4.2
...全文
1567
26
打赏
收藏
串口通讯死机现象
我的系统出现死机现象:打开应用程序(EVC开发)通过串口与控制器通讯。刚开始没有问题。应用程序发出命令后,控制器收到后解析并响应请求。通讯一段时间后系统出现死机现象。但是,当我把控制器断电重启一下,这时候系统又好了。通讯一段时间又死机了。这是怎么回事??谁遇到过这种情况!救救我!(我确定控制器没问题,我用.net 开发的应用与其通讯一直没问题) 我的板子是2410开发板。硬件应该没问题。平台为wince 4.2
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
26 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
jiuzhoulh
2011-10-30
打赏
举报
回复
串口是全双工通信的
huanghaihe
2008-08-01
打赏
举报
回复
请教高手,我采用电脑测试DVB-S串口,老是烧坏主板,请问是什么原因并怎么处理才能防止主板烧坏?谢谢!
wqm_44944
2007-10-22
打赏
举报
回复
都能成功!现在问题解决了,应该是因为控制器与我的开发串口配置参数不一致造成了死机!同时我把发送线程去掉了。现在通讯都没问题了。请问应该程序当中最多可以打开几个定时器?
lenux
2007-10-19
打赏
举报
回复
我用2,3 短接的通讯线测试的时候,我的程序没问题!
2,3短接后你的发送和接受数据还都能成功吗?
lenux
2007-10-19
打赏
举报
回复
发现你的两个线程的读和写的两个操作之间没有设同步机制,你能保证两个操作不会同时发生吗?
KevinCEC
2007-10-18
打赏
举报
回复
ce支持的串口通信只能同步通信的
wqm_44944
2007-10-18
打赏
举报
回复
我用就是同步方式啊!
canjiu
2007-10-17
打赏
举报
回复
我以前遇到的串口死机问题是底层驱动问题,本来就是调驱动的.屏蔽掉驱动的一个函数就不死机了,你好像是做应用程序的,不知你的问题.若是底层驱动问题可与我交流.
wqm_44944
2007-10-12
打赏
举报
回复
我用2,3 短接的通讯线测试的时候,我的程序没问题!
lenux
2007-10-12
打赏
举报
回复
兄弟,你读串口和写串口的线程单独分开跑测试情况怎么样了。
我没有你的设备只能靠你的反馈来判断啊。
你的问题可能不是原则上的,需要细心调试。
wqm_44944
2007-10-12
打赏
举报
回复
大家帮忙想想办法,分不够可以再加!
lenux
2007-10-10
打赏
举报
回复
if (WaitForSingleObject(ceSeries- >m_hReadCloseEvent,500) == WAIT_OBJECT_0)
等待退出的时间太长了,有个1个毫秒就够了。
明天再来看吧。代码好像有问题啊
//清空串口
PurgeComm(ceSeries- >m_hComm,PURGE_RXCLEAR ¦ PURGE_TXCLEAR);
每读一次串口都要清一下吗?
happytt
2007-10-10
打赏
举报
回复
我也是前两天解决这个问题的,代码其实都差不多,只是我只有读,没有写.
可能就像楼上说的,你用单个来测试看看
lenux
2007-10-10
打赏
举报
回复
晕啊,lz
你先只读串口,不写。看出问题不。
然后再看只写串口,不读。看出问题不。
要是单个跑可以,同时跑不行,就是同步处理出问题了。单看代码好累得。
wqm_44944
2007-10-10
打赏
举报
回复
这我通讯部分的全部代码?请大家帮我看看是那里的问题!
wqm_44944
2007-10-10
打赏
举报
回复
// CSeries.h: interface for the CCSeries class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CSERIES_H__2DB1AAE2_F6D9_4320_8421_69FAF7A70B87__INCLUDED_)
#define AFX_CSERIES_H__2DB1AAE2_F6D9_4320_8421_69FAF7A70B87__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
typedef unsigned int UNIT;
typedef void (CALLBACK* ONSERIESREAD)(CWnd*,BYTE* buf,int bufLen);
typedef struct
{
BYTE FunNO; //功能码
BYTE StartNO; //开始变量号
BYTE Length; //长度
int Data[8]; //要传输的数据
//BYTE Coefficient; //系数
//int OffSet; //偏移量
BYTE ReturnLen; //返回长度
}STRBUF;
class CCSeries
{
public:
CCSeries();
virtual ~CCSeries();
private:
//关闭写线程
void CloseWriteThread();
//关闭读线程
void CloseReadThread();
//串口写线程函数
static DWORD WINAPI WriteThreadFunc(LPVOID lparam);
//串口读线程函数
static DWORD WINAPI ReadThreadFunc(LPVOID lparam);
//向串口写入数据
static BOOL WritePort(HANDLE hComm,const BYTE *buf,DWORD bufLen);
//已打开的串口句柄
HANDLE m_hComm;
CWnd* m_pPortOwner;
//读写线程句柄
HANDLE m_hReadThread;
HANDLE m_hWriteThread;
//读写线程ID标识
DWORD m_dwReadThreadID;
DWORD m_dwWriteThreadID;
//读写线程退出事件
HANDLE m_hReadCloseEvent;
HANDLE m_hWriteCloseEvent;
public:
CString m_strRecvData;
BOOL SetSeriesTimeOuts(COMMTIMEOUTS CommTimeOuts);
BOOL WritePort(const BYTE *buf,DWORD bufLen);
void ClosePort();
//以指定的参数打开串口
BOOL OpenPort(CWnd* pProtOwner,UNIT portno = 1,UNIT baud = 19200,UNIT parity = NOPARITY,UNIT databits = 8,UNIT stopbits = 0);
//回调事件
ONSERIESREAD m_OnSeriesRead;
//灭菌参数集合
static BYTE auchByte[256];
static int auiWord[256];
//读写队列
static STRBUF WriteBuf[5];
static STRBUF ReadBuf[50];
//读写缓冲区头尾指针
static BYTE WriteBufFront;
static BYTE WriteBufRear;
static BYTE ReadBufFront;
static BYTE ReadBufRear;
//入队操作
static void EnQueue(BYTE FunNO,BYTE StartNO,BYTE Length,int *Data,BYTE PossessionMark);
static BYTE CalcReturnLen(BYTE FunNO,BYTE Len);
static char NSYL[20];
static char NSWD[20];
static char JCYL[20];
static char JCWD[20];
static char DateTime[30];
};
#endif // !defined(AFX_CSERIES_H__2DB1AAE2_F6D9_4320_8421_69FAF7A70B87__INCLUDED_)
wqm_44944
2007-10-10
打赏
举报
回复
// CSeries.cpp: implementation of the CCSeries class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SeriesComm.h"
#include "CSeries.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
const CM_THREADCOMMWRITE = WM_USER + 110;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CCSeries::CCSeries()
{
m_hComm = INVALID_HANDLE_VALUE;
}
CCSeries::~CCSeries()
{
}
BOOL CCSeries::WritePort(HANDLE hComm, const BYTE *buf, DWORD bufLen)
{
DWORD dwNumBytesWritten = 0;
DWORD dw_HaveNumWritten = 0;
ASSERT(hComm != INVALID_HANDLE_VALUE);
//清空串口
PurgeComm(hComm,PURGE_RXCLEAR | PURGE_TXCLEAR);
do
{
if(WriteFile(hComm,buf + dw_HaveNumWritten,bufLen - dw_HaveNumWritten,&dwNumBytesWritten,NULL))
{
dw_HaveNumWritten = dw_HaveNumWritten + dwNumBytesWritten;
//写入完成
if (dw_HaveNumWritten == bufLen)
{
break;
}
Sleep(10);
}
else
{
AfxMessageBox(_T("write failed."));
return FALSE;
}
}while(TRUE);
return TRUE;
}
//串口读线程函数
DWORD WINAPI CCSeries::ReadThreadFunc(LPVOID lparam)
{
CCSeries *ceSeries = (CCSeries*)lparam;
DWORD evtMask;
BYTE * readBuf = NULL; //读取的字节
DWORD actualReadLen = 0; //实际读取的字节数
DWORD WillReadLen;
DWORD dwReadErrors;
COMSTAT cmState;
//清空缓冲,并检查串口是否打开
ASSERT(ceSeries->m_hComm != INVALID_HANDLE_VALUE);
//清空串口
PurgeComm(ceSeries->m_hComm,PURGE_RXCLEAR | PURGE_TXCLEAR);
SetCommMask(ceSeries->m_hComm,EV_RXCHAR | EV_CTS | EV_DSR);
while(TRUE)
{
if (WaitCommEvent(ceSeries->m_hComm,&evtMask,0))
{
//延时50毫秒再读数据
Sleep(30);
// CCSeries::Count += 1;
SetCommMask(ceSeries->m_hComm,EV_RXCHAR | EV_CTS | EV_DSR);
//表示串口接收到字符
if ((evtMask & EV_RXCHAR) == EV_RXCHAR)
{
ClearCommError(ceSeries->m_hComm,&dwReadErrors,&cmState);
WillReadLen = cmState.cbInQue;
if (WillReadLen <=0)
{
continue;
}
readBuf = new BYTE[WillReadLen];
ReadFile(ceSeries->m_hComm,readBuf,WillReadLen,&actualReadLen,0);
//读取的数据大于0
if (actualReadLen > 0)
{
//触发回调函数
ceSeries->m_OnSeriesRead(ceSeries->m_pPortOwner,readBuf,actualReadLen);
}
//清空串口
PurgeComm(ceSeries->m_hComm,PURGE_RXCLEAR | PURGE_TXCLEAR);
delete [] readBuf;
}
}
//如果收到读线程退出信号,则退出线程
if (WaitForSingleObject(ceSeries->m_hReadCloseEvent,500) == WAIT_OBJECT_0)
{
break;
}
}
return 0;
}
//串口写线程函数
DWORD WINAPI CCSeries::WriteThreadFunc(LPVOID lparam)
{
CCSeries *ceSeries = (CCSeries*)lparam;
MSG msg;
DWORD dwWriteLen = 0;
BYTE * buf = NULL;
while(TRUE)
{
if (PeekMessage(&msg,0,0,0,PM_REMOVE))
{
if (msg.hwnd != 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
continue;
}
if (msg.message == CM_THREADCOMMWRITE)
{
buf = (BYTE*) msg.lParam;
dwWriteLen = msg.wParam;
WritePort(ceSeries->m_hComm,buf,dwWriteLen);
delete[] buf;
}
}
//如果收到写线程退出信号,则退出线程
if (WaitForSingleObject(ceSeries->m_hWriteCloseEvent,500) == WAIT_OBJECT_0)
{
break;
}
ceSeries->m_hWriteThread = NULL;
}
return 0;
}
//关闭读线程
void CCSeries::CloseReadThread()
{
SetEvent(m_hReadCloseEvent);
//设置所有事件无效
SetCommMask(m_hComm,0);
//清空所有将要读的数据
PurgeComm(m_hComm,PURGE_RXCLEAR);
if (WaitForSingleObject(m_hReadThread,10000) == WAIT_TIMEOUT)
{
TerminateThread(m_hReadThread,0);
}
m_hReadThread = NULL;
}
//关闭写线程
void CCSeries::CloseWriteThread()
{
SetEvent(m_hWriteCloseEvent);
//设置所有事件无效
SetCommMask(m_hComm,0);
//清空所有将要读的数据
PurgeComm(m_hComm,PURGE_TXCLEAR);
if (WaitForSingleObject(m_hWriteThread,10000) == WAIT_TIMEOUT)
{
TerminateThread(m_hWriteThread,0);
}
m_hWriteThread = NULL;
}
BOOL CCSeries::OpenPort(CWnd *pProtOwner, UNIT portno, UNIT baud, UNIT parity, UNIT databits, UNIT stopbits)
{
DCB commParam;
TCHAR szPort[15];
if (m_hComm != INVALID_HANDLE_VALUE)
{
return TRUE;
}
ASSERT(pProtOwner != NULL);
ASSERT(portno > 0 && portno < 5);
//设置串口名
wsprintf(szPort,L"COM%d:",portno);
//打开串口
m_hComm = CreateFile(szPort,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
if (m_hComm == INVALID_HANDLE_VALUE)
{
AfxMessageBox(_T("无法打开端口!请检查是否已被占用。"));
return FALSE;
}
//得到打开串口的当前属性参数,修改后再重新设置串口
//设置串口的超时 特性为立即返回
if (!GetCommState(m_hComm,&commParam))
{
AfxMessageBox(_T("GetCommState faild."));
return FALSE;
}
commParam.BaudRate = baud;
commParam.fBinary = TRUE;//设置二进制模式,此处必须设置为true
commParam.fParity = TRUE;//支持奇偶校验
commParam.ByteSize = databits;
commParam.Parity = NOPARITY;
commParam.StopBits = stopbits;
commParam.fOutxCtsFlow = FALSE;
commParam.fOutxDsrFlow = FALSE;
commParam.fDtrControl = DTR_CONTROL_ENABLE;
commParam.fDsrSensitivity = FALSE;
commParam.fTXContinueOnXoff = 0;
commParam.fOutX = 0;
commParam.fInX = 0;
commParam.ErrorChar = FALSE;
commParam.fNull = FALSE;
commParam.fRtsControl = RTS_CONTROL_ENABLE;
commParam.fAbortOnError = FALSE;
if (!SetCommState(m_hComm,&commParam))
{
AfxMessageBox(_T("SetCommState error."));
return FALSE;
}
COMMTIMEOUTS CommTimeOuts;
GetCommTimeouts(m_hComm,&CommTimeOuts);
CommTimeOuts.ReadIntervalTimeout = 100;
CommTimeOuts.ReadTotalTimeoutMultiplier = 1;
CommTimeOuts.ReadTotalTimeoutConstant = 100;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 0;
if (!SetCommTimeouts(m_hComm,&CommTimeOuts))
{
AfxMessageBox(_T("无法按当前参数配置端口,请检查参数!"));
return FALSE;
}
m_pPortOwner = pProtOwner;
SetCommMask(m_hComm,EV_RXCHAR);
SetupComm(m_hComm,1024,1024);
PurgeComm(m_hComm,PURGE_TXCLEAR | PURGE_RXCLEAR);
m_hReadCloseEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
if (NULL == m_hReadCloseEvent)
{
AfxMessageBox(_T("Create read close event failed."));
return FALSE;
}
m_hWriteCloseEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
if (NULL == m_hWriteCloseEvent)
{
AfxMessageBox(_T("Create write close event failed."));
return FALSE;
}
m_hReadThread = CreateThread(NULL,0,ReadThreadFunc,this,0,&m_dwReadThreadID);
if (NULL == m_hReadThread)
{
AfxMessageBox(_T("Create read thread failed."));
return FALSE;
}
m_hWriteThread = CreateThread(NULL,0,WriteThreadFunc,this,0,&m_dwWriteThreadID);
if (NULL == m_hWriteThread)
{
AfxMessageBox(_T("Create write thread failed."));
return FALSE;
}
return TRUE;
}
//关闭串口
void CCSeries::ClosePort()
{
if (m_hComm == INVALID_HANDLE_VALUE)
{
return;
}
CloseReadThread();
CloseWriteThread();
if (!CloseHandle(m_hComm))
{
m_hComm = INVALID_HANDLE_VALUE;
return;
}
}
BOOL CCSeries::WritePort(const BYTE *buf, DWORD bufLen)
{
if (PostThreadMessage(m_dwWriteThreadID,CM_THREADCOMMWRITE,WPARAM(bufLen),LPARAM(buf)))
{
return TRUE;
}
return FALSE;
}
BOOL CCSeries::SetSeriesTimeOuts(COMMTIMEOUTS CommTimeOuts)
{
ASSERT(m_hComm != INVALID_HANDLE_VALUE);
return SetCommTimeouts(m_hComm,&CommTimeOuts);
}
lenux
2007-10-10
打赏
举报
回复
还有可能读写线程有问题,死锁
lenux
2007-10-10
打赏
举报
回复
缓冲区设小一点,1k,
qfeng168
2007-10-10
打赏
举报
回复
是不是线程阻塞掉了
加载更多回复(6)
串口导致单片机
死机
的原因
本文主要讲了串口导致单片机
死机
的原因有哪些,下面一起来学习下
ECOM串口助手V2.80 亲测可用
1、 支持Windows 9x / 2000 / XP / 2003 / Vista / Win7系统; 2、 绿色软件,不需安装。运行解压软件,将压缩包解压到指定目录即可。卸载时只需将程序目录删除; 3、 支持常用的1200 ~ 921600bps波特率; 4、 端口范围是COM1-COM255,支持扩展端口(USB转RS232); 5、 能设置校验、数据位和停止位; 6、 能以字符或十六进制收发数据,支持中文字符的收发; 7、 支持文件数据的发送; 8、 数据发送区允许设置发送周期,自动发送数据; 9、 支持键盘输入,将键盘数据发送到串口; 10、 支持定时保存接收窗口数据,便于查看长时间调试记录信息; 11、 有效的检测通讯错误,避免软件
死机
(如USB转串口设备拔出检测); 12、 数据接收窗口及文件发送均采用多线程设计,避免软件时机
现象
。 13. 带CRC等校验模式。
USB转串口常见故障
现象
和故障分析
通用USB推出以后,串口逐渐被USB接口替代,在普通电脑上已经越来越少,但目前工业环境中许多重要的设备仍使用RS-232接口界面设计(如台式电脑、PLC等)。在端口被大大削减的笔记本上,不太常用的串口早已消失。为了能够使用串口,没办法只能利用现在广泛存在并使用的USB接口来模拟串口使用(USB转232、USB转485/422)。在实际应用过程肯定会遇到各种难题,下面给大家分析可能遇到的问题和对策。
基于MFC的纯方位定位系统
串口通讯
软件设计 (2012年)
针对定位系统扩频通信的功能需求和上位机、下位机的硬件特点,在通信程序中使用多线程技术,以层次化结构完成了数据处理芯片和PC端的串行口通信程序的设计,解决了通信过程中常见的线程阻塞和
死机
现象
,突出了系统的构造性和组合性;实际应用证明:系统通信实时性好,纠错能力强,可靠性高,满足对水下定位跟踪数据传输过程的模拟要求?
西门子S7-1200PLC MODBUS通讯协议轮询的探讨.pdf
#资源达人分享计划#
嵌入开发(WinCE)
19,522
社区成员
41,567
社区内容
发帖
与我相关
我的任务
嵌入开发(WinCE)
硬件/嵌入开发 嵌入开发(WinCE)
复制链接
扫一扫
分享
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章