在vs2008编写基于MFC的串口通信,从STM32实时读取数据,遇到读写冲突问题

zyqaly 2017-02-16 05:34:10
这是串口响应函数,在响应函数中开了个线程,用于处理接受到的数据,数据是一个帧头6.000000后面带四路数据,想要将四路数据分别赋给AD_A,AD_B,AD_C,AD_D四个变量,不知道这样开线程可以?串口读数据的线程和数据处理的线程能不断运行?我想的是串口读数据也是一个线程,那他在他的时间片内运行,时间到,然后调用线程函数运行,线程函数的时间片到,再轮到串口线程运行,我是刚开始写,查了很多资料,也不知道这样到底对不对,希望有人帮帮我,真的卡了好久了。

void CScomDlg::OnComm()
{
// TODO: 在此处添加消息处理程序代码
//################################################################################
hThread1=CreateThread(NULL,0,DataHander,NULL,0,NULL);
CloseHandle(hThread1);

g_hEvent=CreateEvent(NULL,FALSE,FALSE,"tickets");//无信号状态
if(g_hEvent)
{
if(ERROR_ALREADY_EXISTS==GetLastError())
{
AfxMessageBox("有一个线程在运行");
return;
}
}
SetEvent(g_hEvent);
CloseHandle(g_hEvent);

VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
CString strtemp;
if(m_ctrlComm.get_CommEvent()==2) //事件值为2表示接收缓冲区内有字符
{
////////以下你可以根据自己的通信协议加入处理代码

Global::DataRuning=1;
variant_inp=m_ctrlComm.get_Input(); //读缓冲区
safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
len=safearray_inp.GetOneDimSize(); //得到有效数据长度
for(k=0;k<len;k++)
safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组
for(k=0;k<len;k++) //将数组转换为Cstring型变量
{
BYTE bt=*(char*)(rxdata+k);//字符型
strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放
////此处编译有错误,可在项目属性->配置属性->常规里将“字符集”改为使用多字节字符集即可
strtemp1+=strtemp;
m_strRXData+=strtemp; //接受的传感器的数据,加入接收编辑框对应字符串

}

}
else
Global::DataRuning=0;
UpdateData(FALSE); //更新编辑框内容

}


这是线程响应函数
DWORD WINAPI DataHander(LPVOID lpParameter)
{
while(true)
{
WaitForSingleObject(g_hEvent,INFINITE);

CString s="6.000000";
CString tt=Global::strtemp1;
int n=2;
int N=80;
CString head="0";
for (unsigned int i=0;i<N;)
{
head=tt.Mid(i,8);//MID(a,b)函数,从a位起截取b位
if (!(head.Compare(s)))
{
i+=8;
Global::ad_a=tt.Mid(i,8);
Global::AD_A= atof( Global::ad_a);

i+=8;
Global::ad_b=tt.Mid(i,8);
Global::AD_B= atof( Global::ad_b.GetBuffer());

i+=8;
Global::ad_c=tt.Mid(i,8);
Global::AD_C= atof( Global::ad_c.GetBuffer());


i+=8;
Global::ad_d=tt.Mid(i,8);
Global::AD_D= atof( Global::ad_d.GetBuffer());
i=i+8;

}
else
i++;



if(Global::DataRuning=1)//如果缓冲区有数字,证明数据在更新

{
if(i==72)
{
N=80*n;
n++;
}
}
SetEvent(g_hEvent);
}
}

return 0;

}
...全文
268 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
zgl7903 2017-02-17
  • 打赏
  • 举报
回复
遇到冲突时 结合调用堆栈调试解决之 个人感觉 处理和数据分配其实在接收事件处理中完成就可以了 safearray_inp.GetElement(&k,rxdata+k); 这里可能会存在越界
走好每一步 2017-02-17
  • 打赏
  • 举报
回复
没什么耐心看程序,解决思路是 g_buf1 g_buf2 g_buf2Len thread1 { Sleep(10); len = GetDataFromSTM32(g_buf1) if (len > 0) { 进入临界区 Copybuf(g_buf1, g_buf2); g_buf2Len = len; 离开临界区 } } thread2 { Sleep(10); 进入临界区 if g_buf2Len == 0 return; Handle(g_buf2); g_buf2Len = 0; 离开临界区 }
zyqaly 2017-02-16
  • 打赏
  • 举报
回复
都没有人??

15,471

社区成员

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

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