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 ;
}