//-----------------------函数声明,变量定义-------------------------------------------- 
//-----------------------函数声明,变量定义-------------------------------------------------------- 
#include <stdio.h> 
#include <intrins.h> 
#include <reg51.h> 
#define uchar unsigned char  
#define uint  unsigned int   
#define    OFF 1 
#define ON    0 
#define True 1 
#define    False 0 
#define RMM_COMM 0x30    //读主存命令字 
#define WMM_COMM 0x38    //写主存命令字 
#define VER_COMM 0x33    //校验密码 
#define RSM_COMM 0x31    //读密码存储区 
#define WSM_COMM 0x39    //写密码存储区 
#define RPM_COMM 0x34    //读保护存储区 
#define WPM_COMM 0x3c    //写保护存储区 
//---------------------------------------------------------------------------- 
//------------------------------------------------------------------------------------ 
//             定义IC卡接口 
sbit IC_RST =P1^0;         // 将p1.0口设定为复位管脚 
sbit IC_CLK =P1^1;        // 用p1.1口模拟时钟口 
sbit IC_IO =P1^2;            // 将p1.2口模拟数据口 
sbit watch_PW =P1^3;        // 将p1.3口作为电源监控,watch_PW=0,设备有损坏 
sbit CT_PW =P1^4;         // 将p1.4口作为电源控制,CT_PW=0接通电源,CT_PW=1断开电源 
sbit IC_INT0 =P3^2;        // P3.2用于检测有无卡插入,检测到低电平,说明有卡插入 
//------------------------------------------------------------------------------------ 
uchar Read_Buffer[16]; 
bit     IC_In_Flag; 
bit        IC_Read_Flag; 
//------------------------------------------------------------------------------------ 
//4442卡底层程序的外部函数声明 
//------------------------------------------------------------------------------------ 
void ReaDMAinMem(uchar addr,uchar idata *pt,uchar count); //读IC卡主存 
void WriteMainMem(uchar addr,uchar idata *pt);        //写IC卡主存 
void ReadProtectMem(uchar idata *pt);                 //读保护存储器 
void ProtectByte(uchar CardAdd,uchar idata *pt);      //保护一字节,注意待保 
//护的字节是已经写入过的,地址只能在保护存储区内 
void SendComm(uchar a,uchar b,uchar c);                      //发送命令 
void ReadMode(uchar idata *pt,uchar count); 
void ProcessMode(void); 
void ResetCard(void); 
void BreakOperate(void); 
void StartComm(void); 
void StopComm(void); 
uchar ReadByte(void); 
void WriteByte(uchar ch); 
void Delay10us(void); 
void Delay5us(void); 
void init(); 
//-------------------------------------------------------------------------------- 
// 函数名称: ResetCard 
// 函数功能: 卡复位子程序 
//------------------------------------------------------------------------------- 
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();        
    temp = ReadByte(); 
    temp = ReadByte(); 
    temp = ReadByte(); 
    temp = ReadByte();   
    IC_CLK = 0;          
    Delay5us();         
    IC_IO  = 1;          
    _nop_();            
    IC_CLK = 0;          
    Delay5us(); 
    } 
//------------------------------------------------------------------------------------- 
// 函数名称: BreakOperate 
// 函数功能: 停止操作 
//----------------------------------------------------------------------------------- 
void BreakOperate(void) 
{ 
     IC_CLK = 0; 
     IC_RST = 0; 
     IC_IO  = 0; 
     Delay5us(); 
     IC_RST = 1; 
     IC_IO  = 1; 
     Delay5us(); 
     IC_RST = 0; 
     Delay5us(); 
     CT_PW = 1; 
} 
//------------------------------------------------------------------------------------ 
// 函数名称: StartComm() 
// 函数功能: 启动I2C总线子程序 
//----------------------------------------------------------------------------------- 
void StartComm(void) 
{ 
    IC_CLK = 0; 
    IC_IO  = 1; 
    Delay5us(); 
    IC_CLK = 1; 
    Delay5us(); 
    IC_IO  = 0; 
    Delay5us(); 
} 
//------------------------------------------------------------------------------- 
// 函数名称: StopComm() 
// 函数功能: 停止I2C总线数据传送子程序 
//----------------------------------------------------------------------------- 
void StopComm(void) 
{ 
    IC_CLK = 0; 
    IC_IO  = 0; 
    Delay5us(); 
    IC_CLK = 1;        //CLK: H 
    Delay5us(); 
    IC_IO  = 1;        //IO : H 
    Delay10us(); 
} 
//----------------------------------------------------------------------------------- 
// 函数名称: ReadByte 
// 返回接收的数据 
// 函数功能: 接收一字节子程序 
//----------------------------------------------------------------------------------- 
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 
// 入口参数: ch 
// 函数功能: 发送一个字节 
//------------------------------------------------------------------------------------ 
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 
// 入口参数: pt地址指针,指向接收缓冲区,count要接收的数据个数 
// 函数功能: 接收n位数据子程序 
//---------------------------------------------------------------------------------- 
void ReadMode(uchar idata *pt,uchar count) 
{ 
    IC_CLK=0; 
    Delay5us(); 
    do 
    { 
        *pt = ReadByte();    //读入一个字节 
        pt++;                //指针加一 
    }while(--count);         //计数器减一,判断 
} 
//------------------------------------------------------------------------ 
// 延时10us子程序,根据系统时钟需要调整 
//------------------------------------------------------------------------ 
void Delay10us(void) 
{ 
    _nop_(); 
    _nop_(); 
    _nop_(); 
    _nop_(); 
    _nop_(); 
    _nop_(); 
} 
//------------------------------------------------------------------------ 
// 延时5us子程序,根据系统时钟需要调整 
//------------------------------------------------------------------------ 
void Delay5us(void) 
{ 
    _nop_(); 
    _nop_(); 
    _nop_(); 
} 
//------------------------------------------------------------------------ 
// 初始化子程序//------------------------------------------------------------------------ 
void init() 
{ 
    IC_INT0 = 1; 
    IC_Read_Flag = True; 
} 
//--------------------------------------------------------------------------------- 
// 函数名称: ReadMainMem() 
// 入口参数:  addr: IC存储区地址; 
//            pt: 地址指针,指向接收缓冲区; 
//            count: 接收数据的个数 
// 函数功能: 读存储区 
//----------------------------------------------------------------------------------- 
void ReadMainMem(uchar addr,uchar idata *pt,uchar count) 
{ 
    SendComm(RMM_COMM,addr,0xff); 
    ReadMode(pt,count); 
    BreakOperate(); 
    IC_Read_Flag = False; 
} 
//----------------------------------------------------------------------------- 
// 函数名称: SendComm() 
// 入口参数:  a: 命令字; 
//            b: 地址; 
//            c: 数据 
// 函数功能: 发送一个完整的命令 
//------------------------------------------------------------------------------- 
void SendComm(uchar a,uchar b,uchar c) 
{ 
    StartComm();          //开始发送命令 
    WriteByte(a);          //a: 发命令字 
    WriteByte(b);          //b: 发地址 
    WriteByte(c);          //c: 发数据 
    StopComm();           //结束发送命令 
} 
main() 
{ 
    init(); 
    if((IC_INT0 == 0)&&(IC_Read_Flag == 1) == 1)   //有卡插入,并且有读标记 
    { 
        CT_PW = 0;                                    //上电 
        Delay10us(); 
        if(IC_Read_Flag == True) 
        { 
            ResetCard();                // 
            ReadMainMem(0xEF,&Read_Buffer[0],16); 
            BreakOperate(); 
            Delay10us(); 
            ResetCard(); 
        } 
        Delay10us(); 
        CT_PW = 1; 
    } 
}