11666|25

61

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

串口通讯死机现象 [复制链接]

我的系统出现死机现象:打开应用程序(EVC开发)通过串口与控制器通讯。刚开始没有问题。应用程序发出命令后,控制器收到后解析并响应请求。通讯一段时间后系统出现死机现象。但是,当我把控制器断电重启一下,这时候系统又好了。通讯一段时间又死机了。这是怎么回事??谁遇到过这种情况!救救我!(我确定控制器没问题,我用.net 开发的应用与其通讯一直没问题) 我的板子是2410开发板。硬件应该没问题。平台为wince 4.2

最新回复

请教高手,我采用电脑测试DVB-S串口,老是烧坏主板,请问是什么原因并怎么处理才能防止主板烧坏?谢谢!  详情 回复 发表于 2008-8-1 21:10
点赞 关注

回复
举报

67

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
是不是内存泄露啊,导致内存耗尽死机啊
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
我觉得可能性不大,因为我把与开发板相连的控制器重启一下,就不死机了(鼠标可以移动了)。应用程序与控制器自动通讯几分钟后又死机了。
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

4
 
是不是串口有些设置设错了
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

5
 
两边波特率不一样?

先少量数据发送试试呢。
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

6
 
我还用dell的商务机一连上就蓝屏,其它机又没事
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

7
 
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,16384,16384);

        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;
}
这是我的串口配置代码。请大家帮我看看!evc应用与控制器的波特率都是19200,开发板上的应用程序可以正确的与控制器进行通讯一段时间。因为如果波特率不一样,传输的数据就会出错。控制器不会响应开发板上应用程序的请求。
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

8
 
是不是线程阻塞掉了
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

9
 
缓冲区设小一点,1k,
 
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

10
 
还有可能读写线程有问题,死锁
 
 
 

回复

46

帖子

0

TA的资源

一粒金砂(初级)

11
 

// 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);
}
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

12
 
// 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_)
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

13
 
这我通讯部分的全部代码?请大家帮我看看是那里的问题!
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

14
 
晕啊,lz
你先只读串口,不写。看出问题不。
然后再看只写串口,不读。看出问题不。

要是单个跑可以,同时跑不行,就是同步处理出问题了。单看代码好累得。
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

15
 
我也是前两天解决这个问题的,代码其实都差不多,只是我只有读,没有写.
可能就像楼上说的,你用单个来测试看看
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

16
 
if (WaitForSingleObject(ceSeries- >m_hReadCloseEvent,500) == WAIT_OBJECT_0)

等待退出的时间太长了,有个1个毫秒就够了。

明天再来看吧。代码好像有问题啊
//清空串口
PurgeComm(ceSeries- >m_hComm,PURGE_RXCLEAR  ? PURGE_TXCLEAR);
每读一次串口都要清一下吗?
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(中级)

17
 
大家帮忙想想办法,分不够可以再加!
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

18
 
兄弟,你读串口和写串口的线程单独分开跑测试情况怎么样了。
我没有你的设备只能靠你的反馈来判断啊。
你的问题可能不是原则上的,需要细心调试。
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

19
 
我用2,3 短接的通讯线测试的时候,我的程序没问题!
 
 
 

回复

57

帖子

0

TA的资源

一粒金砂(初级)

20
 
我以前遇到的串口死机问题是底层驱动问题,本来就是调驱动的.屏蔽掉驱动的一个函数就不死机了,你好像是做应用程序的,不知你的问题.若是底层驱动问题可与我交流.
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表