📄 t2.c
字号:
#include <AT89X52.h>
#include <INTRINS.H>
#include <string.h>
unsigned char INBUF_LEN; //数据长度
unsigned char inbuf1[32];
unsigned char count3;
unsigned int i;
unsigned char c0[9]={0x00,0x06,0x00,0x00,0x05,0x03,0x01,0x03,0x01}; //初始相对卡号
unsigned char temp[9]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char pass[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
bit flag=0; //是否进行下一步的标志
//*********************************************************************************//
unsigned char ledcode[] ={0xee, //0
0x28, //1
0xcd, //2
0x6d, //3
0x2b, //4
0x67, //5
0xe7, //6
0x2c, //7
0xef, //8
0x6f, //9
0xaf, //A
0xe3, //B
0xc6, //C
0xe9, //D
0xc7, //E
0x87}; //F
//数码管字符表
//*********************************************************************************//
void delay(int j) // 延时
{
int a;
while (--j){a=1000;while(--a){;}}
}
/***********************************************************************************/
void init_com(void) //初始化串口
{
SCON=0x50;
TMOD=0x20;//t0 timer
TH1=0xfd;//9600bps
TR1=1;
ET1=0;
ES=1;
EA=1;
IT0 =0;
count3=0; //串口计数清零
INBUF_LEN=0x21; //数据长度设为最大
}
//向串口发送一个字符串,strlen为该字符串长度,连续发送
void send_string_com(unsigned char strlen)
{
unsigned int t=0;
RI=0;
EA=0;
do
{
SBUF=inbuf1[t];
while(TI==0);
TI=0;
t++;
} while(t < strlen);
EA=1;
}
//串口接收中断函数 ,连续接收
void serial () interrupt 4 using 3
{
unsigned int k=0;
EA=0;
if(RI)
{
while(inbuf1[count3]!=0x0D)
{
RI = 0;
if (inbuf1[count3]==0x3C )
{count3=0;inbuf1[count3]=0x3C;count3++;}
else count3++;
inbuf1[count3]=SBUF;
while (RI==0&&k<6000){k++;}
}
}
EA=1;
//INBUF_LEN=count3+1;
count3=0;
}
/***************************************************************/
unsigned char BCC(unsigned char *str,unsigned int strlen) //数据校验
{
unsigned char bcc1=0x00;
i=0;
while(i<strlen)
{
bcc1^=str[i];
i++;
}
return bcc1;
}
/***************************************************************/
void searchcard() //这一步能正常通过了!
{
flag=0;
inbuf1[0]=0x3C; //下传命令:3C 04 01 70 00(寻卡模式00(IDLE)或01(ALL)) 00 BCC(49) 0D
inbuf1[1]=0x04;
inbuf1[2]=0x01;
inbuf1[3]=0x70;
inbuf1[4]=0x01;
inbuf1[5]=0x00;
inbuf1[6]=BCC(inbuf1,6); //校验
inbuf1[7]=0x0D;
INBUF_LEN=8; count3=0;
send_string_com(INBUF_LEN); //向模块发送命令
delay(100); //等待模块回传信息
// send_string_com(INBUF_LEN);
if ( inbuf1[1]==0x05)
{
temp[0]=inbuf1[2]; //获取相对卡号
temp[1]=inbuf1[3];
temp[2]=inbuf1[4];
temp[3]=inbuf1[5];
delay(50);
flag=1; //寻卡成功,flag置位
} else
flag=0;
count3=0;
return;
}
/**************************************************************/
void passcheck() //这一步好像有问题!不知道为什么!可能是延时太少么?
{
unsigned int i;
flag=0;
inbuf1[0]=0x3C; // 下传命令:3C 0E 01 6C 六字节密码 认证模式(00-A/01-B) 绝对块号 四字节卡号 校验位 0D
inbuf1[1]=0x0E; //eg:3C 0E 01 6C ff ff ff ff ff ff 00 02 74 09 49 C4 AD 0D
inbuf1[2]=0x01;
inbuf1[3]=0x6C;
for (i=0;i<6;i++){inbuf1[i+4]=pass[i];}
inbuf1[10]=0x00; //认证模式(00-A/01-B) 使用A模式 只读不写
inbuf1[11]=0x01; //读块号1
for (i=0;i<4;i++) {inbuf1[i+12]=temp[i];}
inbuf1[16]=BCC(inbuf1,16);
inbuf1[17]=0x0D;
INBUF_LEN=18; count3=0;
send_string_com(INBUF_LEN); //向模块发送命令
delay(100); //等待模块回传信息
// send_string_com(INBUF_LEN); //测试点
if (inbuf1[1]==0x02) //这里只是根据返回命令的特征进行简单验证,为了程序更加健壮,应该要进行bcc校验
{
delay(100);
flag=1; //密码验证成功,flag置位
}
return;
}
/**************************************************************/
void readcard()
{
flag=0;
inbuf1[0]=0x3C; // 下传命令:3C 04 01 66 00(绝对块号) 00 BCC 0D
inbuf1[1]=0x04;
inbuf1[2]=0x01;
inbuf1[3]=0x66;
inbuf1[4]=0x01; //绝对块号
inbuf1[5]=0x00;
inbuf1[6]=BCC(inbuf1,6);
inbuf1[7]=0x0D;
INBUF_LEN=8;
count3=0;
send_string_com(INBUF_LEN); //向模块发送命令
delay(100); //等待模块回传信息
if (inbuf1[1]==0x12) //这里只是根据返回命令的特征进行简单验证,为了程序更加健壮,应该要进行bcc校验
{
for (i=0;i<10;i++)
{temp[i]=inbuf1[i+3];
inbuf1[i]=temp[i];}
delay(20);
flag=1; //寻卡成功,flag置位
}
// INBUF_LEN=0x08; count3=0;
// send_string_com(INBUF_LEN);
delay(20);
return;
}
/**************************************************************/
void cardcheck() //验证相对卡号
{
flag=1;
for(i=0;i<8;i++)
{if (temp[i]!=c0[i])
flag=0;}
// if (temp[8]>=c0[8])
// c0[8]=temp[8]; //卡号的最后一个字节是识别字节,用于用户换自己的卡,大数有效
// else flag=0;
}
/**************************************************************/
void closecard() // 关闭卡片:3C 04 01 68 00 00 51 0D
{
inbuf1[0]=0x3C;
inbuf1[1]=0x04;
inbuf1[2]=0x01;
inbuf1[3]=0x68;
inbuf1[4]=0x00;
inbuf1[5]=0x00;
inbuf1[6]=0x51;
inbuf1[7]=0x0D;
INBUF_LEN=0x08;
count3=0;
send_string_com(INBUF_LEN);
}
/**************************************************************/
void main(){
unsigned int state;
init_com(); //初始化串口和中断
state=1;
P1_7=1;
P0=ledcode[0];
delay(50);
while(1)
{
// P1_2=0; P0=ledcode[0];delay(50);
switch(state){
case 1:
P0=ledcode[state];delay(50);
searchcard();
if (flag) state++;else state=6;break;
//寻卡
case 2:
P0=ledcode[state];delay(50);
passcheck();
if (flag) state++;else state=6;break;
//如果寻卡成功,获取绝对卡号,进行密码验证
case 3:
P0=ledcode[state];delay(50);
readcard();
if (flag) state++;else state=6;break;
//如果密码验证成功,读卡获取,获取相对卡号
case 4: P0=ledcode[state];delay(50);
cardcheck();
if (flag) state++;else state=6;break;
// 进行验证
case 5:
P0=ledcode[state];delay(500);
P1_7=0;delay(1000);P1_7=1;state++;break;
// p1.7指示电动门锁执行开门动作 ,
case 6: P0=ledcode[state];delay(50);
closecard();state=1;break;
// 模拟时接led显示 及接在外部中断上,用以模拟正常开门时门磁动作
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -