注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

沙粒的博客

 
 
 

日志

 
 

pc_c51:pc端接收数据  

2014-12-13 23:20:54|  分类: 通信 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

一、功能:

c51发送数据,pc接收并显示。

二、通信协议,4个字节,开始+类型+设备号+数据

1、控制信号协议:

0x01+’K’+设备号+数据。

设备号说明:

字符 ’1’ 表示1号设备。

字符 ’2’ 表示2号设备。

数据说明:

字符 ’O’ 表示设备合闸。

字符 ’C’ 表示设备跳闸。

2、数据通信协议

0x01+’S’+设备号+数据。

三、几个关键函数代码

1、串口配置:opencomm()

2、接收线程:threadfun(LPVOID lpParam )

3、串口事件处理:ProcessNotification()

4、接收数据处理:processData()

5、读串口:ReadComm()

四、函数代码:

1BOOL CTestDlg::opencomm()

{

     //如果串口打开,关闭

     if(m_hcom!=NULL)

            CloseHandle(m_hcom);

 

     //创建串口

     m_hcom=CreateFile(

            "COM4",

            GENERIC_READ | GENERIC_WRITE,

            0, //不共享

            NULL,  //

            OPEN_EXISTING,  //

            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, //异步操作

            NULL);

     //

     if(m_hcom==INVALID_HANDLE_VALUE)

     {

            MessageBox("CreateFile error");

            return false;

     }

 

     //-----配置串口

     //定义通信设备

     DCB dcb;

     //获取串口配置,成功返回非零

     BOOL gcs=GetCommState(m_hcom,&dcb);

     if(gcs==0)

     {

            MessageBox("GetCommState err");

 

            return false;

     }

 

     //修改串口参数

     dcb.BaudRate=9600;

     dcb.ByteSize=8;

     dcb.Parity=NOPARITY;   //无校验

     dcb.StopBits=ONESTOPBIT;  //1位停止位

 

     //设置串口设备参数

     BOOL scs=SetCommState(m_hcom,&dcb);

     if(scs==0)

     {

            MessageBox("SetCommState err");

            return false;

     }

 

     //设置通信事件,EV_RXCHAR 事件

     BOOL scm=SetCommMask(

            m_hcom,

            EV_RXCHAR);

     if(scm==0)

     {

            MessageBox("SetCommMask err");

            return false;

     }

 

     //创建线程,由线程函数完成读串口,

     m_hthread=CreateThread(

            NULL,

            0,

            (LPTHREAD_START_ROUTINE)threadfun,  //线程函数

            this,  //参数为 CScmDlg 类指针

            CREATE_SUSPENDED , //线程挂起运行,ResumeThread函数启动

            NULL);

     if(m_hthread==NULL)

     {

            MessageBox("CreateThread error");

 

            //串口未连接

            m_bconnected=0;

 

            return false;

     }

     else

     {

            //启动线程

            ResumeThread(m_hthread);

 

            //串口连接状态

            m_bconnected=1;

            //

     }

     return true;

 

}

2//

DWORD WINAPI threadfun(LPVOID lpParam )

{

     //获取类指针,用于调用类变量

     CTestDlg* pdlg=(CTestDlg*)lpParam;

 

     //串口错误标识

     DWORD dwErrorflag;

     //串口状态信息结构,

     COMSTAT cs;

 

     //事件掩码

     DWORD dwMask;

     //实际传送的字节数

     DWORD dwTrans;

 

 

 

 

     //定义异步结构

     OVERLAPPED olap;

     memset(&olap,0,sizeof(OVERLAPPED));

     //异步操作要求,事件手动置位,初始nonsignaled 状态

     //程序结束关闭,关闭位置 else 函数结束时。

     //

     olap.hEvent=CreateEvent(NULL,true,false,NULL);

     if(olap.hEvent==NULL)

     {

            AfxMessageBox("in threadfun, CreateEvent error");

            return false;

     }

 

     //如果串口连接

     while(pdlg->m_bconnected)

     {

            //清除串口错误,获取串口信息

            BOOL cce=ClearCommError(

                   pdlg->m_hcom,

                   &dwErrorflag,

                   &cs);

 

            //如果串口有接收到的数据,调用函数执行串口读操作

            if(cs.cbInQue)

            {

 

                   //调用函数,读串口

                   //参数表示事件类型

                   pdlg->ProcessNotification(EV_RXCHAR,0);

 

                   continue;

 

            }

 

            //如果串口没有收到数据,等待串口事件发生

            //表示事件代码

            dwMask=0;

 

    

 

            //等待串口事件,异步操作,函数马上返回,

            //函数返回0GetLastError函数返回ERROR_IO_PENDING,表示异步操作

            //异步操作要求,pdlg->m_hcom设置了FILE_FLAG_OVERLAPPED

            //要求olap.hEvent事件为手动,无信号状态

            //olap.hEventd 的变化:

            //函数返回前,系统将olap.hEventd 设为nonsignaled,

            //当等待的事件发生时,系统将olap.hEventd 设为signaled,

            BOOL wce=WaitCommEvent(

                   pdlg->m_hcom,

                   &dwMask,  //输出事件代码

                   &olap);  //overlapped 结构

            //异步操作,或函数出错

            if(wce==0)

            {

                   //异步操作

                   if(GetLastError()==ERROR_IO_PENDING)

                   {

                          //等待WaitCommEvent 函数异步操作的结果

                          //bWait=true,WaitCommEvent等待的事件发生后,此函数才返回

                          //注意此语句与 WaitForSingleObject语句

                          GetOverlappedResult(

                                 pdlg->m_hcom,

                                 &olap,

                                 &dwTrans, //实际传送的字节数

                                 true);

 

                   }

                   else //出错

                   {

                          //关闭事件句柄

                          CloseHandle(olap.hEvent);

                          return false;

                   }

            }

     }

     //关闭事件句柄

     CloseHandle(olap.hEvent);

 

     return true;

}

3BOOL CTestDlg::ProcessNotification(WPARAM wparam, LPARAM lparam)

{

     int k=0;

     const DWORD rlength=1024;

     char buf[rlength];

     DWORD length;

     //审核,如果串口无效或参数不是EV_RXCHAR,函数返回

     if(!m_hcom || (wparam & EV_RXCHAR)!=EV_RXCHAR )

     {

            MessageBox("no EV_RXCHAR");

            return true;

     }

 

 

 

     //读串口

     length=ReadComm(buf,rlength);

 

     if(length!=4)

            return false;

 

 

 

 

 

 

 

 

     CString str;

     str.Format("%d",length);

 

 

     //添加到

     m_strRx+=buf;

     m_strRx+="  ";

     m_strRx+=str;

     m_strRx+="  ";

 

 

     GetDlgItem(IDC_EDIT_receive)->SetWindowText(m_strRx);

 

     //处理接收数据,显示对应设备数据

     processData(buf,length);

    

    

    

    

    

     return true;

 

}

 

4

void CTestDlg::processData(char* buf,DWORD length)

{

     CString str1;

     str1="";

 

     if(buf[0]==0x30 && buf[1]=='d')

     {

           

           

                  

           

            if(buf[2]=='1')

            {

                  

                   str1="equipment 1: ";

                   str1+=buf[3];

 

                   GetDlgItem(IDC_equip)->SetWindowText(str1);

 

            }

            if(buf[2]=='2')

            {

                   str1="equipment 2: ";

                   str1+=buf[3];

           

                   GetDlgItem(IDC_equip)->SetWindowText(str1);

            }

            if(buf[2]=='3')

            {

                   str1="equipment 3: ";

                   str1+=buf[3];

           

           

                   GetDlgItem(IDC_equip)->SetWindowText(str1);

            }

            if(buf[2]=='4')

            {

                   str1="equipment 4: ";

                   str1+=buf[3];

                  

                  

                   GetDlgItem(IDC_equip)->SetWindowText(str1);

            }

           

     }

 

}

 

 

5

DWORD CTestDlg::ReadComm(char* buf,DWORD dwlength)

{

     //定义变量

     DWORD dwError; //串口错误信息

     COMSTAT comstat; //串口状态信息结构

 

     DWORD length; //读取串口字节数

 

     //GetOverlappedResult函数传送的字节数

     DWORD laplength;

 

 

 

     int k1,k2,flag;

     flag=0;

 

     do{

            if(flag==0)

            {

                   ClearCommError(m_hcom,&dwError,&comstat);

                   k1=comstat.cbInQue;

                  

                   Sleep(20);

                  

                   ClearCommError(m_hcom,&dwError,&comstat);

                   k2=comstat.cbInQue;

 

                   flag=1;

            }

            else

            {

                   k1=k2;

                   Sleep(20);

                   ClearCommError(m_hcom,&dwError,&comstat);

                   k2=comstat.cbInQue;              

            }

           

 

     }while(k1!=k2);

 

     ClearCommError(m_hcom,&dwError,&comstat);    

 

     //关键语句

     //获取2参数中较小值,用于返回串口缓存中实际字节数

     length=min(dwlength,comstat.cbInQue);

 

     //

     memset(buf,0,dwlength);

 

     //读串口,此操作是读缓存,不需要异步等待语句

     //函数立即返回1.

     flag=ReadFile(m_hcom,buf,length,&length,&m_osRead);

     if(flag==0)

     {

            if(GetLastError()==ERROR_IO_PENDING)

            {

                   //等待WaitCommEvent 函数异步操作的结果

                          //bWait=true,WaitCommEvent等待的事件发生后,此函数才返回

                          //注意此语句与 WaitForSingleObject语句

                          GetOverlappedResult(

                                 m_hcom,

                                 &m_osRead,

                                 &laplength, //实际传送的字节数

                                 true);                

            }

     }

 

     return length;

 

}

  评论这张
 
阅读(269)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017