TechWeb-技术社区 » 硬件选配 » 串口通讯死机现象


2008-8-26 16:19 匿名
串口通讯死机现象

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

2008-8-26 16:20 匿名
是不是内存泄露啊,导致内存耗尽死机啊

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

2008-8-26 16:20 匿名
是不是串口有些设置设错了

2008-8-26 16:20 匿名
两边波特率不一样?
K(Q)c5v:f.s3|3e3X
x~b.?7P5p 先少量数据发送试试呢。

2008-8-26 16:20 匿名
两边波特率不一样?
1]cy%W2Ij ] ni%q;` W!v3RU+~ [ BzkP3y
先少量数据发送试试呢。

2008-8-26 16:20 匿名
BOOL CCSeries::OpenPort(CWnd *pProtOwner, UNIT portno, UNIT baud, UNIT parity, UNIT databits, UNIT stopbits)
Kk'lO*G/dcK {
0l+Il&]ZF1g DCB commParam;
J_2l@1I5o.S R~3B TCHAR szPort[15];
,CI3[]t T K7Wu[ {NO$Al*K BW
if (m_hComm != INVALID_HANDLE_VALUE)
4I b+c {+VB2u;W {
k oc9Ir[3Ws return TRUE; )TL@P7{/qB)w
} JF*iF(phq,]~
!~q7yPoM xd
ASSERT(pProtOwner != NULL); l{*rZXU'n
ASSERT(portno > 0 && portno < 5); :B pWjEl A(KK7j
MK.q#aVeJ(N x h"[
//设置串口名 "{O.@2yf&iqax(_.IA
wsprintf(szPort,L"COM%d:",portno);
Q8k Kgxg ']0dpv9u CH
//打开串口
b5j3~+K)_$j0^R m_hComm = CreateFile(szPort,GENERIC_READ ¦ GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); w^2X4I3B!["a

@dT.zet8G7N!{_ if (m_hComm == INVALID_HANDLE_VALUE)
L#E.w2qQu {
#l$lU2h s%Yb AfxMessageBox(_T("无法打开端口!请检查是否已被占用。"));
X,q1JCD d.^ return FALSE;
,P1B8AA#H)}$~ r0bA/i } Jo8D4D#{

$Tv*[hJJ //得到打开串口的当前属性参数,修改后再重新设置串口
%O5l0f sq7ju //设置串口的超时 特性为立即返回
6sk.C!}Z
tdu|R+Gtj if (!GetCommState(m_hComm,&commParam)) *thtqWD
{ ?KP,d-?'R0cbW7|
AfxMessageBox(_T("GetCommState faild."));
}:Mp s{0L return FALSE;
}1Q;m2_!j5j's"W9S }
q5MGzi3e.R+a/P6e +ex `aN1w[xv
commParam.BaudRate = baud; Qj1[6Q@gF
commParam.fBinary = TRUE;//设置二进制模式,此处必须设置为true
C;Bj-x5v commParam.fParity = TRUE;//支持奇偶校验
+GT2U$AN7l commParam.ByteSize = databits; P"VN+zXUP"Gk
commParam.Parity = NOPARITY;
#@!G&K*Qa0G commParam.StopBits = stopbits;
\gh8u4Mv commParam.fOutxCtsFlow = FALSE; -p)w8y:CHC
commParam.fOutxDsrFlow = FALSE;
%J4zR6N.Yb$T$j commParam.fDtrControl = DTR_CONTROL_ENABLE;
"@v8@&dv
_8~ xo/}Y commParam.fDsrSensitivity = FALSE;
j/?:kt$W)q,I-O commParam.fTXContinueOnXoff = 0; 3ET5~5n2M8{xT
commParam.fOutX = 0;
e*O^~|)P7k commParam.fInX = 0; )Bh4Wtp
commParam.ErrorChar = FALSE;
(}i |6~9y*C&W W|3@ commParam.fNull = FALSE;
v7t'hs&M#VqO commParam.fRtsControl = RTS_CONTROL_ENABLE; ;]@ j;CV8k4?3I
;V;W-v.o^ iB
commParam.fAbortOnError = FALSE;
3t1Jo;^UK
:XE?a-HAW I if (!SetCommState(m_hComm,&commParam))
x'A X8df7kg0p {
&I;s^\9Y7D AfxMessageBox(_T("SetCommState error."));
|.R!^"u$@4B return FALSE; U!@0Jcs-]#Qt q
}
r/rUl-T#b:]0i e
m.i7Dn+A9SX2B COMMTIMEOUTS CommTimeOuts;
$p6Yo M,Rdv GetCommTimeouts(m_hComm,&CommTimeOuts);
bk W`+ZA,z&c:c CommTimeOuts.ReadIntervalTimeout = 100; /Cd6|] mmU
CommTimeOuts.ReadTotalTimeoutMultiplier = 1;
Q@_!T*~"B CommTimeOuts.ReadTotalTimeoutConstant = 100; &cY,n+Gbl
CommTimeOuts.WriteTotalTimeoutMultiplier = 0; WXX m9{8@WK
CommTimeOuts.WriteTotalTimeoutConstant = 0;
7Mu.g(G.ihFO
8I*zz'H(i.YH if (!SetCommTimeouts(m_hComm,&CommTimeOuts))
vY\_,A_R*p { ] ~h V/ju
AfxMessageBox(_T("无法按当前参数配置端口,请检查参数!")); 5vV(s/B(vA_h_
return FALSE; l-|:N(Ox
}
s%C}4m3]H m_pPortOwner = pProtOwner;
q~\K1H"A:i
7_zi9ed9q&N SetCommMask(m_hComm,EV_RXCHAR);
@Or{M4d0H d 6rVuQ0e d'wE
SetupComm(m_hComm,16384,16384); wB&{$d*V%[X
:hD&U8X-n
PurgeComm(m_hComm,PURGE_TXCLEAR ¦ PURGE_RXCLEAR);
vg.T"lQ )E bf/i|o3HE7hN
m_hReadCloseEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
5Y*[b7e:z L"d*J!_D1U${ if (NULL == m_hReadCloseEvent) z^UB5Z:\J8?.n
{
}2qD,d!H AfxMessageBox(_T("Create read close event failed."));
gax x0p!p6^-[O return FALSE;
,{G]\@ Vt5q _ }
pi``3v5^w0i s&fO
(W J_0O'}v m m_hWriteCloseEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
kuSx M/z{2` f if (NULL == m_hWriteCloseEvent) H yN5R'[&`
{
7SHEJ1l3P8Ry'u(z.a AfxMessageBox(_T("Create write close event failed.")); l7L"zKt|G7l/Eav|
return FALSE;
|`@T FT,cf5Q? } Y'w X4d2Kj&Q&l

n;\bHg m_hReadThread = CreateThread(NULL,0,ReadThreadFunc,this,0,&m_dwReadThreadID); c n$KRBT
if (NULL == m_hReadThread) !Hf2MYE`&q[
{
l(E-hUO(wgS0M{Q AfxMessageBox(_T("Create read thread failed."));
-hOFHZp W:?Z.l return FALSE; zv/^2t6PaBF k#g$A
}
C/q QL5^:[G"sK`*x D8Rc,_Z0j s9x#`NT
m_hWriteThread = CreateThread(NULL,0,WriteThreadFunc,this,0,&m_dwWriteThreadID); (y Ke&_&]G'MT
if (NULL == m_hWriteThread)
_)J%[q1w { \*M)\%Z,f.{a-QEm B
AfxMessageBox(_T("Create write thread failed."));
/K Zwr%p L ] N return FALSE;
6HbU)R6Inw.cc } 0L:|s~:Ex-]+G/G G
return TRUE;
EA DeN@C } 6fZ0}:Kb
这是我的串口配置代码。请大家帮我看看!evc应用与控制器的波特率都是19200,开发板上的应用程序可以正确的与控制器进行通讯一段时间。因为如果波特率不一样,传输的数据就会出错。控制器不会响应开发板上应用程序的请求。

2008-8-26 16:21 匿名
是不是线程阻塞掉了

2008-8-26 16:21 匿名
缓冲区设小一点,1k,

2008-8-26 16:21 匿名
还有可能读写线程有问题,死锁

2008-8-26 16:21 nimabi
// CSeries.cpp: implementation of the CCSeries class. aM~&a*zl E$we
// oge{ [Hd,rQ D,u
////////////////////////////////////////////////////////////////////// #C-Q O#Uk'Er

nL3Fy)R&Z #include "stdafx.h"
JKP,o @?sO #include "SeriesComm.h"
i5T8y s}1g i7K3z #include "CSeries.h"
f/|w|B+l srJKvb
#ifdef _DEBUG
eNZoXJ @y #undef THIS_FILE
@v C2l _(z9\znRtt static char THIS_FILE[]=__FILE__;
iG%bY.ku!| #define new DEBUG_NEW I L@%NSDe
#endif 2nSw` A"s.@G)t
const CM_THREADCOMMWRITE = WM_USER + 110; /n|V#Fzs k Rc
//////////////////////////////////////////////////////////////////////
U ~(n2c-x/U.cy // Construction/Destruction
%~y!eLtk {8H ////////////////////////////////////////////////////////////////////// 4bI]G!_E
CCSeries::CCSeries()
0gp;cD!N { r'es)~D4mo
m_hComm = INVALID_HANDLE_VALUE; w p5lJ \Y4j)i9`3r
} Fu&c,h"\7f-SD1B

1E.[%j4l0h ^ CCSeries::~CCSeries() U [g d$Dv*Y |
{
\L d.d| EzM]I*g
} 9[!g2@N Q
BOOL CCSeries::WritePort(HANDLE hComm, const BYTE *buf, DWORD bufLen) 5m*`9MS^.v$t!mG&W
{
@n4z"E9z*U*~NIu DWORD dwNumBytesWritten = 0; %M6XW8Rd%I*EX
DWORD dw_HaveNumWritten = 0;
"E l$W F BwU J_"jhr"l6p%b X
ASSERT(hComm != INVALID_HANDLE_VALUE); o!x.X B`U
//清空串口
zp\ qBD w&Mtj PurgeComm(hComm,PURGE_RXCLEAR ¦ PURGE_TXCLEAR);
h%Sp&g#Y5L4[l*{ do
FE2?6b]%Ce8VD#n {
B1mcz2paW fH2e if(WriteFile(hComm,buf + dw_HaveNumWritten,bufLen - dw_HaveNumWritten,&dwNumBytesWritten,NULL))
}zp`b*k0y { ?%O;huc3AM+Dl
dw_HaveNumWritten = dw_HaveNumWritten + dwNumBytesWritten; (zT^Ieuo
            //写入完成 BE!Ul\/},|
if (dw_HaveNumWritten == bufLen) J0o9BI n9C] nSM
{
G"Pi+O+Kl break; vu;a8wT x C
} 3C ]T;W;\o*m,X+r Jcp
Sleep(10);
'^9?Hld6l+P i@n)M } C/Mu(b H
else UL`3k+t.CQ(?O
{ %oFT6qi&EcqR6b
AfxMessageBox(_T("write failed."));
E ]1jN.H2g S return FALSE;
'f LD t k`@8};Z } mHagl$Xtt
}while(TRUE);
bx{L#F4J-Y!T L
Uc:o8hW ^a#iav S return TRUE;
M}3`%O+n }
$@UE!leXkaj-~w +z^jFxu{+q
//串口读线程函数 -u3e}(Z`:Q+C0X0pw
DWORD WINAPI CCSeries::ReadThreadFunc(LPVOID lparam)
H7P8jw-}uj Z*o&V {
\(aAgI)X CCSeries *ceSeries = (CCSeries*)lparam;
/T? u"IpR I0ZR4[9?(W#l0KJ
DWORD evtMask; -o:vQpy},J2c:_
BYTE * readBuf = NULL; //读取的字节 H`7QD6Z2\
DWORD actualReadLen = 0; //实际读取的字节数
)q#w xrK%_J%j DWORD WillReadLen;
+m u(v(yQ K1V
Tgr6Q5S7T.I DWORD dwReadErrors;
(N [!GOnL#~f COMSTAT cmState; JcQ2isZ'vE}l
\2DzZ P$sLm1gR*i
//清空缓冲,并检查串口是否打开
!S)HaB9z*r-R-A.?9q&Kf ASSERT(ceSeries->m_hComm != INVALID_HANDLE_VALUE); D H)]+{3f$~2X0C
1Y1P,g S ?xH
//清空串口
KYcHLF%M!J PurgeComm(ceSeries->m_hComm,PURGE_RXCLEAR ¦ PURGE_TXCLEAR);
7R9@L`6l&P5dvsz#w
M d9e o z5Ce SetCommMask(ceSeries->m_hComm,EV_RXCHAR ¦ EV_CTS ¦ EV_DSR);
-Y:b1@ Rc5{8n&N while(TRUE)
/C ]`As%U]3c { RbV4Fq-x3N6~i9t
if (WaitCommEvent(ceSeries->m_hComm,&evtMask,0)) *J} t#[Gt"c
{
o'YQ)DWt //延时50毫秒再读数据
-M[ W Y~/~v8w x Sleep(30);
'w"M i&e6O"Us'R           // CCSeries::Count += 1; xyOb7d0NNkvY0Ia.[
SetCommMask(ceSeries->m_hComm,EV_RXCHAR ¦ EV_CTS ¦ EV_DSR); \&Gd!J4D7G.g#V
//表示串口接收到字符 -x j t0oH1t G/o
if ((evtMask & EV_RXCHAR) == EV_RXCHAR) /ZM${6T(]*[1TU0[
{
/k.V@%S9|6o3y(u JF ClearCommError(ceSeries->m_hComm,&dwReadErrors,&cmState); [odr7Cc'i i
WillReadLen = cmState.cbInQue;
h'LG@G (x f Q;]+o
if (WillReadLen <=0)
9P4cL,[/gb|2i { )ow7t;}9s {:Vg:}e
continue; BTa4e.U+rB$VK0I
} ,^+L+|(]8i2oZ'q,z T4`

TX-ll:u$] QiT readBuf = new BYTE[WillReadLen];
i1I eA2f ReadFile(ceSeries->m_hComm,readBuf,WillReadLen,&actualReadLen,0); m G Lo-RTQ ]Y~
//读取的数据大于0 +^&S7m M%B\2W-V
if (actualReadLen > 0) 9ab7\i%R)q5e
{
Z.fM#Y${fy-ex.x //触发回调函数
Qlbn:R {5y_}0a:{ ceSeries->m_OnSeriesRead(ceSeries->m_pPortOwner,readBuf,actualReadLen); d,aB9TR qA
} "[2_U u P L!c
//清空串口
}r S]*}sW PurgeComm(ceSeries->m_hComm,PURGE_RXCLEAR ¦ PURGE_TXCLEAR); {8Mj3b6m.a'?
delete [] readBuf;
JC)c Yj:\$z] z }
amjO&c1s } ? jm} E_ a
//如果收到读线程退出信号,则退出线程 %B6JHnb8w*R}8^ C
if (WaitForSingleObject(ceSeries->m_hReadCloseEvent,500) == WAIT_OBJECT_0) erl6Bsw'Mw!kQ
{
K2wE%{px break;
4YS2`-{.F1[ q } :t/F Yi?D
} sKKok0X9H
return 0; $i/`6Hk0ccT
}
r NH'OTg1d )eeKF g.Y-Z)|
//串口写线程函数 Rzv,N/`?%w,K7T[a
DWORD WINAPI CCSeries::WriteThreadFunc(LPVOID lparam)
W(S3RNb {
9Up'S3m^bl9u)}FR CCSeries *ceSeries = (CCSeries*)lparam;
C#Pe0}h\+t!l
iaZ])s G MSG msg; 5aA.d,qk B
+a g Vgj
DWORD dwWriteLen = 0; @7Z2oPd/h,D'a#K
BYTE * buf = NULL;
+@M)V~/tt,V
4p(y&wB0k!@o{ W while(TRUE) H l B!gQ |
{ dz1L]*Q
if (PeekMessage(&msg,0,0,0,PM_REMOVE)) 1R3H pdr)~8i$X)zO7c
{
*L9We5f {7q5AZ u if (msg.hwnd != 0) 7w+jc d5p4Jv
{ SxfFmkD
TranslateMessage(&msg);
f%c(n5NIt h7W DispatchMessage(&msg);
*vF"EF Z continue;
:|/{WrFC}+W } M#W.L"S"c*N
6H)yt4vq#y8D'q
if (msg.message == CM_THREADCOMMWRITE) ?s.p?3m4nBg
{
W2?[9p9x@@ buf = (BYTE*) msg.lParam;
7UnhyR$K6Y dwWriteLen = msg.wParam;
w dk] F%N:K(C $tB_Lp
WritePort(ceSeries->m_hComm,buf,dwWriteLen); 3g7dVkP~Q+J

K1h n4Hz q delete[] buf; -V(]4|8C)_%yU7V
} /[@6e)Q}R
}
[&AN6S:WgTQ 3{mM)X|l#^#dhu%`
//如果收到写线程退出信号,则退出线程
:|c9~!_KsKg#I if (WaitForSingleObject(ceSeries->m_hWriteCloseEvent,500) == WAIT_OBJECT_0) )~)\9E%@@S3q,tu
{
K%\:M d8g break; /W ErA"BWb
}
Yl(y3D#UFU ceSeries->m_hWriteThread = NULL; %u4Y]luck
} ;`pJ"h$S.Z~
return 0;
N `|\/n c{7G6ug!Y'F/h } @^(p@U;s5{/uT

%k2X0ML] //关闭读线程
T"?5_]k _tPc+k void CCSeries::CloseReadThread()
.niV5I|~C9S { 7GG3Uk&E
SetEvent(m_hReadCloseEvent);
(f,@oUWm|f} B d?z,q
//设置所有事件无效 /X.BU#r hb'~
SetCommMask(m_hComm,0);
1i[D/pf x //清空所有将要读的数据 U.~"V4E#gX.y"V
PurgeComm(m_hComm,PURGE_RXCLEAR); TZn,m }:m/~b
3hvipcyn$n
if (WaitForSingleObject(m_hReadThread,10000) == WAIT_TIMEOUT) 2_Q(w"o:l,^h
{
8EVAQ$p:QQ` TerminateThread(m_hReadThread,0);
+_/h%c} yzj;K,s }
Wpu`x5? m_hReadThread = NULL; d&V*npSm4m
}
K!Ok"PwOR[ g%RnL?
//关闭写线程
%V9x%\*p^n lQuZ void CCSeries::CloseWriteThread() ILz2L r` T{*n
{
+zKF)UX3p6x SetEvent(m_hWriteCloseEvent); 1Yw-|6FIk
@?\y8Vj,Q;lA
//设置所有事件无效
E5S4q!b:| o+N6D f}!P SetCommMask(m_hComm,0); L`?9e8}
//清空所有将要读的数据 4Z"q&rXB p i+L+k)?
PurgeComm(m_hComm,PURGE_TXCLEAR);
l^n h3cKh5I
!YXq ZS J&g0?+P if (WaitForSingleObject(m_hWriteThread,10000) == WAIT_TIMEOUT) O wzkGt+G1h?&hd"W
{
FA#S5T0IML$I,Bu9~ TerminateThread(m_hWriteThread,0); %OO\ ~ D b
}
k~ K-M(}0Mc.g m_hWriteThread = NULL;
Mo-WIOpx3v } R6a{\5E3drbm|

yq;n(JB0r BOOL CCSeries::OpenPort(CWnd *pProtOwner, UNIT portno, UNIT baud, UNIT parity, UNIT databits, UNIT stopbits) &L6v@'{FT rR
{ l ga Sc3w:B
DCB commParam;
X{ n dPp+L TCHAR szPort[15]; 6p}eF(j'q
~6nkA;R
if (m_hComm != INVALID_HANDLE_VALUE) Q-q%lU+sI5B+W
{ -Z OUgc
return TRUE; :kQ-V\KO9u/}2}E:F
} $UN7x |d
_ ?5XqyIJ M
ASSERT(pProtOwner != NULL);
8A8] f7o*J^:c2R4y ASSERT(portno > 0 && portno < 5);
5`|j$f{k+ez {q:@ `#h1n!Y3^?0I
//设置串口名
*oo&t| e-f$`{$A wsprintf(szPort,L"COM%d:",portno); n s W;j_
f0Z)hu)|Bk
//打开串口
qZ/KLh3mJ9p5` m_hComm = CreateFile(szPort,GENERIC_READ ¦ GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); d/d8P Jak}yQ
N)EW#}|%s0T\"n
if (m_hComm == INVALID_HANDLE_VALUE) e Iv!U6[E6{
{ rtkJ4^*`8fT;G7Nx n
AfxMessageBox(_T("无法打开端口!请检查是否已被占用。")); k mT6j j:A a
return FALSE;
%dNF*P$g$d1CRg ^ x8y }
TU4fnu)I#r[P
h~c+t f9yJy%j //得到打开串口的当前属性参数,修改后再重新设置串口
%cn.n4eW+@'g"|K#t //设置串口的超时 特性为立即返回 'ZgI*nD8_[a
j;@#{eQr
if (!GetCommState(m_hComm,&commParam))
0Bhe0?"oi:nt9AH { },\4dK$Y%? K~x;\
AfxMessageBox(_T("GetCommState faild.")); p]{hF*B9} X)g
return FALSE;
C1C1?^Xw } &nJ*cf.D/{0dZJ:db

Ib;p"~ fkSh @ commParam.BaudRate = baud; p o7L{:i
commParam.fBinary = TRUE;//设置二进制模式,此处必须设置为true 7JXE#L5u o|l2l j+K'`
commParam.fParity = TRUE;//支持奇偶校验
p2JK)S\0{` commParam.ByteSize = databits; x3vt,LvS6]2@[
commParam.Parity = NOPARITY; 7S3\}/E1Pi0Pq
commParam.StopBits = stopbits;
)C%R$YW7@+d commParam.fOutxCtsFlow = FALSE; &n3C I7g\7b
commParam.fOutxDsrFlow = FALSE;
/Ab*|f?#^6O commParam.fDtrControl = DTR_CONTROL_ENABLE;
*g6RDO.Ou ;{}G?QD
commParam.fDsrSensitivity = FALSE;
v rbgefs-? commParam.fTXContinueOnXoff = 0;
s#QC z0Unu;k commParam.fOutX = 0; sFVhxP7W+D jt/k
commParam.fInX = 0; j5P{OJe
commParam.ErrorChar = FALSE;
'yk!j(W;e8{#t5l|v commParam.fNull = FALSE;
i$\,Cw.p fW commParam.fRtsControl = RTS_CONTROL_ENABLE;
*x![ D+yZw HS7MqF3sm,ZG*T
commParam.fAbortOnError = FALSE; &D W)A/y'F&Z:H&_Fl$A
SQO+_%[!?
if (!SetCommState(m_hComm,&commParam))
6MAo-uet4h#] {
6w \;m Sd AfxMessageBox(_T("SetCommState error.")); 7Yw"_ @k*H*L6T
return FALSE;
^BI2^)^L)J }
zBtg&q"v)_u
H'T H8yE4yN]d COMMTIMEOUTS CommTimeOuts; MR&?}LQ
GetCommTimeouts(m_hComm,&CommTimeOuts); 6l9Bd fV@(~i
CommTimeOuts.ReadIntervalTimeout = 100; 5p|5m%R!YpW+soXu
CommTimeOuts.ReadTotalTimeoutMultiplier = 1;
HF}5rk CommTimeOuts.ReadTotalTimeoutConstant = 100; R-jUY(Q*w*R q
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
V^j|X:W CommTimeOuts.WriteTotalTimeoutConstant = 0;
1x(D5BRA\wu X 7in)|5iU,C+_
if (!SetCommTimeouts(m_hComm,&CommTimeOuts)) $b lfEU_n
{
| W/vlH1J/R.jE AfxMessageBox(_T("无法按当前参数配置端口,请检查参数!")); J/k!Sr.bnQ#js
return FALSE;
W)U0K9Kni8MK&I }
b9i3Vr6l5I` m_pPortOwner = pProtOwner;
8J(qF1f yW.f7u"P8M\(? 5MB&\@8kxS+g
SetCommMask(m_hComm,EV_RXCHAR);
Ej!N ^8e5O+y$owm7VZ
9w Z eS._#L SetupComm(m_hComm,1024,1024); v V/k8MO.DP^-g
["\+P u{7m
PurgeComm(m_hComm,PURGE_TXCLEAR ¦ PURGE_RXCLEAR);
&w[6O6` |,r4|v ~\8^_ )iW|!v6Q"Jx#g?E
m_hReadCloseEvent = CreateEvent(NULL,TRUE,FALSE,NULL); 5Y-C9j'@^2I.P\A I
if (NULL == m_hReadCloseEvent)
I;R ?1r#hl/|j7gb {
:xPj3F_'d8U t AfxMessageBox(_T("Create read close event failed.")); i+n |t!j n%E+w
return FALSE;
i^p(p_y } Qo:k vz0[ru1b
bir}Ekkawj
m_hWriteCloseEvent = CreateEvent(NULL,TRUE,FALSE,NULL); d%V)hC|w
if (NULL == m_hWriteCloseEvent)
f"F zbF g1N&Na:B {
5XoY F*M \:^-UT AfxMessageBox(_T("Create write close event failed.")); 'Ir)d%?m
return FALSE;
+^2y ~8[7An@'z!zE }
+X/iqh E6o3hu
*x;w#M:f+u m_hReadThread = CreateThread(NULL,0,ReadThreadFunc,this,0,&m_dwReadThreadID); C+SRO*csos%n
if (NULL == m_hReadThread)
R!Guh_a&j { zD/\ P*c
AfxMessageBox(_T("Create read thread failed.")); 2B6a#wP[z-f"f t}
return FALSE; "gj*d%~#wC;@
} \.a&C6ZH"H(T9V

[&F"n6g]5h m_hWriteThread = CreateThread(NULL,0,WriteThreadFunc,this,0,&m_dwWriteThreadID);
"A#J%EzQ7A&@ufv]h if (NULL == m_hWriteThread) !j QT7zYuSZ ]9e
{ J8DVj7j%zV1x"OA s
AfxMessageBox(_T("Create write thread failed."));
~H p&t(S?F[0J return FALSE; K6~(@ bk/n.A(j0Yi
}
%Fw5et%f {(j4T8S return TRUE; *h6r2m [*Ql
}
s6V+h `\-^ //关闭串口
zsH+i2O!v/Gi i void CCSeries::ClosePort()
zP)fy2A4d { _KK#G ECu.p6g0B
if (m_hComm == INVALID_HANDLE_VALUE) 1{ {*^{%@Z\l
{ 0mF)@pl:FI;{$}%Isg
return; *j aH1D'q+^
}
o I K pa!sE#w%h3l5f${
2}nj)Krj CloseReadThread();
+~7H P UP&i'`hG"D CloseWriteThread(); "|~NY oe%jdm
#\1cY.J1H:R2k\q C)A
if (!CloseHandle(m_hComm))
!b%jTf)[ { C6@"h!XXx"B
m_hComm = INVALID_HANDLE_VALUE;
yh+@zB5u^^4_ return; 7c/L _tHS
}
v} ?;W,_vu }
,zwsr@Q:?6H
z O1W;y:\(NEewe BOOL CCSeries::WritePort(const BYTE *buf, DWORD bufLen)
N#j!f(w xDap { C:zWJL g
if (PostThreadMessage(m_dwWriteThreadID,CM_THREADCOMMWRITE,WPARAM(bufLen),LPARAM(buf)))
7tj_k\V/J o^ { %p$i/d+[L1O/W
return TRUE;
*h] Q]cK@6qb } $X&|q!CdO%A
|+x:D/R W(i4k\
return FALSE; xgN!G3[Q
}
'x`0PAs`F7Vs!a(Q
+b?![ii|.|i BOOL CCSeries::SetSeriesTimeOuts(COMMTIMEOUTS CommTimeOuts) py(RZ"rm3x
{ u)uF7}H4\Ip
ASSERT(m_hComm != INVALID_HANDLE_VALUE); Zc8u)U%c!p7t
return SetCommTimeouts(m_hComm,&CommTimeOuts); lg$o(rS ksP8N `O?
}

2008-8-26 16:21 nimabi
// CSeries.h: interface for the CCSeries class. ^']%Y#g"Ic-Tn
//
e*j5M Z*`$QFk //////////////////////////////////////////////////////////////////////
Ba9_@D'}S~ 4| VBT^qS
#if !defined(AFX_CSERIES_H__2DB1AAE2_F6D9_4320_8421_69FAF7A70B87__INCLUDED_) *] X cS]y;?o
#define AFX_CSERIES_H__2DB1AAE2_F6D9_4320_8421_69FAF7A70B87__INCLUDED_
A#kv7qC H1FK"g\
#if _MSC_VER > 1000
h*V^']5p.NFh.j #pragma once \vS2wJ Du"A xb.n
#endif // _MSC_VER > 1000 S"v!_2zg"C/^y;m)~
'syI.u6i
typedef unsigned int UNIT; t6x)j\0@x8YM

,~ z_Y;BV4M typedef void (CALLBACK* ONSERIESREAD)(CWnd*,BYTE* buf,int bufLen);
'^N3Kyg ;n^H,f.T
typedef struct o9EtfR
{
l#En-X&q c BYTE FunNO; //功能码
7_Iz5H%B-m-} BYTE StartNO; //开始变量号
DJ#bi!w,Cs@p4CT:O BYTE Length; //长度 !Bb\m5h OU
int  Data[8]; //要传输的数据
7kr K\K'B //BYTE Coefficient; //系数 3{$gE;wC!u5[
    //int  OffSet; //偏移量
+kk`*Pcr3{8A![ BYTE ReturnLen; //返回长度
QYfi`~ }STRBUF;
Y0x^0}5_8Q*{4B class CCSeries  
[#e)@c+v7jDO I7^ {
h0{mx~3L public:
}$o3U ^ j].gg,t CCSeries();
)upE W.dD virtual ~CCSeries();
j O0g2e,]q;z:^
:Fyubi"J&f'P6? private: )K*p5Z)FcS'T8~
//关闭写线程 F.^s cp%{;r
void CloseWriteThread();
P fy _b;q~\1t |QA //关闭读线程
(e%E.HAn:U(@(m void CloseReadThread(); 4tsie7[6B%im+s
//串口写线程函数
FQ.U9WL h%Q static DWORD WINAPI WriteThreadFunc(LPVOID lparam);
P^V7r9{Y^qV //串口读线程函数 sb9c#{/W^+WUy#]I
static DWORD WINAPI ReadThreadFunc(LPVOID lparam);
F;H3F5d B //向串口写入数据
-d0tb{$w*` static BOOL WritePort(HANDLE hComm,const BYTE *buf,DWORD bufLen); 8R\ zd,A/t!J J

?q.`(]4U/g+g%nM //已打开的串口句柄 9lR.f_T*G{O
HANDLE m_hComm;
a{hl@8T CWnd* m_pPortOwner;
kW5?``k$v )C,j6x1c-Uq2v
//读写线程句柄
(B+}O1`&b'{*C HANDLE m_hReadThread; V!S%Cl Q"Exc4EL/miq
HANDLE m_hWriteThread; #P s"[4`3Q

+n#VPv7N \ //读写线程ID标识 Y;AAC6E-V_(]
DWORD m_dwReadThreadID; /Ncum o^3[d
DWORD m_dwWriteThreadID; MN3P/l'dO4[0Ge
\!p|*S aX]\
//读写线程退出事件
V'~re3Ps%aN HANDLE m_hReadCloseEvent; #Y-l:l'?7E u/HOdh
HANDLE m_hWriteCloseEvent;
!U fQsX(z2_
&Do$pxUHo~ public:
8{b!PV+\-\*V CString m_strRecvData; )XF$OE+q,x a7_"T&K
BOOL SetSeriesTimeOuts(COMMTIMEOUTS CommTimeOuts); b0E:s[ y]K g`
BOOL WritePort(const BYTE *buf,DWORD bufLen);
F*V)S ?r1^Q} void ClosePort();
#Z7{/fd+`&[2~"~ //以指定的参数打开串口 R9Y'HE+e3z ~
BOOL OpenPort(CWnd* pProtOwner,UNIT portno = 1,UNIT baud = 19200,UNIT parity = NOPARITY,UNIT databits = 8,UNIT stopbits = 0);
Y |;|4k~qK8Y y //回调事件 3pkDK'^6V-|"R
ONSERIESREAD m_OnSeriesRead; ![qc5R:SeA
//灭菌参数集合
_-}$~L$~+F1E?^F static BYTE auchByte[256]; g:^7T;F+f
static int  auiWord[256];
,fU\n~ //读写队列
S:^7Gny/R$D-@ static STRBUF WriteBuf[5]; @k7Mv7@:w7D
static STRBUF ReadBuf[50]; J4X*O'Y t vc
//读写缓冲区头尾指针 /oh"It qc
    static BYTE WriteBufFront;
;u-c],M^"a static BYTE WriteBufRear; %f$]6ynZ Zu
static BYTE ReadBufFront;
gv'q:p3A$m8VW z static BYTE ReadBufRear;
"Hew6CIS-m8]R| //入队操作
0QnO,ePP'rfTV static void EnQueue(BYTE FunNO,BYTE StartNO,BYTE Length,int *Data,BYTE PossessionMark); nLac"`C]S W/et
static BYTE CalcReturnLen(BYTE FunNO,BYTE Len);
c2Rd_Aj9p!z)N3dL#s
@ JE5B9Z static char NSYL[20]; r}t!kY dmDFA
static char NSWD[20];
T)wN)BPVY]$JC static char JCYL[20]; N%m([ P Wy$@N
static char JCWD[20]; #ksD#~feQG
static char DateTime[30]; Dg6^LV3F[-{;f
};
*U1N^1g8a gx/h`1bo'l z
#endif // !defined(AFX_CSERIES_H__2DB1AAE2_F6D9_4320_8421_69FAF7A70B87__INCLUDED_)

2008-8-26 16:21 nimabi
这我通讯部分的全部代码?请大家帮我看看是那里的问题!

2008-8-26 16:22 匿名
晕啊,lz
$_5b6u&wY:I 你先只读串口,不写。看出问题不。
i5@+C_[h |] 然后再看只写串口,不读。看出问题不。
v H]4}!d;n6X
qh6jq s 要是单个跑可以,同时跑不行,就是同步处理出问题了。单看代码好累得。

2008-8-26 16:22 匿名
楼主,你怎么老变身啊,高手!!

2008-8-26 16:22 匿名
我也是前两天解决这个问题的,代码其实都差不多,只是我只有读,没有写.
'YZ MzNmL 可能就像楼上说的,你用单个来测试看看

2008-8-26 16:22 匿名
if (WaitForSingleObject(ceSeries- >m_hReadCloseEvent,500) == WAIT_OBJECT_0)
e8DU;z.m6bx ]0w zh/j2v4\-~ aDY$W
等待退出的时间太长了,有个1个毫秒就够了。
4x^G6D8Lnkc"m$Xn y$F'_XtY9S_/C
明天再来看吧。代码好像有问题啊 Cp3AF+p5}6eG8}oADK
//清空串口 ha5z}qXB4d
PurgeComm(ceSeries- >m_hComm,PURGE_RXCLEAR  ¦ PURGE_TXCLEAR);
}lJ?Ln aYX'o*jS 每读一次串口都要清一下吗?

2008-8-26 16:23 nimabi
大家帮忙想想办法,

2008-8-26 16:23 匿名
兄弟,你读串口和写串口的线程单独分开跑测试情况怎么样了。
8FB#b%@s"g6L 我没有你的设备只能靠你的反馈来判断啊。
Lh;@ cWJ k.W;v 你的问题可能不是原则上的,需要细心调试。

2008-8-26 16:23 nimabi
我用2,3 短接的通讯线测试的时候,我的程序没问题!

页: [1] 2
查看完整版本: 串口通讯死机现象


Powered by Discuz! Archiver 5.5.0  © 2001-2006 Comsenz Inc.