当前位置:文档之家› 曼彻斯特解码程序

曼彻斯特解码程序

曼彻斯特解码1、变量定义 (2)2、Manchest初始化 (2)3、Manchest解码信号翻转 (3)4、过滤错误的卡号 (4)5、获取正确的卡号 (5)6、Manchest获取卡号数据 (6)7、通过中断采样获取刷卡数据 (9)1、变量定义#define TH1_370US_H 0XFE //晶振11.0592MHZ,12T模式#define TL1_370US_L 0XAB#define SIGNAL_FLIP_TIME 10 //每隔100ms翻转一次读卡信号#define REPEAT_TIME 5 //500ms后重复读卡#define CLEAR_CARD_TIME 20 //2S后清除卡号数据#define MANCHEST_TIME 5sbit PULSE = P3^2;sbit RFEN = P3^5; //曼彻斯特解码脉冲信号sbit MANCHEST0= P3^2; //wiegand0sbit MANCHEST1= P3^3; //wiegand1uchar code CheckingTab[32]={ //接收到10组卡号的偶校验0X00,0X01,0X01,0X00,0X01,0X00,0X00,0X01, //这里数值是低五位的偶校验值0X01,0X00,0X00,0X01,0X00,0X01,0X01,0X00,0X01,0X00,0X00,0X01,0X00,0X01,0X01,0X00,0X00,0X01,0X01,0X00,0X01,0X00,0X00,0X01};uchar WGCardBuf[5]; //卡号uchar CopyCardBuf[5]; //备份卡号uchar ManchestBuf[11]; //暂存接收到的11组数据uchar idata g_ucManchestTime = MANCHEST_TIME; //uchar idata g_ucDWithCardTime= 0; //隔500ms处理该卡号uchar idata g_ucPreambleFlag = 0;uchar idata g_ucERAgainTimer = 0; //每隔100ms翻转一次RFENuchar idata g_ucStoreGroupCnt= 0; //接收到几组数据,这里为11组才可能正确uchar idata g_ucEGroupBitCnt = 0; //每组数据有5个为,5=4位卡号+1位偶校验uchar idata g_ucPreambleCount= 0; //9位为1的引导码uchar idata g_ucRemvoeCardTime=0; //隔多久清除以前的卡号数据,这里为3s2、Manchest初始化/******************************************************************** 函数原型:ManchestInit功能:曼彻斯特解码变量初始化输入:无输出:无说明:无*-------------------------------------------------------------------- *修改时间| 修改者| 备注*-------------------------------------------------------------------- *2012-02-14 Oscar First********************************************************************/ void ManchestInit(void) //初始化读卡参数{RFEN = 1;g_ucPreambleFlag = 0;g_ucStoreGroupCnt = 0;g_ucEGroupBitCnt = 5;g_ucPreambleCount = 9;g_ucERAgainTimer = SIGNAL_FLIP_TIME;}3、Manchest解码信号翻转/******************************************************************** 函数原型:ProcessManchestSignal功能:manchest解码的翻转信号输入:无输出:无说明:无*-------------------------------------------------------------------- *修改时间| 修改者| 备注*-------------------------------------------------------------------- *2012-02-14 Oscar First********************************************************************/ void ProcessManchestSignal(void){if((g_ucDWithCardTime!=0)&&(--g_ucDWithCardTime==0)){}if((g_ucRemvoeCardTime!=0)&&(--g_ucRemvoeCardTime==0)){CopyCardBuf[0] = 0; //清除卡号缓冲区CopyCardBuf[1] = 0;CopyCardBuf[2] = 0;CopyCardBuf[3] = 0;CopyCardBuf[4] = 0;}RFEN = ~RFEN;g_ucPreambleFlag = 0;g_ucPreambleCount= 9;if(RFEN){EX0 = 1;EX1 = 1;}else{EX0 = 0;EX1 = 0;}}4、过滤错误的卡号/******************************************************************** 函数原型:CalibrationCardData功能:一张卡号,如果出现全部相同的数字或者该卡号只有两种数据,则认为是错误的卡号。

