C51 Manchester译码源程序 C51曼彻斯译码源程序
2009-04-30 11:14
/* manchester编码方式:0为10 1为01,如果与其相反则需要做相应的修改。 适用于125KHz非接触式ID卡,EM4100兼容格式ID卡(64bits, Manchester编码) MCU:stc12c54xx crystal:11.0592M 使用资源:外部中断0(INT0)+PCA0 */ #include <stc12c5410ad.h> #include <stdio.h> #include<intrins.h> #define Channe256uS_H 0x00 //模块60mS 定时常数高位 #define Channe256uS_L 0xEC //模块60mS 定时常数低位 #define uint8 unsigned char sbit RFID_DATA = P3^2; //外部中断口 接收数据 /*/函数申明 */ void start_Read() ; void Data_reveice() ; void Lmove_bite() ; uint8 find_head() ; uint8 Data_L_check() ; uint8 Data_R_check() ; void get_data(); uint8 Data_Sever() ; void Get_EffectData(uint8 edata) ; void Init_PCA0(); void DAT_Change(uint8 dat[]); void init_dev(void); uint8 tcount ;// 定时中断计数 uint8 count ;//接收数据位数计数 uint8 t_count ;//获得数据及校验变量。 uint8 temp ;// 临时变量 uint8 temp_buf[16] ;//128个Machester位 55个数据位 缓冲区。 uint8 effectdata[5] ;//5个数据缓冲区。相当于模块串行读的10 Bytes 数据。 bit error_bit;//数据出错时为0,初始值为1 bit rev_state;//初始值为0;数据正确接收后为1. //当此位变为1时,说明数据接收正确并且正确处理,可以使用此ID数据。 /********************************************* 函数名:main() 功能: 主函数 参数: 无 *********************************************/ void main(void) { uint8 i; error_bit=1; rev_state=0; init_dev();//初始化各模块 //添加自己的程序 } } void init_dev(void) { CMOD = 0x80; //PCA 在空闲模式下停止 PCA 计数器工作 CCON = 0x00; //;CF = 0,清0 PCA 计数器溢出中断请求标志位 CCAP0L=Channe256uS_L;//给 PCA 模块0 的 CCAP0L 置初值 CCAP0H=Channe256uS_H; CCAPM0=0X49; SCON=0x50;//串口工作在方式1,允许接收。 TMOD = 0x20 ; //定时器1工作在方式2 for generator baud rate TH1=0xFD;//11.0592M baud rate//串口用于调试方便,波特率9600 TL1=0xFD; TR1=1; IT0=1; EA = 1 ;// 开总中断 TI=1; } /********************************************* 函数名:BCD_Change 功能: 初始化RFID模块 参数: 无 *********************************************/ void DAT_Change(uint8 *dat) { uint8 i,count,c; for(count=0;count<5;count++) { for(i=0;i<2;i++) { if(i==0) { c = dat[count]>>4; c &= 0x0f; if( c>=0 && c<=9 ) temp_buf[2*count+1] = '0' + c; else temp_buf[2*count+1] = 'A' + c - 10; } else { c = dat[count]; c &= 0x0f; if( c>=0 && c<=9 ) temp_buf[2*count] = '0' + c; else temp_buf[2*count] = 'A' + c - 10; } } } } /********************************************* 函数名:start_Read() 功能: 初始化RFID模块 参数: 无 *********************************************/ void start_Read() { count = 0 ; EX0 = 1 ;// 开外部中断0 } /********************************************* 函数名:Init_PCA0 功能: 设定定时器1 定时128us 参数: 无 *********************************************/ void Init_PCA0() { CL = 0x76; //清0 PCA 计数器 CH = 0x00; EPCA_LVD=1;//开 PCA 中断和 LVD(低压检测)中断共享的总中断控制位 CR=1;// 启动 PCA 计数器(CH,CL)计数 } /********************************************* 函数名:EX0_Serve 功能: 外部中断0 初始化定时器1 定时128us 参数: 无 *********************************************/ void EX0_Serve() interrupt 0 //外部中断0 { //printf("into EX0_Serve. \n"); Init_Timer1() ; //初始化定时器1 tcount = 0 ; } /********************************************* 函数名:PCA0_Serve 功能: 定时器1中断 参数: 无 *********************************************/ void PCA_Serve() interrupt 6 //定时0中断 { Data_reveice() ; tcount ++ ; if( tcount == 5 )//定时器中断5次,而外部中断没有发生时。 { error_bit=0;//返回出错状态 //printf("data error. \n"); } CL = 0x00; //清0 PCA 计数器 CH = 0x00; CCF0=0;//清0 PCA 模块0中断请求标志位 } void Data_reveice() { //P2=0x00; if(RFID_DATA==1) { temp_buf[count/8] = (temp_buf[count/8]|(0x01<<(count%8)) ) ; } if(RFID_DATA==0) { temp_buf[count/8] = (temp_buf[count/8]&(~(0x01<<(count%8))) ) ; } count ++ ; if(count==128) //0x80) { count=0 ; CR=0; EX0=0; if( Data_Sever() ) //RFID数据处理成功 { //printf("data right. \n"); rev_state = 1 ; //禁止RFID接收数据。 } else //RFID数据处理失败 { //printf("data error1. \n"); error_bit=0;//返回出错状态 } } // P2=0xff; } /********************************************* 函数名:Lmove_bite 功能: 128位左移一位。 参数: 无 *********************************************/ void Lmove_bite() { uint8 tempData0=0 ; for(temp=0 ; temp<0x10 ; temp++ ) //循环16次 { if( temp == 0 ) { tempData0 = ( (temp_buf[0]&0x01) <<7 ) ;} //保存数组0 的1位 if( temp == 0x0f ) { temp_buf[temp] =( (temp_buf[temp]>>1) | tempData0 ) ; } else { temp_buf[temp] = ( (temp_buf[temp]>>1) | ( (temp_buf[temp+1]&0x01) <<7 ) ) ; } } } /******************************************* 函数名:find_head 功能: 循环移位 查128位数据的9个1 : 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 参数: 无 *********************************************/ uint8 find_head() { for(count=0;count<128;count++) { if( (temp_buf[0]==0xAA) && (temp_buf[1]==0xAA) && ((temp_buf[2]&0x03)==0x02) ) {return 1;} else {Lmove_bite();} } return 0 ; } /******************************************* 函数名:get_data 功能: 将128位 除9个1 0 的位转化为55位 参数: 无 ********************************************/ //此处也与实际相反。 //因为些程序应用在0为10 1为01的Machester 解码中。颠倒了大小于符号。 void get_data() { for( count=0 ,t_count=0 ; count <= 126 ; )//0x6c ; ) { if(( temp_buf[((count+18)/8)]&(0x01<<((count+18)%8)))< ( temp_buf[((count+19)/8)]&(0x01<<((count+19)%8)))) ///1 { temp_buf[t_count/8] = ( temp_buf[t_count/8] | ( 0x01 << (t_count%8) ) ) ; } if(( temp_buf[((count+18)/8)]&(0x01<<((count+18)%8)))> ( temp_buf[((count+19)/8)]&(0x01<<((count+19)%8)))) //0 { temp_buf[t_count/8] = ( temp_buf[t_count/8] & ( ~ ( 0x01 << (t_count%8) ) ) ) ; } t_count++; count=count+2; } } /********************************************* 函数名:Data_L_check 功能: 列校验 返回值: 列校验成功返回1 列校验失败返回0 ********************************************/ uint8 Data_L_check() { for(count=0 ; count < 0x04 ; count++) { temp = 0 ; t_count = count ; for( ; t_count <= 53 ; )//0x37 ; ) { 单片机printf函数 if( ( temp_buf[(t_count/8)] & (0x01<<(t_count%8)) ) )//>> (t_count%8) ) { temp ++ ; } t_count = t_count + 5 ; } if((temp%2)!= 0) { return 0 ; //列校验失败 } } return 1 ; } /********************************************* 函数名:Data_R_check 功能: 行校验 [7] 参数: 行校验成功返回1 行校验失败返回0 ********************************************/ uint8 Data_R_check() { uint8 t_buf[5] ; count=0 ; for(t_count=0 ; t_count<= 45 ; )//0x32 ; ) { t_buf[0] = ( ( temp_buf[(t_count/8)] & (0x01<<(t_count%8)) ) >> (t_count%8) ) ; t_buf[1] = ( ( temp_buf[((t_count+1)/8)] & (0x01<<((t_count+1)%8)) ) >> ((t_count+1)%8) ) ; t_buf[2] = ( ( temp_buf[((t_count+2)/8)] & (0x01<<((t_count+2)%8)) ) >> ((t_count+2)%8) ) ; t_buf[3] = ( ( temp_buf[((t_count+3)/8)] & (0x01<<((t_count+3)%8)) ) >> ((t_count+3)%8) ) ; t_buf[4] = ( ( temp_buf[((t_count+4)/8)] & (0x01<<((t_count+4)%8)) ) >> ((t_count+4)%8) ) ; if( (( t_buf[0]+t_buf[1]+t_buf[2]+t_buf[3]+t_buf[4] )%2) == 0) {t_count = t_count + 5 ;} else {return 0 ;} //行校验失败 for(temp=0 ; temp<0x04 ; temp++ ) { Get_EffectData( t_buf[3-temp] ) ; count ++ ; } } return 1 ; } /********************************************* 函数名:Get_EffectData 功能: 将一位数据依次放入数组effectdata【5】 参数: edata 要放入数组的数据 *********************************************/ void Get_EffectData(uint8 edata) { switch(edata) { case 1: //被注释的为 位数从高到低全部掉换因 //为读出的数据左移8位后才也实际数据相符 //effectdata[count/8] = (effectdata[count/8]|(0x01<<(7-(count%8))) ) ; effectdata[count/8] = (effectdata[count/8]|(0x01<<(count%8)) ) ; break ; case 0: //被注释的为 位数从高到低全部掉换因 //为读出的数据左移8位后才也实际数据相符 //effectdata[count/8] = (effectdata[count/8]&(~(0x01<<(7-(count%8)))) ) ; effectdata[count/8] = (effectdata[count/8]&(~(0x01<<(count%8))) ) ; break ; } } /********************************************* 函数名:Data_Sever 功能: 处理RFID数据 返回值:0 处理是失败 1 处理成功 *********************************************/ uint8 Data_Sever() { if(find_head() == 0 ) //寻128位中 9个1 0 的曼切斯的头 { return 0 ; } get_data() ; //将128位转化为除去 9个1 0 的55位 if(Data_L_check() == 0 ) //列校验 { return 0 ; } if(Data_R_check() == 0 ) //行校验 如果成功将其放入特定的有效数组 { return 0 ; } return 1 ; } |
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论