WinCE5.0平台下的Moxa DA66x设备应用开发心得

news/2024/7/4 23:31:34

最近金日隧道广告系统的通信系统要升级,用MoxaDA66x设备取代原先的Moxa5630通信模块,由于DA66x内嵌了WinCE5.0系统,系统的功能可以有很大的发挥余地。

DA66x这款产品功能很强,可以说WinCE5.0在工业通信领域被用到了极致(210/ 100M Tcp/IP通信口,16+1个高波特率串口)我更为喜欢的是,它给PC机提供了多种渠道去控制该设备,内建了Web服务器,可以通过网页进行各种配置,开启了ftp服务,可以通过ftp上传下载文件,此外我更为喜欢的是提供了Pocket CMD 5.0(如下图),可以通过超级终端进行控制(和DOS界面没有什么区别,很早的时候,我开发AB PLC的一个接口板程序时,就是用到类似的东西)。

 

 

通过Moxa提供的SDK,我还是学了不少.net的技术,比如静态构造函数的使用,以前是不知道的,所以以后直接使用静态函数的时候,知道在哪里初始化变量了(题外话:在msdn查静态构造函数的时候,意外的发现在VS2005目录里有好东西,VS2005安装目录/VC#/Specifications/2052下面有两个中文版的C#规范的word文件,很是详细,值得一看)。此外还学到了向API函数传结构体的技术,如:

[StructLayout(LayoutKind.Sequential)]    //该结构体变量内存连续存储

        public struct LCM_POS

        {

            [MarshalAs(UnmanagedType.U1)]        //无符号字节变量

            public byte x;

            [MarshalAs(UnmanagedType.U1)]

            public byte y;

     }

 

          mxdevice.LCM_POS pos = new mxdevice.LCM_POS();

          pos.x = x;

          pos.y = y;

          IntPtr lpPos = Marshal.AllocHGlobal(Marshal.SizeOf(pos)); //分配空间

      Marshal.StructureToPtr(pos, lpPos, false);           //获取结构体指针

      mxdevice1.IoControl(mxdevice.IOCTL_LCM_GOTO_XY, lpPos);  

有时间这方面的技术,我在专门论述。

 

由于DA66x没有提供触摸屏,只是提供了一个16*2LED显示屏和4个按钮,所以功能控制比较麻烦,值得提出的时,moxa公司提供的SDK还是有bug的,比如下面的一个函数:

    public bool IoControl(uint code, ref byte input, ref byte output)

        {

            int num1 = 0;

            byte num2 = 0;

            if (!DeviceIoControl(hLCMPort, IOCTL_KEYPAD_GET_DOWN_STATE, (void*)0, 0, pkey, sizeof(UCHAR), &dwBackSize, NULL))

     }

     上面的output参数竟然没用,幸好moxadll没有加密可以获得源码,否则我修改起来就麻烦了。

此外DA66x系列的设备和UC7400的设置共用一个.net开发包,并且DA66x没有LCD显示和按键的控制(该需求反馈到Moxa后,据说近期就要发布相关代码),还好,moxa发过来LCMEVC程序)的源码,可以把相关的EVC代码转换为.net代码。

Moxa最大的设计败笔(个人认为)就是按钮和LCD的驱动设备为同一个“LCM1:”,按钮和LCD就不能独立设计,否则通过线程不断检查按钮状态时会和显示冲突。没有办法,只好设计在一起了,我自己开发一个DA66x.net驱动,效果还不错(有时间在设计一个二级菜单和多页文本显示的功能)。此外我还是看看moxa提供的开发包是怎么设计的吧,说不定又学到不少东西。

下面是我自己开发的相关代码,有类似需求的朋友可以参考一下:

