📄 sysle4442.c
字号:
#include <reg52.h>
#include <intrins.h>
//#include <AT89X55.H>
/*SLE4442命令字宏定义*/
#define READ_MAIN_MEM 0x30 /*read main memory of SLE 4442*/
#define READ_PROT_MEM 0x34 /*read protection memory of SLE 4442*/
#define WRITE_MAIN_MEM 0x38 /*write main memory of SLE 4442*/
#define WRITE_PROT_MEM 0x3C /*write protection memory of SLE 4442*/
#define READ_SECU_MEM 0x31 /*read security memory of SLE 4442*/
#define WRITE_SECU_MEM 0x39 /*write security memory of SLE 4442*/
#define COMPARE_VERIFY 0x33 /*compare verification data of SLE 4442*/
sfr WDTRST=0x0A6;
/*SLE4442卡校验密码*/
extern unsigned char PassWord[3];
extern unsigned char NewPassWord[3];
//#define PassWord0 0xEF
//#define PassWord1 0x37
//#define PassWord2 0x28
sbit RST_IC=P1^6; /*IC card RESET port*/
sbit CLOCK_PORT=P1^7; /*IC card */
sbit DATA_IC=P1^5; /*IC card DATA port*/
sbit POWER_IC=P1^4; /*port of IC power*/
unsigned char READ_IC_BYTE(void);
void DELAY_1_UNIT(void);
void DELAY_IC_OPERATION(void);
/****************************************************************/
/* SLE4442 子程序 */
/****************************************************************/
/*;============================================================================
; SUBROUTINE_NAME: START_TEST
; 1. FUNCTION: 测试下一个过程的开始
; 2. INPUT: nop
; 3. OUTPUT: nop
; 4. REGISTER USED:
;============================================================================*/
void START_TEST(void){
do {
CLOCK_PORT=1;
DELAY_IC_OPERATION();
CLOCK_PORT=0;
DELAY_IC_OPERATION();
DATA_IC=1;
}
while(DATA_IC==0);
WDTRST=0x1E;
WDTRST=0xE1;
}
/*;============================================================================
; SUBROUTINE_NAME: COMMAND_SEND
; 1. FUNCTION:发送命令字到IC卡
; 2. INPUT: *command 命令字的起始地址指针
; 3. OUTPUT: nop
;============================================================================*/
void COMMAND_SEND(unsigned char *command){
unsigned char BitCount,i;
unsigned char BitData;
DELAY_IC_OPERATION();
DATA_IC=1;
DELAY_IC_OPERATION();
CLOCK_PORT=1;
DELAY_IC_OPERATION();
DATA_IC=0;
DELAY_IC_OPERATION();
CLOCK_PORT=0;
DELAY_IC_OPERATION();
WDTRST=0x1E;
WDTRST=0xE1;
for(i=0;i<3;i++,command++)
{
BitData=*command;
for(BitCount=0;BitCount<8;BitCount++)
{
if(BitData&0x01==1)
DATA_IC=1;
else
DATA_IC=0;
BitData>>=1;
DELAY_IC_OPERATION();
CLOCK_PORT=1;
DELAY_IC_OPERATION();
CLOCK_PORT=0;
DELAY_IC_OPERATION();
WDTRST=0x1E;
WDTRST=0xE1;
}
}
DELAY_IC_OPERATION();
DATA_IC=0;
_nop_(); /*just for delay*/
DELAY_IC_OPERATION();
CLOCK_PORT=1;
_nop_(); /*just for delay*/
DELAY_IC_OPERATION();
DATA_IC=1;
DELAY_IC_OPERATION();
WDTRST=0x1E;
WDTRST=0xE1;
}
/*;============================================================================
; SUBROUTINE_NAME: READ_IC_BYTE
; 1. FUNCTION: 从IC卡读入一个字节
; 2. INPUT: nop
; 3. OUTPUT: nop
; 4. SUB_CALLED:
;============================================================================*/
unsigned char READ_IC_BYTE(void)
{
unsigned char BitCount,BitData;
//DATA_IC=1;
for(BitCount=0;BitCount<8;BitCount++)
{
BitData>>=1;/* >>= 右移位赋值*/
if(DATA_IC==1)
BitData|=0x80;/* |= 逻辑或赋值*/
else
BitData&=0x7F;/* &= 逻辑与赋值,其实它只不过是使I/O产生一个下降沿*/
/*在前面运行的函数中已经有一个下降沿了,所以在该函数中开始的时候
不需要下降沿*/
CLOCK_PORT=1; /*在时钟线上的第一个下降沿到来后,I/O线上的第一个数据位有效*/
DELAY_IC_OPERATION();
CLOCK_PORT=0; /*以上3行产生一个下降沿是I/O口上的数据有效更新*/
DELAY_IC_OPERATION();
WDTRST=0x1E; /*喂狗*/
WDTRST=0xE1;
}
return(BitData);
}
/*;============================================================================
; SUBROUTINE_NAME: WRITE_IC_BYTE
; 1. FUNCTION: 写入一个字节到 SLE4442 MAIN memory
; 2. INPUT: address 数据的写入地址,
; Data 写入的数据数据
; 3. OUTPUT: nop
; 4. REGISTER USED:
; 5. SUB_CALLED:
; WORD1_COMMAND
;============================================================================*/
void WRITE_IC_BYTE(unsigned char address,unsigned Data){
unsigned char command[3];
command[0]=WRITE_MAIN_MEM;
command[1]=address;
command[2]=Data;
COMMAND_SEND(command);
START_TEST();
}
/*;============================================================================
; SUBROUTINE_NAME: WRITE_IC_PROBYTE
; 1. FUNCTION: 写入一个字节到 SLE4442 MAIN memory
; 2. INPUT: address 数据的写入地址,
; Data 写入的数据数据
; 3. OUTPUT: nop
; 4. REGISTER USED:
; 5. SUB_CALLED:
; WORD1_COMMAND
;============================================================================*/
void WRITE_IC_PROBYTE(unsigned char address,unsigned Data){
unsigned char command[3];
command[0]=WRITE_PROT_MEM;
command[1]=address;
command[2]=Data;
COMMAND_SEND(command);
START_TEST();
}
/*;============================================================================
; SUBROUTINE_NAME: RST_AND_ANSWER
; 1. FUNCTION: IC卡复位,检测IC卡的应答.
; 2. INPUT: nop
; 3. OUTPUT: 检测通过,返回1;否则,返回0。
;============================================================================*/
//*
void RST_AND_ANSWER(unsigned char *p){
unsigned char i;
EA=0;
//DATA_IC=0;
RST_IC=0;
DELAY_IC_OPERATION();
CLOCK_PORT=0;
DELAY_IC_OPERATION();
RST_IC=1;
DELAY_IC_OPERATION();
CLOCK_PORT=1;
DELAY_1_UNIT();
CLOCK_PORT=0;
DELAY_IC_OPERATION();
WDTRST=0x1E;
WDTRST=0xE1;
RST_IC=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
for(i=0;i<4;i++)
{
*p++=READ_IC_BYTE();
}
EA=1;
}
//*/
/*;============================================================================
; SUBROUTINE_NAME: READ_EC
; 1. FUNCTION: 读取IC卡错误计数器
; 2. INPUT: *pChar数据输出地址指针
; 3. OUTPUT: 1st byte: EC (pChar, pChar+1, pChar+2, pChar+3)
; 4. SUB_CALLED: COMMAND_SEND, READ_IC_BYTE.
;============================================================================*/
void READ_EC(unsigned char *pChar){
unsigned char ByteCount;
unsigned char WordCommand[3]={ READ_SECU_MEM,0x00,0x00 };
COMMAND_SEND(WordCommand);
CLOCK_PORT=0;
DELAY_IC_OPERATION();
for(ByteCount=0;ByteCount<4;ByteCount++,pChar++)
{
*pChar=READ_IC_BYTE();
}
}
/*;============================================================================
; SUBROUTINE_NAME: VERIFICATION
; 1. FUNCTION: 检测SLE4442的错误计数器,如果计数器的值为非零返回1,否则返回0
; 2. INPUT: nop
; 3. OUTPUT: 输出计数器的值
; 4. REGISTER USED: READ_EC, COMMAND_SEND, START_TEST,
; 5. SUB_CALLED:
;============================================================================*/
/*好像没用*/
/*
bit VERIFICATION(void){
unsigned char Word[4];
unsigned char i;
EA=0;
READ_EC(Word); //read IC card error_counter
if(Word[0]!=0)
{
i=0;
if((Word[0]&0x01)!=0)
i++;
if((Word[0]&0x02)!=0)
i++;
if((Word[0]&0x04)!=0)
i++;
return (i);
}
else
{
return 0;
}
EA=1;
WDTRST=0x1E;
WDTRST=0xE1;
}
//*/
/*;============================================================================
; SUBROUTINE_NAME: COMPARISON_VD
; 1. FUNCTION: 校验4442的写入密码,如果密码正确,返回1;否则返回0
; 2. INPUT: nop
; 3. OUTPUT: OK: return to 1, else return 0
; 4. REGISTER USED:
; 5. SUB_CALLED: COMMAND_SEND, START_TEST, READ_EC
;============================================================================*/
bit COMPARISON_VD(void){
unsigned char Word[4];
unsigned char cData;
unsigned char Check;
EA=0;
START_TEST(); /* test start of processing*/
READ_EC(Word);
cData=Word[0];
if((cData&0x01)!=0)
{
Check=0x06;
goto COMPARISON_Start;
}
else if((cData&0x02)!=0)
{
Check=0x05; /*Check的值要修改为0x04*/
goto COMPARISON_Start;
}
else if((cData&0x04)!=0)
{
Check=0x03; /*Check的值要修改为0x00*/
}
else return 0;
COMPARISON_Start:
Word[0]=WRITE_SECU_MEM;
Word[1]=0x00;
Word[2]=Check;
COMMAND_SEND(Word);
START_TEST(); /*test start of processing*/
Word[0]=COMPARE_VERIFY;
Word[1]=0x01;
Word[2]=PassWord[0];
COMMAND_SEND(Word);
START_TEST();
Word[0]=COMPARE_VERIFY;
Word[1]=0x02;
Word[2]=PassWord[1];
COMMAND_SEND(Word);
START_TEST();
Word[0]=COMPARE_VERIFY;
Word[1]=0x03;
Word[2]=PassWord[2];
COMMAND_SEND(Word);
START_TEST();
Word[0]=WRITE_SECU_MEM;
Word[1]=0x00;
Word[2]=0x0ff;
COMMAND_SEND(Word);
START_TEST(); /* test start of processing*/
READ_EC(Word);
cData=Word[0];
if(cData==0x07)
{
EA=1;
return 1;
/*密码校验通过*/
}
else
{
EA=1;
return 0;
}
}
/*;============================================================================
; SUBROUTINE_NAME: READ_IC_INFOR
; 1. FUNCTION: 读SLE4442的主存储区.
; 2. INPUT: Address 数据的起始地址
; DataNum 数据的个数
; RamAddr 数据存放的地址指针(CPU 内部RAM)
; 3. SUB_CALLED: COMMAND_SEND, READ_IC_BYTE
;============================================================================*/
void READ_IC_INFOR(unsigned char Address,
unsigned char DataNum,
unsigned char ChData[]) /*读主存储器*/
{
unsigned char ByteCount; /*设置要读取的字节数*/
unsigned char WordCommand[3];/*存放命令内容数组*/
WordCommand[0]=READ_MAIN_MEM;/*读主存储器命令的控制字*/
WordCommand[1]=Address; /*读主存储器命令的地址字*/
WordCommand[2]=0x00; /*读主存储器命令的数据字可以不写*/
COMMAND_SEND(WordCommand); /*发送命令到IC卡*/
/*在COMMAND_SEND函数完成后CLOCK_PORT为'1',因此在READ_IC_BYTE
函数中对读取第一位的有效数据时可以不对CLOCK_PORT置'0'*/
CLOCK_PORT=0;/*在时钟线上的第一个下降沿到来后,I/O线上的第一个数据位有效
,方可读位数据*/
for(ByteCount=0;ByteCount<DataNum;ByteCount++)
{
ChData[ByteCount]=READ_IC_BYTE();/*读IC卡主存储数据*/
}
// for(ByteCount=0;ByteCount<255;ByteCount++)
//{ READ_IC_BYTE();
//}
CLOCK_PORT=1; /*增加额外的时钟脉冲,使I/O口成为高阻态*/
_nop_(); /* just for delay*/
_nop_();
_nop_();
_nop_();
CLOCK_PORT=0;
_nop_();
_nop_();
}
/*;============================================================================
; SUBROUTINE_NAME: MODIFY_IC_PSW
; 2. INPUT: 密码存放地址
; 1. FUNCTION: 修改IC卡的密码
; 3. OUTPUT: nop
; 4. REGISTER USED:
; 5. SUB_CALLED: COMMAND_SEND
;============================================================================*/
void MODIFY_IC_PSW(void)
{
unsigned char command[3];
EA=0;
if(COMPARISON_VD()==1)
{
PassWord[0]=NewPassWord[0];
PassWord[1]=NewPassWord[1];
PassWord[2]=NewPassWord[2];
command[0]=WRITE_SECU_MEM;
command[1]=0x00;
command[2]=0x0FF;
COMMAND_SEND(command);
START_TEST();
command[0]=WRITE_SECU_MEM;
command[1]=0x01;
command[2]=PassWord[0];
COMMAND_SEND(command);
START_TEST();
command[0]=WRITE_SECU_MEM;
command[1]=0x02;
command[2]=PassWord[1];
COMMAND_SEND(command);
START_TEST();
command[0]=WRITE_SECU_MEM;
command[1]=0x03;
command[2]=PassWord[2];
COMMAND_SEND(command);
START_TEST();
}
EA=1;
}
/*;=====================================================*/
/* SUBROUTINE_NAME:延时子程序 DELAY 50MS */
/*======================================================*/
void DELAY_1_UNIT(void)
{
unsigned char i,j;
for(i=0;i<8;i++)
for(j=0;j<255;j++)
{
_nop_();
_nop_();
}
}
/*
void DELAY_2(void){
unsigned char i,j;
for(i=0;i<0x80;i++)
for(j=0;j<255;j++)
{
_nop_();
_nop_();
}
}
//*/
/********** IC 操作延时程序************/
void DELAY_IC_OPERATION(void)
{
unsigned char j;
for(j=0;j<4;j++)
{
_nop_();
_nop_();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -