51单片机曼彻斯特码译码源程序
- 格式:doc
- 大小:64.50 KB
- 文档页数:14
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)]&(0 x01<<((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)]&(0
x01<<((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 ; )
{
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 ;
}。