// LCD显示&按键控制
     public   class  LCMKEY
    {
        
private  mxdevice mxdevice1;
        
private  Thread trdKeypadlisten;
        
private   bool  bStop;
        
public   static   int  Key  =   0 ;    // 按键信息
        
        
public  LCMKEY()
        {         
        }

        
public   void  Init()
        {
            mxdevice1 
=   new  mxdevice( " LCM1: " );
            mxdevice1.Open();
            
this .bStop  =   false ;

            
this .trdKeypadlisten  =   new  Thread( new  ThreadStart( this .ThreadTask));
            
this .trdKeypadlisten.Priority  =  ThreadPriority.Normal;
            
this .trdKeypadlisten.Start();
        }

        
public   void  Exit()
        {
            mxdevice1.Close();
            
try
            {
                
if  ( ! this .bStop)
                {
                    
this .bStop  =   true ;
                }
                
this .trdKeypadlisten  =   null ;
            }
            
catch
            {
                
return ;
            }          
        }
         
~ LCMKEY()
        {
            Exit();
        }
        
// 光标控制
         public   void  Cursor( bool  bFlag)
        {
            
byte  num  =   0 ;
            mxdevice1.IoControl(bFlag 
?  mxdevice.IOCTL_LCM_CURSOR_ON : mxdevice.IOCTL_LCM_CURSOR_OFF,  ref  num);  // mxdevice.IOCTL_LCM_BLINK_ON
        }
        
// 清屏
         public   void  Clear()
        {
            
byte  num  =   0 ;
            mxdevice1.IoControl(mxdevice.IOCTL_LCM_CLEAR, 
ref  num);
        }
        
// 光标定位
         public   void  GotoXY( byte  x,  byte  y)
        {
            mxdevice.LCM_POS pos 
=   new  mxdevice.LCM_POS();
            pos.x 
=  x;
            pos.y 
=  y;
            IntPtr lpPos 
=  Marshal.AllocHGlobal(Marshal.SizeOf(pos));
            Marshal.StructureToPtr(pos, lpPos, 
false );
            mxdevice1.IoControl(mxdevice.IOCTL_LCM_GOTO_XY, lpPos);
        }
        
// 文本显示
         public   void  Show( string  text,  byte  x,  byte  y)
        {
            
int  num  =   0 ;
            GotoXY(x, y);
            mxdevice1.WriteDev(Encoding.Default.GetBytes(text), text.Length, 
out  num);
        }
        
// 文本显示
         public   void  Show( string  text1,  string  text2)
        {           
            
// 清屏
            Clear();
            
// 写第一行
            Show(text1,  0 0 );
            
// 写第二行
            Show(text2,  0 1 );          
        }           

        
// 按钮控制
         protected   virtual   void  OnKeyClick( int  e)
        {
            
if  ( this .KeyClick  !=   null )
            {
                
this .KeyClick( this , e);
                Key 
=  e;
            }
        }
        
// 按钮监控
         private   void  ThreadTask()
        {
          
            
byte  pTemp  =   0 , pKey  =   0 ;
            
do
            {
                
if  (mxdevice1.IoControl(mxdevice.IOCTL_KEYPAD_GET_MENU_STATE,  ref  pTemp,  ref  pKey))
                {
                    
if  (pKey  ==   1 )
                    {
                        OnKeyClick(
1 );
                    }
                }
                
if  (mxdevice1.IoControl(mxdevice.IOCTL_KEYPAD_GET_UP_STATE,  ref  pTemp,  ref  pKey))
                {
                    
if  (pKey  ==   1 )
                    {
                        OnKeyClick(
2 );
                    }
                }
                
if  (mxdevice1.IoControl(mxdevice.IOCTL_KEYPAD_GET_DOWN_STATE,  ref  pTemp,  ref  pKey))
                {
                    
if  (pKey  ==   1 )
                    {
                        OnKeyClick(
3 );
                    }
                }
                
if  (mxdevice1.IoControl(mxdevice.IOCTL_KEYPAD_GET_SELE_STATE,  ref  pTemp,  ref  pKey))
                {
                    
if  (pKey  ==   1 )
                    {
                        OnKeyClick(
4 );
                    }
                }
                Thread.Sleep(
100 );
            }
            
while  ( ! this .bStop);
        }    
        
//  Events
         public   event  KeyClickEventHandler KeyClick;
    }




http://www.niftyadmin.cn/n/3655762.html

相关文章

介绍 js 有哪些内置对象?

涉及的知识点 js 中的内置对象主要指的是在程序执行前存在全局作用域里的由 js 定义的一些全局值属性、函数和用来实例化其他对象的构造函 数对象。一般我们经常用到的如全局变量值 NaN、undefined,全局函数如 parseInt()、parseFloat() 用来实例化对象的构 造函数…

Windows Vista不兼容VS2005(需打补丁)

在Windows Vista平台上直接安装VS2005,没有想到安装程序直接就提示Vista与VS2005存在已知的兼容问题,看来需要打SP1补丁(该补丁虽然下载了,但是在XP安装巨慢,不知道在vista上品行如何),此外SQL Server 2005…

解构赋值笔记

数组的解构赋值 let arr [1,2,3,4,5] let [item1,item2] arr console.log(item1,item2) // 1,2 数据2之后的345被垃圾回收机制回收 let [item1, item2,...list] arr console.log(list) // 3,4,5 利用... 把其他的数据赋值到list上 ""..."" 用于取出…

Office 2007 中文版快速一览

Office2007中文版同样是从MSDN下载的,使用起来和office2003以前版本有很大不同,绝对有震撼效果(相比Windows Vista 之于 Windows XP还要强),UI设计的效果和理念,绝对在业界又掀起一股仿制狂潮!这…

Callback 异步操作

1. 什么是回调地狱? 在业务逻辑中为了实现业务功能,经常需要函数层层嵌套的回调函数,如果嵌套过多,极大影响代码可读性和逻辑,这样的场景叫做回调地狱 var sayhello function (name, callback) {setTimeout(function () {console.log(name);callback();}, 1000); } sayhell…

Windows Vista 中文版的兼容性

想把工作平台逐渐有Windows XP 转移 到windows Vista 上来,所以在该平台上开始安装一些Windows XP平台上的程序,目前的情况如下:1、紫光拼音3.0 - 安装成功 2、瑞星杀毒2007 - 安装成功 3、瑞星防火墙2007 …

Windows Vista 中文版快速一览

Windows Vista 中文版发布了, 实在等不及微软的MSDN光盘了,只好在网上下载了2.4G左右的Vista中文版安装光盘,我的机器显卡都有些落后,特效是无法运行了,不过整体感觉还是满好的,比Windows XP要好一个档次。…

DLL(MFC)通过Window消息向C#程序传递数据

这是我在用C#开发IOServer遇到的一个问题,该程序需要用到原先用MFC开发的DLL,最大问题是该dll运行过程中的一些信息,通过window消息向指定的hwnd(窗体句柄)发送数据。数据的指针放在WParam参数里&#xff0…