输入:uchar *pCard,uchar ucCount输出:0或1说明:无*-------------------------------------------------------------------- *修改时间| 修改者| 备注*-------------------------------------------------------------------- *2012-02-14 Oscar First********************************************************************/ uchar CalibrationCardData(uchar *pCard,uchar ucCount){uchar ucCnt = 0;uchar ucVal = 0;uchar ucVerify = 0;uchar ucVerifyCnt= 0;ucVerify = 0;ucVal = pCard[0];for(ucCnt=1;ucCnt<ucCount;ucCnt++) //和第一个数相同的共有多少个{if(ucVal==pCard[ucCnt]){ucVerify++;}}if(ucVerify!=ucCount-1) //所有数据都相同?{ //不是ucVal = pCard[0];for(ucCnt=1;ucCnt<ucCount;ucCnt++){if(ucVal != pCard[ucCnt]) //找出和第一个数不同的数{break;}}ucVal=pCard[ucCnt];ucCnt++;ucVerifyCnt=0;while(ucCnt<ucCount){if(ucVal==pCard[ucCnt]){ucVerifyCnt++;} //和这个数相同的数有几个ucCnt++;}ucVerify = ucVerify + ucVerifyCnt; //两种数共有多少个if(ucVerify==(ucCount-2)) //这张卡只有两种数据{return 1; //则认为错误卡号}else{return 0; //不止两种数据}}else{return 1; //错误卡号}}5、获取正确的卡号/******************************************************************** 函数原型:DealWithCardData功能:处理卡号数据输入:无输出:0或1说明:无*-------------------------------------------------------------------- *修改时间| 修改者| 备注*-------------------------------------------------------------------- *2012-02-14 Oscar First********************************************************************/ uchar DealWithCardData(void){uchar ucCnt = 0;uchar ucValH = 0;uchar ucValL = 0;ucValH=CalibrationCardData(ManchestBuf,10);if(ucValH==0) //卡号正确{for(ucCnt=0;ucCnt<5;ucCnt++) //获取卡号{ucValH = ManchestBuf[2*ucCnt];ucValL = ManchestBuf[2*ucCnt+1];ucValH = (ucValH<<4) | ucValL;ManchestBuf[ucCnt] = ucValH;}return 0;}else //卡号错误{return 1;}}6、Manchest获取卡号数据/******************************************************************** 函数原型:ProcessManchest功能:停止位为0、行校验、列校验、输入:无输出:0或1说明:无*-------------------------------------------------------------------- *修改时间| 修改者| 备注*--------------------------------------------------------------------*2012-02-14 Oscar First********************************************************************/ void ProcessManchest(void){uchar ucCnt = 0;uchar ucVal = 0;uchar ucValue = 0;uchar ucVerify= 0;RFEN = 0;g_ucERAgainTimer = SIGNAL_FLIP_TIME;ucVal=ManchestBuf[10]&0X01; //获取停止位if(ucVal==0) //判断停止位是否为0{ //曼彻斯特编码的停止位为0 ucVerify=ManchestBuf[10]>>1; //获取列偶校验值for(ucCnt=0;ucCnt<10;ucCnt++) //获取行、列偶校验值{ucValue=ManchestBuf[ucCnt]&0X1F;if(CheckingTab[ucValue]!=0) //行校验是否正确{ucVerify = 1; //不正确break; //结束}ucVal = ManchestBuf[ucCnt]; //行校验通过ucVal = ucVal>>1; //移除行校验位ucVal = ucVal & 0X0F; //计算卡号ManchestBuf[ucCnt]=ucVal; //暂存卡号ucVerify=ucVal ^ ucVerify; //列校验}ucVerify = ucVerify&0X0F; //获取列校验值if(ucVerify==0) //列校验正确?{ucVal=DealWithCardData(); //正确,获取卡号if(ucVal==0){for(ucCnt=0;ucCnt<5;ucCnt++) //和上次卡号数据对比是否相等{if(CopyCardBuf[ucCnt]!=ManchestBuf[ucCnt]){break;}}if(ucCnt==5) //连续两次接收到是同一张卡号{if(g_ucDWithCardTime==0) //{for(ucCnt=0;ucCnt<5;ucCnt++)//暂存卡号{CopyCardBuf[ucCnt] = ManchestBuf[ucCnt];WGCardBuf[ucCnt] = ManchestBuf[ucCnt];}g_ucTask |= 0X04;EX0 = 1; //开外部中断EX1 = 1;g_ucDWithCardTime = REPEAT_TIME;}else{EX0 = 1; //开外部中断EX1 = 1;g_ucDWithCardTime = REPEAT_TIME;g_ucRemvoeCardTime= CLEAR_CARD_TIME;} //2S后清除卡号缓冲区}else{for(ucCnt=0;ucCnt<5;ucCnt++) //赋卡号,与下一次接收卡号匹配{CopyCardBuf[ucCnt] = ManchestBuf[ucCnt];}RFEN= 1;EX0 = 1;EX1 = 1;g_ucDWithCardTime = 0;g_ucRemvoeCardTime= CLEAR_CARD_TIME;} //2S后清除卡号缓冲区}else{RFEN= 1; //读取线圈数据EX0 = 1; //开中断EX1 = 1;}}else{EX0 = 1;EX1 = 1;}}else{EX0 = 1;EX1 = 1;}}7、通过中断采样获取刷卡数据/******************************************************************** ********************************************************************* *************************以下为曼彻斯特解码程序********************** *************通过外部中断0、1和定时器TI匹配解码卡号****************** ********************************************************************* ********************************************************************/ /******************************************************************** 函数原型:Int0Routine功能:触发Timer1采样输入:无输出:无说明:无*-------------------------------------------------------------------- *修改时间| 修改者| 备注*-------------------------------------------------------------------- *2012-02-14 Oscar First********************************************************************/ void Int0Routine(void) interrupt 0{if(MANCHEST0!=1){TH1 = TH1_370US_H;TL1 = TL1_370US_L;TR1 = 1;ET1 = 1;TF1 = 0;EX0 = 0;EX1 = 0;}}/******************************************************************** 函数原型:Int1Routine功能:触发Timer1采样输入:无输出:无说明:无*-------------------------------------------------------------------- *修改时间| 修改者| 备注*-------------------------------------------------------------------- *2012-02-14 Oscar First********************************************************************/ void Int1Routine(void) interrupt 2{if(MANCHEST1!=1){TH1 = TH1_370US_H;TL1 = TL1_370US_L;TR1 = 1;ET1 = 1;TF1 = 0;EX0 = 0;EX1 = 0;}}/******************************************************************** 函数原型:Timer1Routine功能:触发Timer1采样输入:无输出:无说明:无*-------------------------------------------------------------------- *修改时间| 修改者| 备注*-------------------------------------------------------------------- *2012-02-14 Oscar First********************************************************************/ void Timer1Routine(void) interrupt 3{uchar ucVal =0; //暂存获取数据TR1=0;if(g_ucPreambleFlag) //9个1到了?{if(PULSE){g_ucPreambleCount--;if(g_ucPreambleCount==0) //在PULSE==1的情况下如果g_ucPreamble_Count{ //还能减到0说明有连续的1出现IE0 = 0;IE1 = 0;EX1 = 1;EX0 = 1;g_ucPreambleFlag = 1;g_ucStoreGroupCnt= 0;g_ucEGroupBitCnt = 5;g_ucPreambleCount= 9;return;}}else{ //只要有低电平出现就重新付值,g_ucPreambleCount = 0X09; //看有否连续的高电平出现}ucVal = ManchestBuf[g_ucStoreGroupCnt];ucVal = ucVal<<1;if(PULSE) //为高{ucVal |= 1; //置位}else{ucVal &=0XFE;}ManchestBuf[g_ucStoreGroupCnt] = ucVal;if(g_ucEGroupBitCnt>5){IE0 = 0;IE1 = 0;EX1 = 1;EX0 = 1;g_ucPreambleFlag = 0;g_ucStoreGroupCnt= 0;g_ucEGroupBitCnt = 5;ManchestBuf[0] = 0;return;}g_ucEGroupBitCnt--;if(g_ucEGroupBitCnt==0){g_ucStoreGroupCnt++;if(g_ucStoreGroupCnt<11){IE0 = 0;IE1 = 0;EX1 = 1;EX0 = 1;g_ucEGroupBitCnt = 5;return;}if(g_ucStoreGroupCnt==11) //11组数据接收完成{EX0 = 0; //关中断EX1 = 0;TR1 = 0;g_ucTask |= 0X02; //置处理卡号标志return;}if(g_ucStoreGroupCnt>11){IE0 = 0;IE1 = 0;EX1 = 1;EX0 = 1;g_ucPreambleFlag = 0;g_ucEGroupBitCnt = 5;g_ucStoreGroupCnt= 0;ManchestBuf[0] = 0;return;}}else{IE0 = 0;IE1 = 0;EX1 = 1;EX0 = 1;} //11组字节收齐了?}else{if(PULSE){g_ucPreambleCount--;if(g_ucPreambleCount==0) //够不够9个1?{g_ucPreambleFlag = 1;g_ucStoreGroupCnt= 0;g_ucEGroupBitCnt = 5;g_ucPreambleCount= 9;}}else{g_ucPreambleCount = 9;}IE0 = 0;IE1 = 0;EX1 = 1;EX0 = 1;}}。

相关主题