使用pcomm.dll控制道闸开关

最近给驾校做一个考场安检验证的程序。其中有一步就是经过指纹验证后,需要开道闸允许考生进入考试区域。

之前没有串口编程经验。大概搜了一下,了解到pcomm.dll提供了一套接口,方便基于串口做开发。下面就说一下整个过程的粗浅应用。虽然应用不够深入,但是基本流程是想通的。这里姑且把使用过程遇到的问题,梳理一遍,也算是基于串口编程的入门。

  • 准备

一些常识性的东西,放到最后作为附注。先把实用的主要的内容展示出来。

  • 硬件设备提供的参数

通讯协议

  • 硬件协议

通讯信号:RS485,半双工

通讯波特率:9600bps

起始位:1位  

停止位:1位

数据位长:8位数据位

奇偶校验位:无

扫描二维码关注公众号,回复: 2708568 查看本文章
  • 帧协议

1.上位机发送帧格式:同步码+机器地址+命令码+数据+校验码

        同步码:235(十进制)

        机器地址:机器地址范围为0-255(十进制)

命令码/数据: 1)左向开闸命令        40H    00H

   2)右向开闸命令        41H    00H

   3)右向开闸命令        48H    00H

   4)取消常开命令        49H    00H

 校验码=(同步码)XOR(设备地址)XOR(命令)XOR(数据)

 (如机器地址为1时则发:EB+01+40+00+AA)注意为十六进制

 

2.单片机发送帧格式:同步码+机器地址+数据+数据+校验码

       同步码:235(十进制)

        设备地址:机器地址范围为0-255(十进制)

                   c) 对于控制命令返回响应码:

  1. 左向开闸命令响应码     C0H   00H
  2. 右向开闸命令响应码     C1H   00H

校验码=(同步码)XOR(设备地址)XOR(数据1)XOR(数据2)。

 

 

  • pcomm.dll sdk下载

这里分享一个链接,写得非常详细,收益匪浅。SDK下载链接。下载完成后,解压,安装,一直下一步,完成。看一下安装目录下的结构,安装包里还附带了一些助手程序,可以帮助调试或者测试串口是否可用。结构如下:

  1. example 是一些demo程序,使用不同语言调用pcomm接口程序;
  2. Help 是帮助文档;
  3. Include 是头文件信息;
  4. Lib是需要的动态、静态库;
  5. Utility 就是助手程序;
  • 测试

本地使用VS2010编译运行example程序。编译会报一个COFF转换的错误。

LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

这个链接错误原因不详,也没有深究,解决办法是

复制 C:\Windows\winsxs\x86_netfx-cvtres_for_vc_and_vb_b03f5f7f11d50a3a_6.1.7601.17514_none_ba1c770af0b2031b 目录下的 cvtres.exe 到C:\Program Files\Microsoft Visual Studio 10.0\VC\bin 目录下,直接覆盖替换。 

不同的IDE,替换对应安装目录bin目录下的cvtres.exe程序。使用这种办法可以解决这个问题。

这里安利一个工具【everything】,下载后无需安装,可以整个电脑搜索文件,只要包含文件相关的关键字,马上就可以把整个系统所有的相关信息列处理,找东西非常快。这里付一张图片

 然后就可以愉快的编译demo程序并运行。pcomm.dll是基于WIN32的一套API。为什么事win32?因为接口实现是基于COM实现的。不了解或者没听说过COM的说明你对Windows系统还不够了解,我自己也了解有限。虽然个人开发用过一段时间。迷失在ATL中间,以前对泛型编程也不够了解,现在也是,哈哈。

  • 以Demo中SIMPLE为例,编译运行结果如下

  • 实现简单的开门指令,下面是win32WndProc消息处理函数,我们借助原来关于的消息,生成响应开门的指令
LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam)
{

        switch(iMsg){
        case WM_COMMAND:
            switch(LOWORD(wParam)){
            case IDM_PORT_OPEN:
                OpenPort();
                return 0;
            case IDM_PORT_CLOSE:
                ClosePort();
                return 0;
            case IDM_PORT_SETTING:{
                COMMDATA bakdata = GCommData;
                if(DialogBox(GhInst,MAKEINTRESOURCE(IDD_OPEN),hwnd,PortDlgProc)==IDCANCEL)
                    return 0;
                if(GbOpen)
                    if (!PortSet())
                        GCommData = bakdata;
                return 0;
                }
            case IDM_HELP_ABOUT:
				// 测试开门指令
				sio_putch(GCommData.Port, 0xEB);
				sio_putch(GCommData.Port, 0x01);

				sio_putch(GCommData.Port, 0x40);
				sio_putch(GCommData.Port, 0x00);
				sio_putch(GCommData.Port, 0xAA); 
                //DialogBox(GhInst,MAKEINTRESOURCE(IDD_ABOUT),hwnd,AboutDlgProc);
                return 0;
            case IDM_PORT_EXIT:
                SendMessage(hwnd,WM_CLOSE,0,0L);
                return 0;
            }
            break;
        case WM_CREATE:
            GCommData.Port = 1;
            GCommData.ibaudrate  = 14;
            GCommData.iparity = 0;
            GCommData.ibytesize = 3;
            GCommData.istopbits = 0;
            GCommData.BaudRate  = B38400;
            GCommData.Parity = P_NONE;
            GCommData.ByteSize = BIT_8;
            GCommData.StopBits = STOP_1;
            GCommData.Hw = FALSE;
            GCommData.Sw = FALSE;
            GCommData.Dtr = TRUE;
            GCommData.Rts = TRUE;
            GbOpen = FALSE;

            hwndedit = CreateWindowEx (WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE,
                       "edit",NULL,
                       WS_CHILD | WS_VISIBLE | ES_LEFT | WS_VSCROLL |
                       ES_MULTILINE |  ES_AUTOVSCROLL,
                       0,0,0,0,
                       hwnd,(HMENU)4,GhInst,NULL) ;
            _wpOrigWndProc = SubclassWindow(hwndedit,EditSubClassProc);

            SwitchMenu(hwnd);
            return 0;

        case WM_SIZE:
            MoveWindow (hwndedit,0,0,LOWORD(lParam),HIWORD(lParam),TRUE) ;
            return 0;
        case WM_CLOSE:
            if(GbOpen)
                SendMessage(hwnd,WM_COMMAND,IDM_PORT_CLOSE,0);
            break;
        case WM_SETFOCUS:
            SetFocus(hwndedit);
            return 0 ;
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hwnd,iMsg,wParam,lParam);
}

最关键部分如下

// 测试开门指令
sio_putch(GCommData.Port, 0xEB);
sio_putch(GCommData.Port, 0x01);

sio_putch(GCommData.Port, 0x40);
sio_putch(GCommData.Port, 0x00);
sio_putch(GCommData.Port, 0xAA); 

指令格式按照《通信协议》中的说明,指令如下

 左向命令:EB 01 40 00 AA
右向命令:EB 01 41 00 AB

左向命令:EB 左开01 40 00 AA
右向命令:EB 右开01 41 00 AB

 调用pcomm接口写入,按16进制写入。滴,滴,芝麻开门。。。,然后门就开了。

因为整个过程简单,可以使用pcomm lite 附带的助手做测试,简单说一下使用流程。先上图直观

如果打开串口成功,会跳出一个新界面,然后可以发数据了,指令类似“EB014000AA”,然后就芝麻开门了。

总结一下,是不是很简单,我可能只有了5个接口,然后就可以实现简单的串口通信了。

 

  • 附注,提供一些参考的信息

  1. Pcomm lite 串口库介绍

  2. Pcomm.dll(串口通讯库)中流控函数操作的说明手册

  3. delphi 的简单调用--这个提醒了我可以直接传16进制

  4. 官网--貌似说是一家台湾做硬件的公司做的,在这方面我们真的有很多需要学习的

猜你喜欢

转载自blog.csdn.net/moyebaobei1/article/details/81357079
今日推荐