/* iccard.h
前一阵子做了个IC卡读写程序,可以读写SLE4442系统逻辑加密卡的,本来想在网上找一个,没找到,自己写了一个,为了让后来人可以轻松一点,所以就奉献给大家:)
注释比较少(本人的坏习惯),看起来有点累,不过建议你在自己看之前先熟悉一下SLE4442的协议。
程序是经过测试的,在我的931上工作的很好,有什么问题,发信给我
Ploto_zhu@etang.com
*/
#ifndef IC_CARD_H
#define IC_CARD_H
#include <REG931.H>
#define RdMainMem 0x30 // outgoing data
#define UpdMainMem 0x38 // processing
#define RdPrtMem 0x34 // outgoing data
#define WrPrtMem 0x3C // processing
#define RdSecMem 0x31 // outgoint data
#define UpdSecMem 0x39 // processing
#define CmpVerDat 0x33 // processing
sbit CCIO = P0^3;
sbit CCRST = P0^1;
sbit CCCLK = P0^2;
sbit CCIN = P2^7;
#ifndef uchar
#define uchar unsigned char
#endif
void IC_Reset(uchar *buffer);
void ReadMainMemory(uchar addrFrom,uchar* buffer,uchar ulen);
void ReadProtectedMem(uchar rdBuf[4]) ;
void UpdateMainMemory(uchar addr,uchar value) ;
void WriteProtectedMem(uchar addr, uchar value) ;
void ReadSecMemory(uchar buffer[4]) ;
void UpdateSecMem(uchar addr, uchar value) ;
bit CompareVerifData(uchar value[3]) ;
#endif
/* --------------------- ICCard.c ----------*/
#include "iccard.h"
#include <REG931.H>
/* 2005-9-4 常州中天科技有限公司 祝启忠*/
#ifndef uchar
#define uchar unsigned char
#endif
//sbit CCRST=P0^1;
//sbit CCCLK=P0^2;
//sbit CCIO=P0^3;
//void sendtoPC(uchar*);
//void sendBuffer(char* buf,char len) ;
void Delay(int x)
{
int i;
for(i=(x<<1);i>0;i--);
}
void OnePlus()
{
CCCLK=1;
Delay(20);
CCCLK=0;
Delay(20);
}
unsigned char ReadByte()
{
uchar TempByte;
uchar Value;
uchar i;
Value=0;
for(i=0;i<8;i++)
{
CCCLK=1;
TempByte=(unsigned char)CCIO;
Delay(10);
CCCLK=0;
Delay(10);
Value |= (TempByte<<i);
}
return Value;
}
void ICSendByte(uchar byte)
{
uchar TempByte;
uchar i;
for(i=0;i<8;i++)
{
TempByte= ((byte>>i) & 0x01);
CCIO=(bit)TempByte;
Delay(8);
CCCLK=1;
Delay(10);
CCCLK=0;
Delay(8);
}
}
void IC_Reset(uchar *buffer)
{
uchar len;
CCCLK=0;
CCRST=0;
CCIO=1;
Delay(800);
CCRST=1;
Delay(10);
CCCLK=1;
Delay(10);
CCCLK=0;
Delay(50);
CCRST=0;
Delay(10);
for(len = 0;len <4;len++)
buffer[len]=ReadByte();
}
void SendCommand(uchar Cmd[3])
{
uchar i;
//start condition
//当时钟线为高的时候,IO线从1到0
CCCLK=0;
CCIO=1;
Delay(4);
CCCLK=1;
Delay(8);
CCIO=0;
Delay(8);
CCCLK=0;
Delay(5); //start condition
//data
//IC卡在时钟的上升沿读取数据
for(i=0;i<3;i++)
ICSendByte(Cmd[i]);
//stop condition
//当时钟线为高的时候, IO从0到1
CCIO=0;
Delay(10);
CCCLK=1;
Delay(10);
CCIO=1;
//命令发送结束
Delay(10);
}
//读取主存储器
void ReadMainMemory(uchar addrFrom,uchar* buffer,uchar ulen)
{
unsigned int len;
uchar buf[3];
buf[0]=RdMainMem;
buf[1]=addrFrom;
buf[2]=0;
SendCommand(buf);
// sendtoPC(" send ok");
//开始读取数据
CCCLK=0;
Delay(10);
for(len=0;len<256-addrFrom;len++)
{
if(len < ulen)
{
buffer[len]=ReadByte();
// sendBuffer(&buffer[len],1);
}
else
{
buf[0]=ReadByte();
// sendBuffer(buf,1); //要给脉冲,但丢弃数据
}
}
// sendtoPC("Read OK");
// 给个结束标志
OnePlus();
}
//读取保护内容,一共32位,4个字节
void ReadProtectedMem(uchar rdBuf[4])
{
uchar len;
uchar buf[3];
buf[0]=RdPrtMem;
buf[1]=buf[2]=0;//addrFrom;
SendCommand(buf);
//开始读取数据
CCCLK=0;
Delay(10);
for(len=0;len<4;len++)
{
rdBuf[len]=ReadByte();
}
// 给个结束标志
OnePlus();
}
//更新主存储器的内容
void UpdateMainMemory(uchar addr,uchar value)
{
uchar len;
uchar buf[3];
buf[0]=UpdMainMem;
buf[1]=addr;
buf[2]=value;
SendCommand(buf);
//给脉冲
CCCLK=0;
Delay(10);
CCIO=0;
Delay(10);
for(len=0;len<254;len++)
{
OnePlus();
}
CCIO=1;
Delay(10);
OnePlus();
// OnePlus();
}
//更新保护存储器中的内容
void WriteProtectedMem(uchar addr, uchar value)
{
uchar len;
uchar buf[3];
buf[0]=WrPrtMem;
buf[1]=addr;
buf[2]=value;
SendCommand(buf);
//给脉冲
CCCLK=0;
Delay(3);
CCIO=0;
Delay(10);
for(len=0;len<254;len++)
{
OnePlus();
}
CCIO=1;
Delay(10);
OnePlus();
}
//读取安全区的内容
void ReadSecMemory(uchar buffer[4])
{
uchar len;
uchar buf[3];
buf[0]=RdSecMem;
buf[1]=buf[2]=0xff;//addrFrom;
SendCommand(buf);
//开始读取数据
CCCLK=0;
Delay(10);
for(len=0;len<4;len++)
{
buffer[len]=ReadByte();
}
// 给个结束标志
CCIO=1;
Delay(10);
OnePlus();
}
//更新安全区的内容
void UpdateSecMem(uchar addr, uchar value)
{
uchar len;
uchar buf[3];
buf[0]=UpdSecMem;
buf[1]=addr;
buf[2]=value;
SendCommand(buf);
//给脉冲
CCCLK=0;
Delay(10);
CCIO=0;
Delay(10);
for(len=0;len<254;len++)
{
OnePlus();
}
CCIO=1;
Delay(10);
OnePlus();
}
//比较密码
bit CompareVerifData(uchar value[3])
{
uchar len;
uchar buf[4];
ReadSecMemory(buf);
if(buf[0]== 0)
return 0;
//正确,计数一次
// if(buf[0]
for(len =0;len <3;len++)
if(buf[0] & (1 << len) )
{
buf[0] &= ~(1<<len);
break;
}
UpdateSecMem(0,buf[0]);
// sendtoPC("Update OK");
for(len = 0;len < 3;len++)
{
buf[0]=CmpVerDat;
buf[1]=len+1;
buf[2]=value[len];
SendCommand(buf);
//给脉冲
CCCLK=0;
// Delay(5);
CCIO=0;
Delay(10);
OnePlus();
OnePlus();
CCIO=1;
Delay(10);
OnePlus();
}
UpdateSecMem(0,0xff);
ReadSecMemory(buf);
if(buf[0] & 0x07 == 0x07)
return 1;
else
return 0;
}
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【笔记】生成报错synthdesignERROR被打赏50分 | |
【STM32H7S78-DK评测】LTDC+DMA2D驱动RGBLCD屏幕被打赏50分 | |
【STM32H7S78-DK评测】Coremark基准测试被打赏50分 | |
【STM32H7S78-DK评测】浮点数计算性能测试被打赏50分 | |
【STM32H7S78-DK评测】Execute in place(XIP)模式学习笔记被打赏50分 | |
每周了解几个硬件知识+buckboost电路(五)被打赏10分 | |
【换取逻辑分析仪】RA8 PMU 模块功能寄存器功能说明被打赏20分 | |
野火启明6M5适配SPI被打赏20分 | |
NUCLEO-U083RC学习历程2-串口输出测试被打赏20分 | |
【笔记】STM32CUBEIDE的Noruletomaketarget编译问题被打赏50分 |