⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cid.c

📁 C 语言的 ID卡开发应用 详细的介绍和使用C语言开发ID读卡器
💻 C
字号:
/*-- 曼码调制的非接触ID卡通用读卡程序编制
/******************头文件********************/
#include "string.h"
#include <reg52.h>
#include <intrins.h>
#include <math.h>

#if 0
#define p 9
#define l 10
#endif
/******************宏定义*********************/
sbit P17 = P1^7; 
sbit P37 = P3^7;
sbit P16 = P1^6; 
sbit P36 = P3^6;
sbit P15 = P1^5;
sbit P35 = P3^5;
sbit P14 = P1^4; 
sbit P34 = P3^4;
sbit P13 = P1^3; 
sbit P33 = P3^3;
sbit P12 = P1^2; 
sbit P32 = P3^2;
sbit P11 = P1^1; 
sbit P31 = P3^1;
sbit P10 = P1^0; 
sbit P30 = P3^0;
sbit P27 = P2^7; 
sbit P07 = P0^7;
sbit P26 = P2^6; 
sbit P06 = P0^6;
sbit P25 = P2^5; 
sbit P05 = P0^5;
sbit P24 = P2^4; 
sbit P04 = P0^4;
sbit P23 = P2^3; 
sbit P03 = P0^3;
sbit P22 = P2^2; 
sbit P02 = P0^2;
sbit P21 = P2^1; 
sbit P01 = P0^1;
sbit P20 = P2^0; 
sbit P00 = P0^0;

#define uchar unsigned char
#define uint unsigned int

#define RF_DATA_IN P17 //接收来至U2270B的数据"Output"
#define SO P31 //单片机输出数据到用户接口
#define SCK P16 //同步时钟输出
#define CP P15 //卡存在信号输出
#define MSEL P13 //数据发送方式选择
#define WATCHDOG P21 //看门狗
#define RED_LED  P10 //led灯
#define GREEN_LED P11 //led灯
#define DD P12 //蜂鸣器

/****************全局变量***********************/
uchar data Read_RF_Data[11]; //暂存从U2270B上接收的数据
uchar data ID_Data[6]; //暂存经效验后的正确数据
uint data TIMER_1=0;
bit Check_Data_bit; //效验请求标志位
/****************函数列表***********************/
void Recive_RF_Data(void);
void Check_Data(void);
void Clern_Number(void);
void Send_RS232net(uchar Data[],uchar Num);
void delay0_2ms(uint count);
void delay1ms(uint count);
void dida(uchar j);
/*****************串口初始话*********************/
void Data_start(void)
{DD=0x00;
 RED_LED=0x00;
 TMOD=0x21; //T0方式1,T1工作于方式2
 TH1=0x00; //初始化T1计时器
 TL1=0x00;
 TR1=0;
 SCON=0x50; //串行口初始化
 PCON=0x80; //SMOD位设置
 TH0=0x00; //初始化T0计时器
 TL0=0x04;
 TR0=0;
 ES=1; //开放串行口中断
 EA=1; //开放总中断
}
/**********************************************/
/*主函数*/
/**********************************************/
void main(void)
{
  delay1ms(100);
  Data_start();
  while(1)
  {
   WATCHDOG=~WATCHDOG;
   Recive_RF_Data(); //调用接收RF数据函数
   if(Check_Data_bit==1) //如果此位为1,有一组数据申请效验
    {
     Check_Data(); //调用数据效验函数
     Check_Data_bit=0;
    }
   }
}
/*********************************************/
/*接收RF数据*/
/*********************************************/
void Recive_RF_Data(void)
{
/////////////////////定义局部变量
  uchar header,pc;
  uchar temp;
  uchar temp1;
  uint temp2;
  uchar ByteCounter; //字节计数器
  uchar *PData;
  uchar BitCounter; //位计数器
  ////////////////////初始化变量值
  header=0;pc=4;
  PData=Read_RF_Data;
  temp=0;
  temp1=0;
  ByteCounter=0;
  BitCounter=5;
  /////////////////////检测一个稳定的低电平
str:
  WATCHDOG=~WATCHDOG;
  if(RF_DATA_IN==0)
  if(RF_DATA_IN==0)
  if(RF_DATA_IN==0)
  if(RF_DATA_IN==0)
  if(RF_DATA_IN==0)
  {
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
////////////////////检测一个起始位电平
  while(RF_DATA_IN==0); //当电平由低向高跳变时启动计时器
    TR0=1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
////////////////////检测9个"header"
   while(RF_DATA_IN==1);
     TR0=0;
     TF0=0;
     TIMER_1=TH0;
     TIMER_1=(TIMER_1<<8)+TL0;
     TH0=0x00;
     TL0=0x04;
     temp2=0x108;
   if(TIMER_1>temp2) // >520us
     {
     goto str;
     }
     temp2=0xf9;
   if(TIMER_1<temp2) // <490us
     {
     goto str;
     }
   do
    {
     TIMER_1=0;
     WATCHDOG=~WATCHDOG;
     while(RF_DATA_IN==0);
     TR0=1;
     _nop_();
     _nop_();
     _nop_();
     _nop_();
     _nop_();
     _nop_();
     _nop_();
     _nop_();
     _nop_();
     _nop_();
     while(RF_DATA_IN==1);
     TR0=0;
     TF0=0;
     TIMER_1=TH0;
     TIMER_1=(TIMER_1<<8)+TL0;
     TH0=0x00;
     TL0=0x04;
     temp2=0x90;
     if(TIMER_1>temp2)// >280us
      {
       header=0;
       goto str;
       }
      temp2=0x77;
     if(TIMER_1<temp2)// <230us
      {
       header=0;
       goto str;
       }
       header++;
      }while(header<8);
      TR0=0;
      TF0=0;
///////////////////如果9个"header"都对,开始接收卡内数据
      TH0=0xff; //time:300us
      TL0=0x6a;
      TR0=1;
      if(header==8)
        {
         do
         {
          do
            {

           while(TF0==0); //等待一个位周期
           TF0=0;
         if(RF_DATA_IN==1) temp=1;
         else temp=0;
      while(RF_DATA_IN==temp) //检测电平跳变否?
      {
       if(TF0==1) //如果300us计时到还未跳变,视为非法电平!!!
       {
        TR0=0;
        TF0=0;
        goto str;
       }
      }
      TH0=0xff; //time:300us
      TL0=0x6a;
      temp=~RF_DATA_IN;
      temp1=(temp1<<1)|temp;
      BitCounter--;
      }while(BitCounter); //一个字节完否
      *(PData+ByteCounter)=temp1; //将一字节数据存入缓存数组
      temp1=0;
      BitCounter=5;
      ByteCounter++;
      WATCHDOG=~WATCHDOG;
      }while(ByteCounter<10);
     do
      {
       WATCHDOG=~WATCHDOG;
       while(TF0==0); //等待一个位周期
       TF0=0;
       if(RF_DATA_IN==1) temp=1;
       else temp=0;
       while(RF_DATA_IN==temp) //检测电平跳变否?
       {
        if(TF0==1) //如果300us计时到还未跳变,视为非法电平!!!
        {
         TR0=0;
         TF0=0;
         goto str;
        }
       }
       TH0=0xff; //time:300us
       TL0=0x6a;
       temp=~RF_DATA_IN;
       temp1=(temp1<<1)|temp;
       pc--;
       }while(pc); //一个字节完否
       Read_RF_Data[10]=temp1; //将一字节数据存入缓存数组
///////////////////检测最后一个停止位
       while(TF0==0);
       TR0=0;
       TF0=0;
       if(RF_DATA_IN==1) temp=1;
       else temp=0;
       while(RF_DATA_IN==temp) //检测电平跳变否?
        {
        if(TF0==1) //如果300us计时到还未跳变,视为非法电平!!!
       {
        TR0=0;
        TF0=0;
        goto str;
        }
       }
       temp=~RF_DATA_IN;
       if(temp==0) //如果停止位正确
        {
        Check_Data_bit=1; //置效验请求标志
        }
       else //如果停止位不正确
       {
       Clern_Number(); //清除
       }
       }
       }
       }
