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

📄 iccard.c

📁 MCS-51单片机实验 39个实用实验和源码
💻 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 + -