?? sle4442.c
字號:
#include <stdio.h>
#include <intrins.h>
#include <reg51.h>
#include <sle4442.h>
/*********************************************************************
函 數 名: ReadMainMem()
功 能: 讀ic卡主存
說 明:
調 用:
全局變量:
入口參數: IC卡地址(32 - 255),指向內部RAM的指針,字節數
出口參數:指向內部RAM的指針 *pt
返 回 值: 無
設 計:zhaojunjie 日期:2002-04-24
修 改: 日期:
*********************************************************************/
void ReadMainMem(uchar addr,uchar idata *pt,uchar count)
{
ResetCard();
SendComm(RMM_COMM,addr,0xff);
ReadMode(pt,count);
BreakOperate();
}
/*********************************************************************
函 數 名: WriteMainMem()
功 能: 寫IC卡主存,一次 1Byte
說 明:
調 用:
全局變量:
入口參數: addr: IC卡地址(32 - 255), pt: 指向數據區的指針 i:字節數
出口參數:無
返 回 值: 無
設 計:zhaojunjie 日期:2002-04-24
修 改: 日期:
*********************************************************************/
void WriteMainMem(uchar addr,uchar idata *pt)
{
ResetCard();
SendComm(WMM_COMM, addr, *pt); //寫主存的命令字,地址,數據
ProcessMode();
BreakOperate();
}
/*********************************************************************
函 數 名: ReadProtectMem()
功 能: 讀保護存儲器
說 明:
調 用:
全局變量:
入口參數: 指向直接尋址數據區的指針
出口參數:無
返 回 值: 無
設 計:zhaojunjie 日期:2002-04-24
修 改: 日期:
*********************************************************************/
void ReadProtectMem(uchar idata *pt)
{
ResetCard();
SendComm(RPM_COMM,0xff,0xff); //讀保護存儲器的命令字,后兩個參數忽略
ReadMode(pt,4); //讀出
BreakOperate();
}
/*********************************************************************
函 數 名: ProtectByte()
功 能: 保護一字節,注意待保護的字節是已經寫入過的,地址只能在保護存儲區內
說 明:
調 用:
全局變量:
入口參數: IC卡地址,指向直接尋址數據區的指針
出口參數:無
返 回 值: 無
設 計:zhaojunjie 日期:2002-04-24
修 改: 日期:
*********************************************************************/
void ProtectByte(uchar addr,uchar idata *pt)
{
ResetCard();
SendComm(WPM_COMM, addr, *pt); //寫保護存儲區的命令字,地址,數據
ProcessMode();
BreakOperate();
}
/*********************************************************************
函 數 名: SendComm()
功 能: 發送命令
說 明:
調 用:
全局變量:
入口參數: a: 命令字, b: 地址, c: 數據
出口參數:無
返 回 值: 無
設 計:zhaojunjie 日期:2002-04-24
修 改: 日期:
*********************************************************************/
void SendComm(uchar a,uchar b,uchar c)
{
StartComm(); //開始發送命令
WriteByte(a); //a: 發命令字
WriteByte(b); //b: 發地址
WriteByte(c); //c: 發數據
StopComm(); //結束發送命令
}
/*********************************************************************
函 數 名: StartComm()
功 能: 開始命令模式
說 明: (內部函數)
調 用:
全局變量:
入口參數: 無
出口參數:無
返 回 值: 無
設 計:zhaojunjie 日期:2002-04-24
修 改: 日期:
*********************************************************************/
void StartComm(void)
{
IC_CLK = 0;
IC_IO = 1;
Delay5us();
IC_CLK = 1;
Delay5us();
IC_IO = 0;
Delay5us();
}
/*********************************************************************
函 數 名: StopComm()
功 能: 結束命令模式
說 明: (內部函數)
調 用:
全局變量:
入口參數: 無
出口參數:無
返 回 值: 無
設 計:zhaojunjie 日期:2002-04-24
修 改: 日期:
*********************************************************************/
void StopComm(void)
{
IC_CLK = 0;
IC_IO = 0;
Delay5us();
IC_CLK = 1; //CLK: H
Delay5us();
IC_IO = 1; //IO : H
Delay10us();
}
/*********************************************************************
函 數 名: ResetCard()
功 能: 卡復位和復位應答
說 明: (內部函數)
調 用:
全局變量:
入口參數: 無
出口參數:無
返 回 值: 無
設 計:zhaojunjie 日期:2002-04-24
修 改: 日期:
*********************************************************************/
void ResetCard(void)
{
uchar temp;
Delay5us();
IC_RST = 0;
IC_CLK = 0;
IC_IO = 1;
Delay5us();
IC_RST = 1;
Delay5us();
IC_CLK = 1;
Delay10us();
Delay10us();
Delay10us();
Delay10us();
IC_CLK = 0;
Delay5us();
IC_RST = 0;
Delay10us(); //復位和復位應答時序
// ___
//RST _| |_______________________
// _ _ __ __
//CLK __|0|_|1|_ ..._|31|_|32|_____
// _ __ __ ___ _____
// \/ \/D0\ ... \/D31\/
//I/O _/\__/\__/ /\___/
temp = ReadByte();
temp = ReadByte();
temp = ReadByte();
temp = ReadByte(); //空讀 32Bit (4Byte)
IC_CLK = 0; // __ __ IC sets I/O to state H
Delay5us(); //CLK_|31|_|32|______________
IC_IO = 1; // __ ___ ____________
_nop_(); // 30 \/ 31\/
IC_CLK = 0; //I/O __ /\___/
Delay5us();
}
/*********************************************************************
函 數 名: BreakOperate()
功 能: SLE/4442 IC卡操作中止
說 明: (內部函數)
調 用:
全局變量:
入口參數: 無
出口參數:無
返 回 值: uchar
設 計:zhaojunjie 日期:2002-04-24
修 改: 日期:
***********************************************************************/
void BreakOperate(void)
{
IC_CLK = 0;
IC_RST = 0;
IC_IO = 0;
Delay5us();
IC_RST = 1;
IC_IO = 1;
Delay5us();
IC_RST = 0;
Delay5us();
}
/*********************************************************************
函 數 名: ReadByte()
功 能: 從SLE4442讀一個字節
說 明: (內部函數)
調 用:
全局變量:
入口參數: 無
出口參數:無
返 回 值: uchar
設 計:zhaojunjie 日期:2002-04-24
修 改: 日期:
***********************************************************************/
uchar ReadByte(void)
{
uchar i,ch;
ch = 0;
for (i = 8; i > 0; i--)
{
IC_CLK = 0;
ch = ch >> 1; //從低位讀起
if((uchar)IC_IO)
ch |= 0x80;
Delay5us();
IC_CLK = 1;
Delay5us();
}
return ch;
}
/*********************************************************************
函 數 名: WriteByte()
功 能: 往SLE4442寫一個字節
說 明: (內部函數)
調 用:
全局變量:
入口參數: uchar
出口參數:無
返 回 值: 無
設 計:zhaojunjie 日期:2002-04-24
修 改: 日期:
***********************************************************************/
void WriteByte(uchar ch)
{
uchar i;
for(i = 8; i > 0; i--)
{
IC_CLK = 0;
IC_IO = (bit)(ch & 0x01);
Delay5us();
IC_CLK = 1;
Delay10us();
ch = ch >> 1; //右移一位
}
}
/*********************************************************************
函 數 名: ReadMode()
功 能: 連續輸入i(=<255)個字節,存放到以pt開頭的內部單元中,必須在某一讀數據命令模式之后使用
說 明: (內部函數)
調 用:
全局變量:
入口參數: pt: 起始地址, count: 數據個數
出口參數:無
返 回 值: 無
設 計:zhaojunjie 日期:2002-04-24
修 改: 日期:
*********************************************************************/
void ReadMode(uchar idata *pt,uchar count)
{
IC_CLK=0;
Delay5us();
do
{
*pt = ReadByte(); //讀入一個字節
pt++; //指針加一
}while(--count); //計數器減一,判斷
}
/*********************************************************************
函 數 名: ProcessMode()
功 能: 處理模式,開始處理模式后,卡片將輸入口拉低,處理完后輸入口變成高電平
說 明: (內部函數)
調 用:
全局變量:
入口參數: 無
出口參數:無
返 回 值: 無
設 計:zhaojunjie 日期:2002-04-24
修 改: 日期:
*********************************************************************/
void ProcessMode(void)
{
uint i;
IC_CLK = 0;
Delay5us();
IC_IO = 0;
for (i = 255; i > 0; i--)
{
IC_CLK = 1;
Delay5us();
IC_CLK = 0;
Delay5us();
}
IC_IO = 1;
}
/*********************************************************************
函 數 名: Verify()
功 能: 校驗密碼
說 明:
調 用:
全局變量:
入口參數: 指向存放密碼的內部直接尋址RAM地址,
密碼:BCD 碼,從低往高放,比如:114086 *pt = 0x11 *pt+1 = 0x40 *pt+2 = 0x86
出口參數:無
返 回 值: 成功返回1,失敗返回0,卡片已鎖也返回0
設 計:zhaojunjie 日期:2002-04-24
修 改: 日期:
*********************************************************************/
bit Verify(uchar idata *pt)
{
uchar idata temp[4]; //暫存4字節的保密區內容
uchar i;
SendComm(RSM_COMM,0xff,0xff); //讀密碼存儲區的命令字,第2,3個參數在此命令中被忽略
ReadMode(temp, 4); //讀出
if((temp[0] & 0x07) != 0) //第一字節是錯誤計數器,如果錯誤計數器為0,直接退出
{
if((temp[0] & 0x07)==0x07) // 00000111
i = 0x06;
else if((temp[0] & 0x07)==0x06)// 00000110
i = 0x04;
else if((temp[0] & 0x07)==0x04)// 00000100
i = 0x00; //將其中一位為1的改為0
SendComm(WSM_COMM,0,i); //修改錯誤計數器
ProcessMode(); //處理
for (i = 1; i < 4; i++, pt++) //校對3字節的密碼
{
SendComm(VER_COMM,i,*pt); //發出校對命令,
ProcessMode(); //處理
}
SendComm(WSM_COMM,0,0xff); //擦除計數器恢復錯誤計數器
ProcessMode(); //處理
SendComm(RSM_COMM,0xff,0xff); //讀密碼存儲區的命令字,第2,3個參數在此命令中被忽略
ReadMode(temp, 4); //讀錯誤計數器的內容
if((temp[0] & 0x07)==0x07) //如果沒有被成功擦除,表明校對失敗
return 1 ;
}
return 0;
}
/********************************************************************
函 數 名:Delay10us()
功 能:延時10微秒(包括調用和返回的時間),f = 11.0592Mhz
說 明:
調 用:
入口參數:無
出口參數:無
返 回 值:無
設 計:zhaojunjie 日 期:2002-04-24
修 改: 日 期:
***********************************************************************/
void Delay10us(void)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
/********************************************************************
函 數 名: Delay5us()
功 能:延時10微秒(包括調用和返回的時間),f = 11.0592Mhz
說 明:
調 用:
入口參數:無
出口參數:無
返 回 值:無
設 計:zhaojunjie 日 期:2002-04-24
修 改: 日 期:
***********************************************************************/
void Delay5us(void)
{
_nop_();
_nop_();
_nop_();
}
/*//////////////////////////////////////////////////////////////////////*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -