Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1416941
  • 博文数量: 1334
  • 博客积分: 645
  • 博客等级: 上士
  • 技术积分: 5762
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-25 16:56
文章分类

全部博文(1334)

文章存档

2014年(108)

2013年(1059)

2012年(169)

分类: LINUX

2013-02-21 05:00:58

原文地址:韦根协议 wiegand 作者:leon_yu

一、概述:

Wiegand(韦根)协议是由摩托罗拉公司制定的一种通讯协议,它适用于涉及门禁控制系统的读卡器和卡片的许多特性;其协议并没有定义通讯的波特率、也没有定义数据长度。韦根格式主要定义是数据传输方式:Data0 Data1 两根数据线分别传输 0 1.现在应用最多的是 26bit,34bit36bit44bit 等等。

二、Wiegand时序:

Wiegand接口通常由3根线组成,它们是:数据0Data0),数据1Data1 Data return。这3条线负责传输Wiegand信号。D0D1在没有数据输出时都保持+5V高电平。若输出为0,则D0拉低一段时间,若输出为1,则D1拉低一段时间。

输出‘0’时:DATA0 线上出现负脉冲;

输出‘1’时:DATA1 线上出现负脉冲;

负脉冲宽度 TP=100 微妙;周期 TW=1600 微妙

具体时序如下:

例如:数据‘01000’的时序如下:

三、标准26 Wiegand协议:    

标准韦根输出是由26位二进制数组成,每一位的含义如下:

1 2                   9 10                                         25 26
E X X X X X X X X X X X X X X X X X X X X X X X X O       
二进制         

1位为2—13位的偶校验位
2—9位对应与电子卡HID码的低8
10-25位对应电子卡的PID号码
26位为14-25位的奇校验位
26位数据在读出器的韦根输出线D0D1上输出。

以上数据从左至右顺序发送。高位在前。

四、韦根 26 接收:

    韦根的接收对时间的实时性要求比较高,如果用查询的方法接收会出现丢帧的现象:假设查询到 DATA0 0 时主程序正在指向其他任务,等主程序执行完该任务时 DATA0 已经变为 1 了,那么这样就导致了一个 0 bit 丢了,这样读出的卡号肯定奇偶校验通不过,所以表现出 CPU 接收不到 ID 模块发送的卡号了。

唯一的办法是在外部中断里接收每个 bit (仅仅在中断里获得开始接收 wiegand 数据还不行,因为这是尽管给开始接收 wiegand 数据标志位置位了,但是主程序还在执行其他代码而没有到达查询开始接收 wiegand 数据标志位这条指令)。

五.韦根接口定义

Wiegand 接口界面由三条导线组成:

DATA0:暂定,兰色,P2.5  (通常为绿色)。

DATA1:暂定,白色,P2.6  (通常为白色)。

GND:(通常为黑色), 暂定信号地。 当安装商拿到读卡器时,他们希望在读卡器和门禁控制面板的连接点(终端)上都能够看到这三个名称。

目前所有的标准型读卡器都提供可选择的 Wiegand 接口。这三条线负责传送 Wiegand 数据,也被称为Wiegand 信号。

代码仅供参考,没有实测,实际应用时,做发送,注意延时。做接收,一般用中断采集数据。

  1. 发送程序: 
  2.  
  3. //------------------------------------------------------
  4. //功能:把数组封包成韦根 26 的格式,并发送出去
  5. // 原理是把每个字节的低 4 位取出,来计算这个字节的值
  6. //入口:str=要封包的数组,
  7. //出口:DATA0P3.0;DATA1=P3.1
  8. //设计:大鹏,大鹏艾迪,2006/4/11
  9. //------------------------------------------------------
  10. void send_wiegand26(uchar *str)
  11. {
  12. //| wiegand[0] | wiegand[1] | wiegand[2] |
  13.     //| *str *(str + 1) | *(str + 2) *(str + 3)| *(str + 4) *(str + 5)|
  14. uchar data i;
  15. static uchar data one_num; //计算 1 的个数
  16. uchar data check_temp; //韦根包奇偶效验中间暂存
  17. bit data even; //韦根包前 12 位偶效验
  18. bit data odd; //韦根包后 12 位齐效验
  19. static uchar data wiegand[3]; //韦根包数据 24 位
  20. //--------------------------------端口方向定义
  21. P3M0 = 0x00; //普通 I/O 口
  22. P3M1 = 0x00;
  23. //================================数组到韦根包的转化
  24. wiegand[0] = wiegand[0]|((*str)<<4);//原理是把每个字节的低 4 位取出,来计算这个字节的值
  25. wiegand[0] = wiegand[0]|(*(str+1)&0x0f);
  26. //--------------------------------计算前 8 位 1 的个数,为偶效验用
  27. check_temp = wiegand[0];
  28. for(i = 0;i<8;i++)
  29. {
  30.     if(check_temp&0x01) //(check_temp&0x01)
  31. {
  32.     one_num++;
  33. }
  34. check_temp >>= 1;
  35. }
  36. wiegand[1] = wiegand[1]|(*(str+2)<<4);
  37. //--------------------------------计算接下来的 4 位 1 的个数,为偶效验用
  38. check_temp = wiegand[1];
  39. for(i = 0;i<4;i++)
  40. {
  41.     if(check_temp&0x80)
  42. Copyright(C) 2006-2007 DAPID. All Rights Reserved
  43. 3
  44. {
  45.     one_num++;
  46. }
  47. check_temp<<=1;
  48. }
  49.     //--------------------------------判断 1 的个数
  50. one_num%2 == 0 ? (even = 0):( even = 1);
  51. one_num = 0;
  52.  
  53. wiegand[1] = wiegand[1]|(*(str+3)&0x0f);
  54.     //--------------------------------计算接下来的 4 位 1 的个数,为奇效验用
  55. check_temp = wiegand[1];
  56. for(i = 0;i<4;i++)
  57. {
  58.     if(check_temp&0x01)
  59. {
  60.     one_num++;
  61. }
  62. check_temp>>=1;
  63. }
  64. wiegand[2] = wiegand[2]|(*(str+4)<<4);
  65. wiegand[2] = wiegand[2]|(*(str+5)&0x0f);
  66.     //--------------------------------计算接下来的 8 位 1 的个数,为奇效验用
  67. check_temp = wiegand[2];
  68. for(i = 0;i<8;i++)
  69. {
  70.     if(check_temp&0x01)
  71. {
  72.     one_num++;
  73. }
  74. check_temp >>= 1;
  75. }
  76.     //--------------------------------判断 1 的个数
  77. one_num%2 == 0 ? (odd = 1):( odd = 0);
  78. one_num = 0;
  79.  
  80. //================================启动发送,用定时器做时间延时
  81. //--------------------------------韦根 输出端初始化
  82. WG_DATA0 = 1;
  83. WG_DATA1 = 1;
  84. //--------------------------------发送偶效验
  85. if(even)
  86. {
  87.      WG_DATA1 = 0;

  88.  //-------------------------延时 100us
  89.  TR0 = 0;
  90.  TH0 = (65536 - 78)/256; //定时 100us
  91.  TL0 = (65536 - 78)%256;
  92.  TF0 = 0;
  93.  ET0 = 0;
  94.  TR0 = 1;
  95.  while (!TF0) { ;}
  96.   
  97.  TF0 = 0;
  98.  WG_DATA1 = 1;
  99. }
  100. else
  101. {
  102.      WG_DATA0 = 0;
  103.  //------------------------延时 100us
  104.  TR0 = 0;
  105.  TH0 = (65536 - 78)/256; //定时 100us
  106.  TL0 = (65536 - 78)%256;
  107.  TF0 = 0;
  108.  ET0 = 0;
  109.  TR0 = 1;
  110.  while (!TF0) { ;}
  111.  
  112.  TF0 = 0;
  113.  WG_DATA0 = 1;
  114. }
  115.  //----------------------------延时一个发送周期
  116.  TR0 = 0;
  117.  TH0 = (65536 - 1382)/256; //定时 1500us
  118.  TL0 = (65536 - 1382)%256;
  119.  TF0 = 0;
  120.  ET0 = 0;
  121.  TR0 = 1;
  122.      while (!TF0) { ;}
  123.  
  124.  TF0 = 0;
  125. //-------------------------------发送 24 位数据
  126. for(i = 0;i<24;i++)
  127.     {
  128.     //---------------------------韦根 输出端初始化
  129.     WG_DATA0 = 1;
  130. WG_DATA1 = 1;
  131. if((wiegand[0])&0x80) 
  132. {
  133.      WG_DATA1 = 0;
  134.  //----------------------延时 100us
  135.   
  136.  TR0 = 0;
  137.  TH0 = (65536 - 78)/256; //定时 100us
  138.  TL0 = (65536 - 78)%256;
  139.  TF0 = 0;
  140.  ET0 = 0;
  141.  TR0 = 1;
  142.  
  143.  while (!TF0) { ;}
  144.  TF0 = 0;
  145.  WG_DATA1 = 1;
  146. }
  147. else
  148. {
  149.      WG_DATA0 = 0;
  150.  //---------------------延时 100us
  151.  TR0 = 0;
  152.  TH0 = (65536 - 78)/256; //定时 100us
  153.  TL0 = (65536 - 78)%256;
  154.  TF0 = 0;
  155.  ET0 = 0;
  156.  TR0 = 1;
  157.  while (!TF0) { ;}
  158.  TF0 = 0;
  159.  WG_DATA0 = 1;
  160. }
  161. (*(long*)&wiegand[0]) <<= 1;
  162. //-------------------------------延时一个发送周期
  163. TR0 = 0;
  164. TH0 = (65536 - 1382)/256; //定时 1500us
  165. TL0 = (65536 - 1382)%256;
  166. TF0 = 0;
  167. ET0 = 0;
  168. TR0 = 1;
  169.     while (!TF0) { ;}
  170. TF0 = 0;
  171. }
  172. //==============================发送奇效验位
  173.     //------------------------------韦根 输出端初始化
  174.     WG_DATA0 = 1;
  175. WG_DATA1 = 1;
  176.                     
  177. if(odd)
  178. {
  179.      WG_DATA1 = 0;
  180.  
  181.  //-------------------------延时 100us
  182.  TR0 = 0;
  183.  TH0 = (65536 - 78)/256; //定时 100us
  184.  TL0 = (65536 - 78)%256;
  185.  TF0 = 0;
  186.  ET0 = 0;
  187.  TR0 = 1;
  188.  while (!TF0) { ;}
  189.  TF0 = 0;
  190.  WG_DATA1 = 1;
  191. }
  192. else
  193. {
  194.      WG_DATA0 = 0;
  195.  //-------------------------延时 100us
  196.  TR0 = 0;
  197.  TH0 = (65536 - 78)/256; //定时 100us
  198.  TL0 = (65536 - 78)%256;
  199.  TF0 = 0;
  200.  ET0 = 0;
  201.  TR0 = 1;
  202.  while (!TF0) { ;}
  203.  TF0 = 0;
  204.  WG_DATA0 = 1;
  205. } 
  206. }

阅读(657) | 评论(0) | 转发(0) |
0

上一篇:spi协议

下一篇:ldd3学习之五:并发与竞态

给主人留下些什么吧!~~