最近给驾校做一个考场安检验证的程序。其中有一步就是经过指纹验证后,需要开道闸允许考生进入考试区域。
之前没有串口编程经验。大概搜了一下,了解到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) 对于控制命令返回响应码:
- 左向开闸命令响应码 C0H 00H
- 右向开闸命令响应码 C1H 00H
校验码=(同步码)XOR(设备地址)XOR(数据1)XOR(数据2)。
-
pcomm.dll sdk下载
这里分享一个链接,写得非常详细,收益匪浅。SDK下载链接。下载完成后,解压,安装,一直下一步,完成。看一下安装目录下的结构,安装包里还附带了一些助手程序,可以帮助调试或者测试串口是否可用。结构如下:
- example 是一些demo程序,使用不同语言调用pcomm接口程序;
- Help 是帮助文档;
- Include 是头文件信息;
- Lib是需要的动态、静态库;
- 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个接口,然后就可以实现简单的串口通信了。
-
附注,提供一些参考的信息