/*********************************************/
/*效验数据*/
/*********************************************/
void Check_Data(void)
{
/////////////////////定义局部变量
     uchar temp;
     uchar temp1;
     uchar ByteCounter; //数组计数器
     uchar ByteCounter1;
     uchar *PData;
     uchar *PData1;
////////////////////初如化变量值
     PData=Read_RF_Data;
     PData1=ID_Data;
     temp=0;
     temp1=0;
     ByteCounter=0;
     ByteCounter1=0;
/////////////////////循环效验
     WATCHDOG=~WATCHDOG;
/////////////////////行校验
for(ByteCounter1=0;ByteCounter1<5;ByteCounter1++)//有5个字节数据
{
    temp=(((*(PData+ByteCounter))&0x10)>>4)+(((*(PData+ByteCounter))&0x08)>>3)+(((*(PData+ByteCounter))&0x04)>>2)+(((*(PData+ByteCounter))&0x02)>>1);
    if((temp&0x01)==((*(PData+ByteCounter))&0x01))//效验高4位
     {
      temp1=(*(PData+ByteCounter)&0xfe)<<3;
      ByteCounter++;
      temp=(((*(PData+ByteCounter))&0x10)>>4)+(((*(PData+ByteCounter))&0x08)>>3)+(((*(PData+ByteCounter))&0x04)>>2)+(((*(PData+ByteCounter))&0x02)>>1);
      if((temp&0x01)==((*(PData+ByteCounter))&0x01))//效验高4位
      {
       *(PData1+ByteCounter1)=temp1|((*(PData+ByteCounter)&0xfe)>>1);//高低位生成一个字节存入数组
       ByteCounter++;
      }
     else
     {
     ByteCounter1=5;//只要有一组不对则退出效验
     Clern_Number();//并清所有数据
     }
    }
   else
   	{
     ByteCounter1=5;//只要有一组不对则退出效验
     Clern_Number();//并清所有数据
    }
     WATCHDOG=~WATCHDOG;
   }
/////////////////////列校验
//......因没有必要所以先省略此处.........//
/////////////////////生成校验和,并发送出去
   if(ByteCounter==10)
   {
    ID_Data[5]=ID_Data[0]+ID_Data[1]+ID_Data[2]+ID_Data[3]+ID_Data[4];//生成校验和
    if(MSEL==0) //此脚如果为低电位,为异步通信方式发送数据
     {
      CP=0;
      delay0_2ms(1);
      Send_RS232net(ID_Data,6); //调用串口发送函数
      delay0_2ms(1);
      CP=1;
     }
    Clern_Number();
    dida(1);
    GREEN_LED=0x00;
    delay0_2ms(1000);//*****(正确读取一张卡号后要等待约一秒后再重新扫描)*****
   }
  }
//************************************************************
/*清暂存器*/
//************************************************************
void Clern_Number(void)
{
  WATCHDOG=~WATCHDOG;
  Read_RF_Data[0]=0;
  Read_RF_Data[1]=0;
  Read_RF_Data[2]=0;
  Read_RF_Data[3]=0;
  Read_RF_Data[4]=0;
  Read_RF_Data[5]=0;
  Read_RF_Data[6]=0;
  Read_RF_Data[7]=0;
  Read_RF_Data[8]=0;
  Read_RF_Data[9]=0;
  Read_RF_Data[10]=0;
  ID_Data[0]=0;
  ID_Data[1]=0;
  ID_Data[2]=0;
  ID_Data[3]=0;
  ID_Data[4]=0;
  ID_Data[5]=0;
}
//**********************************************************
/*串行口发送,接收程序*/
//**********************************************************
void Send_RS232net(uchar Data[],uchar Num) //串行口数据发送
{
  uchar i=0;
  uchar *PData;
  PData=Data;
  WATCHDOG=~WATCHDOG;
  TH1=0xf3; //串行口波特率2400b/s
  TL1=0xf3;
  TR1=1;
  for(i=0;i<Num;i++)//有Num组号码要发送
   {
    SBUF=*(PData+i);
    while(TI==0);TI=0;//等待数据发送出去
    delay0_2ms(1);//等待后再发送
   }
    TR1=0;
  }
//*****************************************************
/*延时0.2ms*count*/
//*****************************************************
void delay0_2ms(uint count)
{
   uint k;
   while(count--!=0)
    {
     for(k=0;k<50;k++)
     {
      WATCHDOG=~WATCHDOG;
     }
    }
}
void delay1ms(uint count)
{
   uint k;
   while(count--!=0)
   {
    for(k=0;k<250;k++)
    {
     WATCHDOG=~WATCHDOG;
    }
   }
}
//*****************************************************
/*鸣叫声*/
//*****************************************************
void dida(uchar j)
{
   uchar i;
   for(i=0;i<j;i++)
   {
    DD=~DD;
    delay1ms(30);
    DD=~DD;
    delay1ms(30);
    }
}
///////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -