📄 iccard.c
字号:
/*------------------------------------------------------------*/
#include<stdio.h>
#include<reg51.h>
#include<absacc.h>
#include<intrins.h>
/*------------------------------------------------------------*/
#define uchar unsigned char
#define uint unsigned int
/*------------------------------------------------------------*/
#define C8279 XBYTE[0xF239] /*定义8279命令口地址*/
#define D8279 XBYTE[0xF238] /*定义8279数据口地址*/
/*------------------------------------------------------------*/
uchar idata atrdata[4]; /*复位应答缓冲区*/
uchar idata command[3]; /*输入命令缓冲区*/
uchar idata dis_ram[8]; /*定义显示缓冲区*/
uchar idata password[3]; /*密码缓冲区*/
uchar idata s_mem[4]; /*保护缓冲区*/
/*------------------------------------------------------------*/
uchar ec; /*错误计数器*/
uchar r_byte; /*读字节*/
uchar w_byte; /*写字节*/
uchar pulse; /*延时脉冲数*/
uchar rd_add; /*读地址*/
uchar wr_add; /*写地址*/
uchar key; /*输入的键号*/
/*------------------------------------------------------------*/
uint i;
uint j;
uint c;
/*------------------------------------------------------------*/
bit bdata kbz; /*有无键标志*/
bit bdata ic; /*输入的键号*/
sbit clk = P1^3; /*CLK*/
sbit rst = P1^5; /*RST*/
sbit sda = P1^7; /*I/O*/
/*------------------------------------------------------------*/
uchar code ledseg[]={0x3f,0x06,0x5b,0x4F,0x66,0x6D,0x7D,0x07,
0x7f,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
0xbf,0x86,0xdb,0xcf,0x40,0x00};
/*---------------------------初始化---------------------------*/
void init()
{
C8279 = 0x00; /*置8279工作方式*/
C8279 = 0x2f; /*置键盘扫描速率*/
C8279 = 0xc1; /*清除LED显示*/
while(C8279 & 0x80); /*等待清除结束*/
}
/*--------------------------显示函数--------------------------*/
void disled(d)
uchar idata *d;
{
for(j=0;j<8;j++)
{
C8279 = 0x87 - j;
D8279 = ledseg[*d];
d++;
}
}
/*----------------------------延时----------------------------*/
void delay()
{
_nop_();
_nop_();
_nop_();
}
/*--------------------------时钟脉冲--------------------------*/
void card_pulse()
{
delay();
clk = 1;
delay();
delay();
clk = 0;
}
/*---------------------------读字节---------------------------*/
void rdbyte()
{
r_byte = 0x00;
for(c=0;c<8;c++)
{
clk = 1;
if(sda)
{
r_byte = r_byte + 0x01;
}
r_byte = _cror_(r_byte,1);
delay();
clk = 0;
delay();
}
}
/*---------------------------写字节---------------------------*/
void wrbyte(k)
uchar k;
{
for(c=0;c<8;c++)
{
clk =0;
delay();
if(_cror_(k,c)&0x01)
{
sda = 1;
}
else
{
sda = 0;
}
clk = 1;
delay();
}
}
/*---------------------------写延时---------------------------*/
void process()
{
delay();
clk = 0;
_nop_();
_nop_();
sda = 0;
for(i=0;i<254;i++)
{
card_pulse();
}
_nop_();
sda = 1;
}
/*--------------------------复位应答--------------------------*/
void rst_atr()
{
clk = 0;
rst = 0;
delay();
rst = 1;
delay();
clk = 1;
delay();
clk = 0;
delay();
rst = 0;
for(i=0;i<4;i++)
{
rdbyte();
atrdata[i] = r_byte;
}
sda = 1;
}
/*--------------------------命令输入--------------------------*/
void send_command()
{
clk = 0;
delay();
sda = 1;
delay();
clk = 1;
delay();
sda = 0;
delay();
clk = 0;
delay();
for(i=0;i<3;i++)
{
wrbyte(command[i]);
}
delay();
clk = 0;
delay();
sda = 0;
clk = 1;
delay();
sda = 1;
}
/*-------------------------读主存储区-------------------------*/
void read()
{
rst_atr(); /*复位应答*/
command[0] = 0x30;
command[1] = rd_add;
send_command();
clk = 0;
pulse = 0xff - rd_add;
rdbyte();
for(j=0;j<pulse;j++)
{
for(i=0;i<8;i++)
{
card_pulse();
}
}
}
/*-------------------------写主存储区-------------------------*/
void write()
{
rst_atr(); /*复位应答*/
command[0] = 0x38;
command[1] = wr_add;
command[2] = w_byte;
send_command();
process();
}
/*------------------------读错误计数器------------------------*/
uchar rdsm_ec()
{
rst_atr();
command[0] = 0x31;
send_command();
clk = 0;
for(i=0;i<4;i++)
{
rdbyte();
s_mem[i] = r_byte;
}
ec = s_mem[0] & 0x07;
return(ec);
}
/*------------------------写错误计数器------------------------*/
void wrsm()
{
rst_atr(); /*复位应答*/
command[0] = 0x39;
command[1] = 0x00;
send_command();
process();
}
/*--------------------------密码比较--------------------------*/
void send_psc()
{
rst_atr(); /*复位应答*/
command[0] = 0x33;
for(j=0;j<3;j++)
{
command[1] = j + 0x01;
command[2] = password[j];
send_command();
process();
}
}
/*--------------------------密码校验--------------------------*/
void verify_password()
{
rdsm_ec(); /*读错误计数器*/
switch(ec)
{
case 0x07 : ec = 0x03;
break;
case 0x06 : ec = 0x02;
break;
case 0x05 : ec = 0x01;
break;
case 0x04 : ec = 0;
break;
case 0x03 : ec = 0x01;
break;
case 0x02 : ec = 0;
break;
case 0x01 : ec = 0;
break;
case 0 : ic = 1;
}
ic = 0;
command[2] = ec;
wrsm();
send_psc();
command[2] = 0xff;
wrsm();
rdsm_ec();
}
/*----------------------------读键----------------------------*/
uchar keyscan()
{
if((C8279&0x07) == 0x00)
{
kbz = 0; /*无键按下,置标志*/
}
else
{
kbz = 1;
C8279 = 0x40; /*读FIFO RAM命令*/
key = D8279;
key = (key&0x3f); /*取键盘数据低6位*/
return(key);
}
}
/*--------------------------标准显示--------------------------*/
void std_disp()
{
for(i=0;i<8;i++)
{
dis_ram[i] = 0x14;
}
disled(dis_ram);
}
/*--------------------------卡片读取--------------------------*/
void rd_card()
{
rd_start:
dis_ram[0] = 0x15; /*显示区设置*/
dis_ram[1] = 0x01;
dis_ram[2] = 0x15;
dis_ram[3] = 0x14;
dis_ram[4] = 0x14;
dis_ram[5] = 0x15;
dis_ram[6] = 0x14;
dis_ram[7] = 0x14;
disled(dis_ram);
for(i=3;i<5;i++)
{
do
{
dis_ram[i] = keyscan();
}while(kbz == 0); /*无键输入,则再读*/
disled(dis_ram);
}
rd_add = _crol_(dis_ram[3],4) + dis_ram[4];
disled(dis_ram);
key = 0x00;
do
{
if(keyscan() == 0x0e)
{
goto rd_start;
}
else if(keyscan() == 0x0d)
{
std_disp();
goto rd_end;
}
else{}
}while(key != 0x0f);
read();
dis_ram[1] = 0x11;
dis_ram[6] = r_byte/16;
dis_ram[7] = r_byte%16;
rd_end:
disled(dis_ram);
}
/*--------------------------卡片写入--------------------------*/
void wr_card()
{
wr_start:
dis_ram[0] = 0x15; /*显示区设置*/
dis_ram[1] = 0x02;
dis_ram[2] = 0x15;
dis_ram[3] = 0x14;
dis_ram[4] = 0x14;
dis_ram[5] = 0x15;
dis_ram[6] = 0x14;
dis_ram[7] = 0x14;
disled(dis_ram);
for(i=3;i<5;i++)
{
do
{
dis_ram[i] = keyscan();
}while(kbz == 0);
disled(dis_ram);
}
for(i=6;i<8;i++)
{
do
{
dis_ram[i] = keyscan();
}while(kbz == 0);
disled(dis_ram);
}
key = 0x00;
do
{
if(keyscan() == 0x0e)
{
goto wr_start;
}
else if(keyscan() == 0x0d)
{
std_disp();
goto wr_end;
}
else{}
}while(key != 0x0f);
dis_ram[1] = 0x12;
wr_add = _crol_(dis_ram[3],4) + dis_ram[4];
w_byte = _crol_(dis_ram[6],4) + dis_ram[7];
write();
wr_end:
disled(dis_ram);
}
/*--------------------------卡片校验--------------------------*/
void verify()
{
ve_start:
dis_ram[1] = 0x15;
switch(rdsm_ec())
{
case 0x07: dis_ram[0] = 0x03;
break;
case 0x06: dis_ram[0] = 0x02;
break;
case 0x05: dis_ram[0] = 0x02;
break;
case 0x04: dis_ram[0] = 0x01;
break;
case 0x03: dis_ram[0] = 0x02;
break;
case 0x02: dis_ram[0] = 0x01;
break;
case 0x01: dis_ram[0] = 0x01;
return;
}
dis_ram[2] = 0x14;
dis_ram[3] = 0x14;
dis_ram[4] = 0x14;
dis_ram[5] = 0x14;
dis_ram[6] = 0x14;
dis_ram[7] = 0x14;
disled(dis_ram);
for(i=2;i<8;i++)
{
do
{
dis_ram[i] = keyscan();
}while(kbz == 0); /*无键输入,则再读*/
disled(dis_ram);
}
key = 0x00;
do
{
if(keyscan() == 0x0e)
{
goto ve_start;
}
else if(keyscan() == 0x0d)
{
std_disp();
goto ve_end;
}
else{}
}while(key != 0x0f);
dis_ram[0] = dis_ram[0] + 0x10;
password[2] = _crol_(dis_ram[6],4) + dis_ram[7];
password[1] = _crol_(dis_ram[4],4) + dis_ram[5];
password[0] = _crol_(dis_ram[2],4) + dis_ram[3];
verify_password();
ve_end:
disled(dis_ram);
}
/*-------------------------头文字显示-------------------------*/
void disp_atr()
{
rst_atr();
rst_atr();
dis_ram[7] = atrdata[3]%16;
dis_ram[6] = atrdata[3]/16;
dis_ram[5] = atrdata[2]%16;
dis_ram[4] = atrdata[2]/16;
dis_ram[3] = atrdata[1]%16;
dis_ram[2] = atrdata[1]/16;
dis_ram[1] = atrdata[0]%16;
dis_ram[0] = atrdata[0]/16;
disled(dis_ram);
}
/*---------------------------主程序---------------------------*/
void main()
{
init();
while(1)
{
rst_atr();
keyscan();
if(kbz == 1) /*判断是否有键输入*/
{
if(key == 0x00)
{
disp_atr();
}
else if(key == 0x01)
{
rd_card();
}
else if(key == 0x02)
{
wr_card();
}
else if(key == 0x03)
{
verify();
}
else
{
std_disp();
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -