Chinaunix首页 | 论坛 | 博客
  • 博客访问: 30103851
  • 博文数量: 230
  • 博客积分: 2868
  • 博客等级: 少校
  • 技术积分: 2223
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-08 21:48
个人简介

Live & Learn

文章分类

全部博文(230)

文章存档

2022年(2)

2019年(5)

2018年(15)

2017年(42)

2016年(24)

2015年(13)

2014年(1)

2012年(5)

2011年(58)

2010年(56)

2009年(9)

我的朋友

分类: C/C++

2012-07-09 17:00:32

 

 

[c-sharp]
  1. /******************************************************************************************                  
  2.                                 检测方法 
  3. 1).EM4095的数据格式为:9bit起始位+40bit数据位+10bit行校验位+4bit列校验位+1bit停止位 
  4.      
  5. 2).本程序时针对STC12C5A60S2单片机的,与80C51完全兼容,但是大部分指令时单周期指令,也就是 
  6.     说比普通80C51大约快12倍 
  7.                                      
  8. 3).确定起始位,首先要正确找到数据1,按规则下跳为1,上跳为0. 可检测高电平并等其变低, 
  9.     但这会把0错检为1,因为0也存在高电平。但是如果检测到一个周期的高电平(数据01)则可 
  10.     确定找到了数据1,找到1后就可以同步了,因为EM4095卡最后一位数据就是0正好可以利用 
  11.     作为判断的特征。 
  12. 4).对于数据的确定,由于有了同步则可在同步后延时384us即3/4个码元周期,再判断接收段电平, 
  13.     如为高则置数据为1,并一直等到低电平的出现,相反则等高电平的出现,并在此之间插入超时 
  14.     判断。这样,一个完整的数据判断就完成了,并确保数据的准确性,另外这种方法的抗干扰性 
  15.     会非常好,而如果采用定时同步的话则会因信号的畸变而引起数据出错,整体会导致读卡几率降低 
  16.     但是此程序也有其缺点,因为采用纯延时判断的手段,因此其占用单片机的运行时间比较大。 
  17. 5).同步后开始接收同步数据即9个1,这一部分用一个循环做,如果出错则放弃接收 
  18. 6).同步数据接收完后,则开始接收数据,数据分11行5列接收,以利于校验位的判断 
  19.     如有出错则放弃数据 
  20. 7).如一切正常则返回卡号,如因尝试读卡次数到了则返回0,表示没有卡 
  21. 8).码元频率是载波频率的64分频,因此码元周期为:T=64/125000= 0.000512s=512us,因此3T/4=384us 
  22. ********************************************************************************************/ 
  23. #include   
  24. #include //空操作指令需要此头文件  
  25. #define DELAYVAL    384  
  26. #define TIMEOUT     3000   
  27.   
  28. //定义错误代码  
  29. #define ERR_NO                      0x00  
  30. #define ERR_125KNOTFOUND    0x01   
  31.   
  32. //控制EM4095的引脚   
  33. sbit    MOD         = P2^1;  
  34. sbit    SHD         = P2^0;  
  35. sbit    DEMOD_OUT   = P3^3;  
  36. sbit    RDY_CLK     = P3^4;  
  37. sbit    BEEPLED     = P1^5;  
  38.   
  39.   
  40. //延时n*1us函数   
  41. void stc12_Delay1us(unsigned short n)  
  42. {  
  43.         while(--n)  
  44.         {  
  45.                 _nop_();  
  46.                 _nop_();  
  47.                 _nop_();  
  48.                 _nop_();  
  49.                 _nop_();  
  50.         }  
  51. }  
  52.   
  53.   
  54. //读取卡号,   
  55. unsigned char decode_125kCard(unsigned char *buf)  
  56. {  
  57.     unsigned char i=0;  //起始为的计数值   
  58.     unsigned short timeCount;  //时间溢出的计数值   
  59.     unsigned char timeOutFlag; //时间溢出标志   
  60.     unsigned char row,col;    //行列寄存器   
  61.     unsigned char row_parity;  //行校验寄存器   
  62.     unsigned char col_parity[5]; //列校验寄存器   
  63.     unsigned char dat;      //数据寄存器   
  64.     unsigned char searchCount=0;     //搜索次数寄存器   
  65.   
  66.     unsigned char j;  
  67.     while(1)  
  68.     {                 
  69.         timeCount=0;      
  70.         while(0==DEMOD_OUT)//等高电平   
  71.         {  
  72.             if(timeCount==TIMEOUT)  
  73.                 break;//超时退出   
  74.             else   
  75.                 timeCount++;        
  76.         }     
  77.   
  78.         if(timeCount==1200)           
  79.                 return ERR_125KNOTFOUND;  
  80.         else   
  81.                 timeCount=0;  
  82.                               
  83.         stc12_Delay1us(DELAYVAL);//延时3/4码元,使电平判断时间正好处于高电平的中间         
  84.         if(DEMOD_OUT)//寻找真正的起始位1,利用01的波形确定1起始位,即最后一位加第一位起始位   
  85.         {                 
  86.                 for(i=0;i<8;i++)//判断是否是真的起始位,9个字节的1,因为前面已经判断了1位,因此此处只需判断8位即可   
  87.                 {       
  88.                         timeCount=0;       //限定等待时间   
  89.                         while(1==DEMOD_OUT)//等低电平,延时掉后面1/4码元的高电平   
  90.                         {  
  91.                                 if(timeCount==TIMEOUT)  
  92.                                 {       
  93.                                         timeOutFlag=1;//时间超时   
  94.                                         break;  //退出   
  95.                                 }  
  96.                                 else   
  97.                                 {  
  98.                                         timeCount++;  
  99.                                 }   
  100.                         }                                 
  101.                                                               
  102.                         if(timeOutFlag)//如果高电平超时则退出   
  103.                         {  
  104.                                 break;  
  105.                         }  
  106.                         else  
  107.                         {  
  108.                                 stc12_Delay1us(DELAYVAL);       //延时至下一码元   
  109.                                 if( 0==DEMOD_OUT )                                                                        
  110.                                         break;  
  111.                         }                    
  112.                 }  
  113.                 if(timeOutFlag)//因时间溢出造成的本次主循环退出   
  114.                 {       
  115.                         timeOutFlag=0;  
  116.                         return ERR_125KNOTFOUND;  
  117.                 }  
  118.       
  119.                 if(i==8)  //起始位接收完并且正确后开始接收数据   
  120.                 {     
  121.                         timeOutFlag=0;  
  122.                         timeCount=0;     //限定等待时间   
  123.                         while(1==DEMOD_OUT)//等低电平,延时掉第9bit起始位的后面1/4码元的高电平   
  124.                         {                 
  125.                                 if(timeCount==TIMEOUT)  
  126.                                 {                         
  127.                                         timeOutFlag=1;  
  128.                                         break;       //时间溢出造成的出?   
  129.                                 }  
  130.                                 else  
  131.                                 {  
  132.                                         timeCount++;  
  133.                                 }     
  134.                                                   
  135.                                 if(timeOutFlag)      
  136.                                 {  
  137.                                         timeOutFlag=0;                                        
  138.                                         return ERR_125KNOTFOUND;  
  139.                                 }  
  140.                         }  
  141.                         //所有列校验清零   
  142.                         col_parity[0]=col_parity[1]=col_parity[2]=col_parity[3]=col_parity[4]=0;  
  143.                         for(row=0;row<11;row++)  //共11行数据   
  144.                         {  
  145.                                 row_parity = 0;  
  146.                                 j = row>>1;//每两行作为一个字节的数据   
  147.                                 for(col=0,row_parity=0;col<5;col++)//共5列数据   
  148.                                 {  
  149.                                         stc12_Delay1us(DELAYVAL);  //延时至下一码元   
  150.                                         if(DEMOD_OUT)  
  151.                                                 dat=1;  //数据为1   
  152.                                         else  
  153.                                                 dat=0;  //数据为0   
  154.                                   
  155.                                         if(col<4&&row<10)  //数据区的接受,后四个字节   
  156.                                         {  
  157.                                                 buf[j] <<= 1;  
  158.                                                 buf[j] |= dat;                                                
  159.                                         }  
  160.                                   
  161.                                         row_parity += dat;       //行校验加入数据   
  162.                                         col_parity[col] += dat;  //相应列校验加入,虽最后一列没有校验但为了方便也加上   
  163.                                         timeCount=0;                 //限定等待时间清零   
  164.                                         while(DEMOD_OUT==(bit)dat)  
  165.                                         {  
  166.                                                 if(timeCount==TIMEOUT)        //由于时间溢出造成的数据出错   
  167.                                                 {     
  168.                                                         timeOutFlag=1;  
  169.                                                         break;            //退出本while循环   
  170.                                                 }  
  171.                                                 else   
  172.                                                 {  
  173.                                                         timeCount++;  
  174.                                                 }  
  175.                                         }                                         
  176.                                         if(timeOutFlag)break;    //出错退出内层for循环   
  177.                                 }  
  178.                                 if(row<10)//最后一行没有校验所以要加限制   
  179.                                 {  
  180.                                         if((row_parity&0x01)||timeOutFlag) //行校验出错或时间超时   
  181.                                         {  
  182.                                                 timeOutFlag=1;   
  183.                                                 break;           //退出   
  184.                                         }  
  185.                                 }      
  186.                         }  
  187.                           
  188.                         //对最后接收的列校验进行判断,及对来自上面数据error_flag处理以结束本次主循环   
  189.                         //if(timeOutFlag||((col_parity[0]&0x01)&&(col_parity[1]&0x01)&&(col_parity[2]&0x01)&&(col_parity[3]&0x01)))   
  190.                         if( timeOutFlag||(col_parity[0]&0x01)||(col_parity[1]&0x01)||(col_parity[2]&0x01)||(col_parity[3]&0x01) )  
  191.                         {   //最后一列没有校验                                                  
  192.                                 timeOutFlag=0;                                
  193.                                 return ERR_125KNOTFOUND;  
  194.                         }   
  195.                         else   
  196.                         {                             
  197.                                 return ERR_NO;  
  198.                         }  
  199.                 }//end if(i==8)   
  200.                 return ERR_125KNOTFOUND;  
  201.         }//end if(DEMOD_OUT)   
  202.     }  
  203. }
阅读(7509) | 评论(0) | 转发(0) |
0

上一篇:Wiegand协议

下一篇:UCOS/II移植到STM32

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