📄 sle4442_b.c
字号:
/*******************************************************************************
* 标题: 蓝海微芯LJD-SY-5200单片机开发系统演示程序 *
* 文件: SLE4442.C *
* 日期: 2006-8-9 *
* 版本: 1.0 *
* 作者: 蓝海微芯 *
* 网站: http://www.ljd-2008.com *
********************************************************************************
* 描述: *
* IC卡程序模块 *
* *
* 30H-----------读主存储区 *
* 34H-----------读保护存储区 *
* 38H-----------写主存储区 *
* 3CH-----------写保护存储区 *
* 31H-----------读保密存储区 *
* 33H-----------比较验证数据 *
* 39H-----------更新保密存储区 *
* *
* *
********************************************************************************
* 【版权】 Copyright(C)微芯科技 http://www.bluemcu.com All Rights Reserved *
* 【声明】 此程序仅用于学习与参考,引用请注明版权和作者信息! *
*******************************************************************************/
#include<reg51.h> /*=== 头文件包含 ===*/
#include<intrins.h>
#include<absacc.h>
#include <IC_CARD_B.h>
#define uchar unsigned char
#define uint unsigned int
bdata uchar wbyte;
sbit wbyte_0=wbyte^0;
uchar RSTANSER[4]; /*4字节复位应答*/
uchar ICCOMMAND[3]; /*3字节命令*/
uchar ICADDRESS; /*1字节地址*/
uchar ICDATAIN; /*1字节数据*/
uchar ICLENTH; /*1字节读写长度*/
uchar ICCODE[3]={0xff,0xff,0xff}; /*3字节密码*/
uchar ICDATA[32]; /*32字节读写数据*/
void icdelay();
void cardpulse();
uchar cardrbyte();
void cardwbyte(uchar ss);
void rst_ans();
void sendcommand(uchar comm,uchar address,uchar odata);
void rdmm();
void rdpm();
void wrmm();
void wrpm();
void rdsm();
uchar rdsm_ec();
void sendpsc();
void wrsm(uchar ec);
void updatepsc();
uchar verifi();
/*main()
{
uchar i;
uchar EOC;
_nop_();
P1_4=1;
P1_4=0;
for(i=0;i<0x20;i++)
ICDATA[i]=0xf0; //要写的数据
EOC=rdsm_ec(); //读错误计数器
EOC=verifi(); //校验密码
EOC=rdsm_ec();
wrmm(); //写主存储区
rdmm(); //再读主存储区
while(1);
}*/
/********************************************************************
函 数 名:icdelay()
功 能:延时10us
说 明:
入口参数:
返 回 值:
设 计:蓝海微芯
***********************************************************************/
void icdelay()
{
_nop_();
_nop_();
_nop_();
_nop_();
}
/********************************************************************
函 数 名:cardpulse()
功 能:产生时钟脉冲
说 明:
入口参数:
返 回 值:
设 计:蓝海微芯
***********************************************************************/
void cardpulse()
{
SCL=1;
icdelay();
SCL=0;
icdelay();
}
/********************************************************************
函 数 名:cardbyte()
功 能:从SLE4442读取一字节数据
说 明:
入口参数:
返 回 值:ACC
设 计:蓝海微芯
***********************************************************************/
uchar cardrbyte()
{
uchar i;
ACC=0;
SDA=1;
for(i=0;i<8;i++)
{
ACC=ACC>>1;
A_7=SDA;
cardpulse();
}
return ACC;
}
/********************************************************************
函 数 名:cardwbyte()
功 能:向SLE4442写一字节命令或数据
说 明:
入口参数:uchar ss
返 回 值:
设 计:蓝海微芯
***********************************************************************/
void cardwbyte(uchar ss)
{
uchar i;
wbyte=ss;
for(i=0;i<8;i++)
{
SDA=wbyte_0;
wbyte=wbyte>>1;
cardpulse();
}
}
/********************************************************************
函 数 名:rst_ans()
功 能:复位与应答(4个字节的复位应答)
说 明:
入口参数:
返 回 值:
设 计:蓝海微芯
***********************************************************************/
void rst_ans()
{
uchar i;
RST=0;
SCL=0;
icdelay();
RST=1;
icdelay();
SCL=1;
icdelay();
SCL=0;
icdelay();
RST=0;
icdelay();
for(i=0;i<4;i++)
RSTANSER[i]=cardrbyte();
}
/********************************************************************
函 数 名:sendcommand()
功 能:发送命令
说 明:3字节 命令字+地址+数据
入口参数:uchar comm uchar address uchar odata
返 回 值:
设 计:蓝海微芯
***********************************************************************/
void sendcommand(uchar comm,uchar address,uchar odata)
{
SCL=1; /*start condition*/
icdelay();
SDA=0;
icdelay();
SCL=0;
cardwbyte(comm);
cardwbyte(address);
cardwbyte(odata);
SCL=0; /*stop condition*/
SDA=0;
icdelay();
SCL=1;
icdelay();
SDA=1;
icdelay();
SCL=0;
icdelay();
}
/********************************************************************
函 数 名:rdmm()
功 能:读主存储区
说 明:将数据读取到数组ICDATA[]
入口参数:
返 回 值:
设 计:蓝海微芯
***********************************************************************/
void rdmm()
{
uchar i;
rst_ans();
sendcommand(0x30,0x20,0);
for(i=0;i<0x20;i++)
ICDATA[i]=cardrbyte();
}
/********************************************************************
函 数 名:rdpm()
功 能:读保护存储区
说 明:
入口参数:
返 回 值:
设 计:蓝海微芯
***********************************************************************/
void rdpm()
{
uchar i;
rst_ans();
sendcommand(0x34,0,0);
for(i=0;i<0x4;i++)
ICDATA[i]=cardrbyte();
}
/********************************************************************
函 数 名:wrmm()
功 能:写主存储区
说 明:
入口参数:
返 回 值:
设 计:蓝海微芯
***********************************************************************/
void wrmm()
{
uchar i,j;
uchar addr=0;
rst_ans();
for(i=0;i<0x20;i++)
{
addr=0x20+i;
sendcommand(0x38,addr,ICDATA[i]);
for(j=0xff;j>0;j--) /*256个时钟脉冲擦除数据*/
cardpulse();
}
}
/********************************************************************
函 数 名:wrpm()
功 能:写保护存储区
说 明:
入口参数:
返 回 值:
设 计:蓝海微芯
***********************************************************************/
void wrpm()
{
uchar i;
rst_ans();
for(i=0;i<0x20;i++)
{
sendcommand(0x3c,i,ICDATA[i]);
for(i=0;i<0xff;i++) /*256个时钟脉冲擦除数据*/
cardpulse();
}
}
/********************************************************************
函 数 名:rdsm()
功 能:读保密存储区
说 明:
入口参数:
返 回 值:
设 计:蓝海微芯
***********************************************************************/
void rdsm()
{
uchar i;
rst_ans();
for(i=0;i<0x20;i++)
sendcommand(0x31,0,0);
for(i=0;i<0x4;i++)
ICDATA[i]=cardrbyte();
}
/********************************************************************
函 数 名:rdsm_ec()
功 能:读错误计数器
说 明:
入口参数:
返 回 值:erro
设 计:蓝海微芯
***********************************************************************/
uchar rdsm_ec()
{
uchar erro;
rst_ans(); /*RSTANSER[]={0xa2,0x13,0x10,0x91}*/
sendcommand(0x31,0,0);
erro=cardrbyte();
return erro;
}
/********************************************************************
函 数 名:wrsm()
功 能:更新保密存储区
说 明:
入口参数:uchar ec
返 回 值:
设 计:蓝海微芯
***********************************************************************/
void wrsm(uchar ec)
{
uchar i;
rst_ans();
sendcommand(0x39,0,ec);
for(i=0xff;i>0;i--) /*256个时钟脉冲擦除数据*/
cardpulse();
}
/********************************************************************
函 数 名:updatepsc()
功 能:更新密码
说 明:
入口参数:
返 回 值:
设 计:蓝海微芯
***********************************************************************/
void updatepsc()
{
uchar i;
uchar j;
rst_ans();
for(i=0;i<0x03;i++)
{
sendcommand(0x39,(i+1),ICCODE[i]);
for(j=0xff;j>0;j--) /*256个时钟脉冲擦除数据*/
cardpulse();
}
}
/********************************************************************
函 数 名:sendpsc()
功 能:比较校验数据
说 明:
入口参数:
返 回 值:
设 计:蓝海微芯
***********************************************************************/
void sendpsc()
{
uchar i;
uchar j;
uchar adrs=0;
rst_ans();
for(i=0;i<0x03;i++)
{
adrs=i+1;
sendcommand(0x33,adrs,ICCODE[i]);
for(j=123;j>0;j--)
cardpulse();
}
}
/********************************************************************
函 数 名:verifi()
功 能:校验密码
说 明:
入口参数:
返 回 值:uchar EC
设 计:蓝海微芯
***********************************************************************/
uchar verifi()
{
uchar EC=0;
uchar temp;
EC=rdsm_ec(); /*读错误计数器*/
EC=EC&0x07;
switch(EC)
{
case 0x00:
break;
case 0x07:
temp=0x03;
break;
case 0x06:
temp=0x02;
break;
case 0x05:
temp=0x01;
break;
case 0x04:
temp=0x00;
break;
case 0x03:
temp=0x01;
break;
temp=0;
}
if(!EC==0)
{
wrsm(temp); /*更新保密存储区*/
sendpsc(); /*比较验证数据*/
wrsm(0x07); /*更新保密存储区*/
EC=rdsm_ec(); /*读错误计数器*/
EC=EC&0x07;
}
return EC;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -