注册名:

密码:

个人注册

企业注册

商务申请

商务管理平台

企业管理平台

个人管理平台

我的工控博客

中国工控网www.chinakong.com

首页 | 新闻中心 | 工控论坛 | 经验视点 | 工控商务 | 电气手册 | 工控博客 | 招聘求职 | 网上调查 | 企业中心 | 供求信息 | 资料中心 | 工控书店

所在位置:工控论坛 -- 工控机论坛 -- 工控机论坛(非专题) -- 结构与配置

中国工控网搜索:

 登陆:密码:  注册  密码

搜索:

工控机论坛(非专题)分类  

全部论题

结构与配置

数据 I/O

编程与维护

应用方案

发表人:emtronix 发表时间:2010/12/14 21:18:00  

 

 本栏论题: RS485接口通讯的WinCE编程要点  [1318]

    在工业控制场合,RS485总线因其接口简单,组网方便,传输距离远等特点而得到广泛应用。RS485和RS232一样都是基于串口的通讯接口,数据收发的操作是一致的,所以使用的是同样WinCE的底层驱动程序。但是它们在实际应用中通讯模式却有着很大的区别,RS232接口为全双工数据通讯模式,而RS485接口为半双工数据通讯模式,数据的收发不能同时进行,为了保证数据收发的不冲突,硬件上是通过方向切换来实现的,相应也要求软件上必须将收发的过程严格地分开。WinCE是一个多线程实时操作系统,RS232通信数据收发可在不同线程中同时进行,而对于RS485就不能采用这种方式,必须按照一定的流程来实现RS485所要求的通讯过程。大多数的RS485通讯采用主从通讯方式,在本文中将以电力系统中常用的DL/T 645多功能电能表通信规约为例,来说明RS485半双工通讯的WinCE编程要点。
    本例通过封装两个类来实现DL645通信规约,一、用于串口通信的CESerial类,完成打开、关闭串口,收发串口数据等功能。二、实现DL645规约链路层的类DL645_LCP,它提供设置通信地址,超时时间等信息,并完成通信帧的打包、解包、错误较验、数据帧收发的功能。
    基于485半双工通信的特点,使用一个函数Transmit()来完成数据收发。在调用Transmit()函数发送数据后,程序并不立即返回,而是等待数据接收。一个完整的数据发送\接收过程如下:
    ·应用层调用DL645_LCP类的Transmit()方法,并将发送的数据传递给Transmit()。
    ·在Transmit()方法中对数据打包,增加帧起始符,帧结束符,校验码等信息,使其符合DL645规约。
    ·调用串口通信CESerial类的WritePort()方法函数,发送一帧数据。
    ·等待数据接收。遇下列情况之一时,函数返回:1、接收到一帧完整数据,2、接收超时,3、较验出错,4、通信出错。
    下面是Transmit()函数的源代码:
    int DL645_LCP::Transmit( LPSTR pDat, int DLen )
    {
    int i1, i2;
    UCHAR WBuf[MaxWDatLen];
    // fill write data
    for( i1=0; i1<4; i1++ )
    WBuf[i1] = 0xFE;
    WBuf[i1] = 0x68;
    i1++;
    memcpy( &WBuf[i1], &m_LAddr, 6 );
    i1 += 6;
    WBuf[i1] = 0x68;
    i1++;
    memcpy( &WBuf[i1], pDat, 2 );
    i1 += 2;
    for( i2=2; i2 < Dlen; i2++)
    {
    WBuf[i1] = pDat[i2] + 0x33;
    i1++;
    }
    WBuf[i1] = GetCS( &WBuf[4], i1-4 );
    i1++;
    WBuf[i1] = 0x16;
    i1++;
    // write data
    m_nDatLen = 0;
    m_nDatErrFlg = 0;
    m_nUserDatLen = 0;
    m_state = RevStateIDLE;
    //发送一帧数据
    ceSer.WritePort( (LPSTR)WBuf, i1 );
    SetTimeOut( m_dwTimeOut );
    //等待数据接收
    for(;;)
    {
    if( IsTimeOut() )
    return ErrTimeout; //接收超时返回
    else if( m_nDatErrFlg == 1 )
    return -2; //数据出错返回
    else if( m_state == RevStateEND ) //数据接收完成返回
    {
    memcpy( pDat, &RBuf[8], m_nDatLen-8-2 );
    return m_nUserDatLen;
    }
    else
    {
    Sleep( 5 );
    }
    }
    }
    数据接收时,CESerial类的中断处理函数收到数据,直接调用DL645_LCP类中的Receive()方法,在Receive()函数中完成一帧数据的解包工作。
    void DL645_LCP::Receive( )
    {
    UINT i, i1;
    if( m_nDatLen <= MaxRDatLen )
    {
    for( i=0; i< FONT>
   
    {
    SetTimeOut( m_dwTimeOut );
    RBuf[m_nDatLen] = (unsigned char)ceSer.DatBuf[i];
    switch( m_state )
    {
    case RevStateIDLE:
    if( RBuf[m_nDatLen]==0x68 )
    {
    m_state = RevStateSTART;
    m_nDatLen++;
    }
    break;
    case RevStateSTART:
    m_nDatLen++;
    if( m_nDatLen==7 ) m_state = RevStateADDR;
    break;
    case RevStateADDR:
    if( RBuf[m_nDatLen]==0x68 )
    {
    m_state = RevStateSTART1;
    m_nDatLen++;
    }
    break;
    case RevStateSTART1:
    m_nDatLen++;
    m_state = RevStateCTRL;
    break;
    case RevStateCTRL:
    m_nUserDatLen = RBuf[m_nDatLen];
    if( m_nUserDatLen==0 ) m_state = RevStateDATA;
    else m_state = RevStateDLEN;
    m_nDatLen++;
    break;
    case RevStateDLEN:
    m_nDatLen++;
    if( m_nDatLen==(10+m_nUserDatLen) )
    m_state = RevStateDATA;
    break;
    case RevStateDATA:
    m_state = RevStateSUM;
    if( GetCS( RBuf, m_nDatLen)!= RBuf[m_nDatLen] )
    m_nDatErrFlg = 1;
    m_nDatLen++;
    break;
    case RevStateSUM:
    if( RBuf[m_nDatLen]==0x16 )
    {
    m_nDatLen++;
    for( i1=0; i1
    RBuf[10+i1] -= 0x33;
    m_state = RevStateEND;
    }
    break;
    default:;
    }
    }
    }
    else m_nDatErrFlg = 1;
    }
    利用本文提供的例程,在DL645_LCD类上做相应的修改,可方便的实现其它的485通信规约。
   
   
   

如果要回复本栏论题,请首先中国工控网www.chinakong.com

·如果你已经是中国工控网www.chinakong.com成员,请直接登录。

·如果你还不是中国工控网www.chinakong.com成员,请首先注册,注册为免费!

注册名:

密  码:

           注册中国工控网www.chinakong.com
           忘记密码

关闭该窗口

关于我们     免责声明     服务项目     广告联系     友情链接     联系方式     意见反馈     设为首页     加入收藏

 ©2023-2025 中国工控网(www.chinakong.com) 版权所有 豫ICP备17046657号

管理员信箱:chinakong98@163.com  服务热线:13525974529

洛阳博德工控自动化技术有限公司

中国    洛阳