📄 sle4442.c
字号:
#define MAM 0 /*定义主存储器代号*/
#define SCM 1 /*定义加密存储器代号*/
#define PRM 2 /*定义保护存储器代号*/
#define _Nop() _nop_() /*定义空指令*/
#define DELAY5us() _Nop();_Nop();_Nop();_Nop();_Nop();_Nop();_Nop();_Nop();_Nop();_Nop();dog
sbit RST=P1^4;
sbit IO=P1^6;
sbit CLK=P1^5;
uchar xdata sle_pass[3];
/*******************************************************************
起动总线函数
函数原型: void Start_COM();
功能: 启动发送命令起始条件.
********************************************************************/
void Start_COM(void)
{
IO=1; /*发送起始条件的数据信号*/
_Nop();
_Nop();
_Nop();
CLK=1;
DELAY5us(); /*起始条件建立时间大于4.7us,延时*/
IO=0; /*发送起始信号*/
DELAY5us(); /*起始条件锁定时间大于4 s*/
CLK=0; /*钳住总线准备发送或接收数据 */
_Nop();
_Nop();
}
/*******************************************************************
结束总线函数
函数原型: void Stop_COM();
功能: 命令发送结束信号
********************************************************************/
void Stop_COM(void)
{
IO=0; /*发送结束条件的数据信号*/
_Nop(); /*发送结束条件的时钟信号*/
_Nop();
_Nop();
CLK=1; /*结束条件建立时间大于4 s*/
DELAY5us();
IO=1; /*发送总线结束信号*/
_Nop();
_Nop();
}
/*******************************************************************
字节数据传送函数
函数原型: void SendByte(uchar c);
功能: 将数据c 发送出去,可以是命令,也可以是数据
********************************************************************/
void SendByte(uchar c)
{
uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++) /*要传送的数据长度为8 位*/
{
if((c>>BitCnt)&0x01)IO=1; /*判断发送位*/
else IO=0;
_Nop();_Nop();
CLK=1; /*置时钟线为高通知被控器开始接收数据位*/
DELAY5us(); /*保证时钟高电平周期大于4 s*/
CLK=0;
}
}
/*******************************************************************
字节数据接收函数
函数原型: uchar RcvByte();
功能: 用来接收从卡传来的数据
********************************************************************/
uchar RcvByte(void)
{
uchar retc;
uchar BitCnt;
retc=0;
for(BitCnt=0;BitCnt<8;BitCnt++)
{
CLK=0; /*置时钟线为低准备接收数据位*/
IO=1; /*置数据线为输入方式*/
DELAY5us(); /*时钟低电平周期大于4.7 s*/
CLK=1; /*置时钟线为高使数据线上数据有效*/
_Nop();
_Nop();
retc=retc>>1;
if(IO==1)retc=retc+0x80; /*读数据位,接收的数据位放入retc 中 */
_Nop(); _Nop();
}
CLK=0;
_Nop();_Nop();
return(retc);
}
/*******************************************************************
复位和复位响应函数
函数原型 void AnRst();
功能 复位IC 卡并接收响应字节
*******************************************************************/
void AnRst(void)
{
RST=0;
CLK=0;
DELAY5us();
DELAY5us();
RST=1; /*产生复位时序*/
DELAY5us();
CLK=1;
DELAY5us();
DELAY5us();
DELAY5us();
CLK=0;
DELAY5us();
RST=0;
_Nop();
RcvByte(); /*读出32 字节响应数据*/
RcvByte();
RcvByte();
RcvByte();
}
/*******************************************************************
发送4442 处理脉冲函数
函数原型 void WrmOption();
功能 发送处理模式指令后要调用此程序发送脉冲
*******************************************************************/
void WrmOption(void)
{
while(1)
{
CLK=0;
_Nop();_Nop();_Nop();_Nop();_Nop();_Nop();
IO=1;
_Nop();_Nop();
if(IO==1)break; /*没有处理完则继续发送脉冲*/
CLK=1;
_Nop();_Nop();_Nop();_Nop();_Nop();_Nop();
}
}
/*******************************************************************
中止操作函数
函数原型 void BreakN();
功能 中止当前操作
*******************************************************************/
void BreakN(void)
{
CLK=0;
DELAY5us();
RST=1; /*发出中止操作的时序*/
DELAY5us();
RST=0;
}
/*******************************************************************
命令发送函数
函数原型 void SendCOM(ucahr com1,ucahr com2,uchar com3);
功能 负责起动命令发送3 字节命令字
结束命令
*******************************************************************/
void SendCOM(uchar com1,uchar com2,uchar com3)
{
Start_COM();
SendByte(com1); /*连续发送3 字节指令*/
SendByte(com2);
SendByte(com3);
Stop_COM();
}
/*******************************************************************
SLE4442 卡读数据函数
函数原型: bit IRcvdat_4442(uchar area,ucahr addr,uchar num,uchar idata *buf);
功能: 对SLE4442 卡进行读操作area 为存储器类型addr 为起始地址
num 为读取数据字节数buf[]为数据缓冲区指针
说明 操作成功返回1 参数area 错误返回0 使用前用判断卡插好没有
********************************************************************/
bit IRcvdat_4442(uchar area,uchar addr,uchar num,uchar idata *buf)
{
uchar i;
dog;
switch(area)
{
case MAM:
AnRst(); /*复位SLE4442 卡接收复位响应*/
SendCOM(0x30,addr,0x00); /*读主存储器*/
for(i=0;i<num;i++)
{
*buf=RcvByte();
buf++;
}
BreakN();
break;
case SCM:
AnRst();
SendCOM(0x31,0x00,0x00);
for(i=0;i<num;i++)
{
*buf=RcvByte();
buf++;
}
BreakN();
break;
case PRM:
AnRst();
SendCOM(0x34,0x00,0x00);
for(i=0;i<num;i++)
{
*buf=RcvByte();
buf++;
}
BreakN();
break;
default: return(0);
}
return(1);
}
/*******************************************************************
SLE4442 卡写数据函数
函数原型: bit ISenddat_4442(uchar area,ucahr addr,uchar num,uchar buf[]);
功能: 对SLE4442 卡进行写操作area 为存储器类型addr 为起始地址
num 为读取数据字节数buf[]为数据缓冲区指针
说明 操作成功返回1 参数area 错误返回0 使用前用判断卡插好没有
********************************************************************/
bit ISenddat_4442(uchar area,uchar addr,uchar num,uchar idata *buf)
{
uchar i;
dog;
switch(area)
{
case MAM:
AnRst();
for(i=0;i<num;i++)
{
SendCOM(0x38,addr+i,*buf); /*写主存储器*/
buf++;
WrmOption(); /*发送操作脉冲*/
}
break;
case SCM:
AnRst();
for(i=0;i<num;i++)
{
SendCOM(0x39,addr+i,*buf);
buf++;
WrmOption();
}
break;
case PRM:
AnRst();
for(i=0;i<num;i++)
{
SendCOM(0x3c,addr+i,*buf);
buf++;
WrmOption();
}
break;
default: return(0);
}
return(1);
}
/*******************************************************************
SLE4442 卡校验密码函数
函数原型: uchar IChkpsw_4442(uchar psw1,uchar psw2,uchar psw3);
功能: 进行SLE4442 卡进行密码核对核对后方能进行写操作
说明 操作成功返回0x00 卡无效或卡损坏返回0x01,密码错误返
回0x02 卡只剩1 次机会返回0x03.
********************************************************************/
uchar IChkpsw_4442(void)
{
uchar ec;
IRcvdat_4442(SCM,0x00,1,&ec);
switch(ec&0x7)
{
case 1:
case 2:
case 4: return 0x3;
case 3:
case 5: ec=0x1; break;
case 6: ec=0x2; break;
case 7: ec=0x3; break;
default: return 0x1;
}
AnRst();
SendCOM(0x39,0x00,ec); //回写EC 字节
WrmOption();
SendCOM(0x33,0x01,sle_pass[0]);
WrmOption();
SendCOM(0x33,0x02,sle_pass[1]);
WrmOption();
SendCOM(0x33,0x03,sle_pass[2]);
WrmOption();
SendCOM(0x39,0x00,0xff); //修改EC值
WrmOption();
ec=0;
IRcvdat_4442(SCM,0x00,1,&ec);
dog;
if((ec&0x07)!=0x07) return(0x02);
return(0x00);
}
// END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -