Mini板调试SLE4442智能IC卡问题

2019-08-14 17:44发布

最近搞一个智能卡的项目,焦头烂额了@正点原子
自己写的程序,读RAM没有问题,读出数据前48Byte如下:
a2 13 10 91 ff ff 81 15 ff ff ff ff ff ff ff ff
ff ff ff ff ff d2 76 0 0 4 0 ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff (后面全FF)

读密码计数器为0x07 00 00 00
在进行密码校验的时候,写密码计数器一位为0,也是正常的,但是写校验和后面恢复密码计数器的时候就总不成功,用原子哥之前提供的读写程序(原帖http://www.openedv.com/forum.php ... &highlight=4442),读书全是FF,密码校验也不对。贴出程序,给大家看一下,帮忙研究一下,谢谢诸位
[mw_shl_code=applescript,true]
#include "ic_card.h"
#include "delay.h"

//通讯接口初始化
void IC_CardInit()
{
        GPIO_InitTypeDef GPIO_InitStructre;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
        GPIO_InitStructre.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_11|GPIO_Pin_12;
        GPIO_InitStructre.GPIO_Mode=GPIO_Mode_Out_PP;
        GPIO_InitStructre.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOC,&GPIO_InitStructre);
        PCout(4)=0;
        PCout(11)=0;
        PCout(12)=0;
        delay_ms(20);
        IC_Rest();
}

//通讯起始信号
void IC_Start(void)
{
        SDA_OUT();                //设置IO为输出
        CLK=1;
        SDO=1;
        delay_us(4);
        SDO=0;                        //在CLK为高电平时,IO由高到低变化为起始
        delay_us(4);
        CLK=0;               
}
//结束信号       
void IC_Stop(void)
{
        SDA_OUT();                //设置IO为输出
        CLK=1;
        SDO=0;
        delay_us(4);
        SDO=1;                        //在CLK为高的时候,IO由低到高变化为结束
        delay_us(4);
        CLK=0;
}
//发送一个字节数据
//data:要发送的数据
void IC_SendData(u8 data)
{
        u8 t;
        SDA_OUT();                //设置IO为输出模式
        for(t=0;t<8;t++)
        {
                CLK=0;
                if(data&0x01)
                        SDO=1;
                else SDO=0;
                data>>=1;                //低位先发
                delay_us(2);
                CLK=1;
                delay_us(2);
                CLK=0;
                delay_us(2);
        }
}
//读一个字节数据
//返回值:读取的数据
u8 IC_ReadData(void)
{
        u8 t,temp=0;
        SDA_IN();
        for(t=0;t<8;t++)
        {
                temp>>=1;
                CLK=0;
                delay_us(2);
                CLK=1;
                if(SDI)
                        temp|=0x80;
                delay_us(2);
                CLK=0;
        }
        return temp;
}
//操作终止函数
void IC_Break(void)
{
        SDA_OUT();
        SDO=0;
        CLK=0;
        RST=0;
        delay_us(2);
        RST=1;
        SDO=1;
        delay_us(10);               
        RST=0;                        //在CLK为低电平时,RST由高(保持5us)到低变化,产生复位
}
//芯片复位信号,ISO7816-3标准
//开始时,IO保持低电平,RST由低电瓶变为高电平,在高电平期间,给予一个CLK脉冲。
//此时,IO输出了一个有效的低电平信号,伺候连续读取4个Byte字节数据,读出EEPROM中
//4个字节标头数据,最后再给予一个CLK脉冲,使IO进入高阻状态
void IC_Rest(void)
{
        SDA_OUT();
        CLK=0;
        SDO=1;
        RST=0;
        delay_us(5);
        RST=1;
        delay_us(5);
        CLK=1;
        delay_us(20);
        CLK=0;
        delay_us(5);
        RST=0;
        delay_us(5);
        IC_ReadData();
        IC_ReadData();
        IC_ReadData();
        IC_ReadData();
        CLK=1;
        delay_us(5);
        CLK=0;
        SDA_OUT();
}
//等待内部处理函数,开始时,有外部拉低,处理完成后拉高
//擦除和写入(5ms)                相当于255个CLK
//只写不擦(2.5)                        相当于124个CLK
//只擦不写(2.5)                        相当于124个CLK
u8 IC_WaitProcessing(void)
{
        u16 i;
        SDA_IN();
        while(SDI)
        {
                i++;
                CLK=0;
                delay_us(2);
                CLK=1;
                delay_us(2);
                if(i>255)
                        return 1;
        }
        SDA_OUT();
        return 0;
}
//写入一个字节命令
//command:写入模式命令
//add:写入地址
//data:写入数据
void IC_WriteOneByte(u8 command,u8 add,u8 data)
{
        IC_Start();
        IC_SendData(command);       
        IC_SendData(add);
        IC_SendData(data);                //连续发送24bit数据
        IC_Stop();
        IC_WaitProcessing();        //内部处理中
}
//连续写内存
//command:写入模式命令
//add:写入起始地址
//data:写入数据存放数组地址
//len:要写入长度
void IC_WrtieRAM(u8 command,u8 add,u8* data,u8 len)
{
        u8 i;
        for(i=0;i<len;i++)
        {
                IC_WriteOneByte(command,add,data);
                add++;
        }
}
//读取一个字节数据
//command:读取模式命令
//add:读取地址
//返回值:读取数据
u8 IC_ReadOneByte(u8 command,u8 add)
{
        u8 temp;
        IC_Start();
        IC_SendData(command);
        IC_SendData(add);
        IC_SendData(0xFF);                //该字节数据无效
        temp=IC_ReadData();
        IC_Stop();
        IC_Break();                                //结束等待下次通讯
        return temp;
}
//连续读取多个字节数据
//command:读取模式命令
//add:读取目标首地址
//table:存放读取数据的数组首地址
//len:要读取的数据长度
void IC_ReadRAM(u8 command,u8 add,u8* table,u16 len)
{
        u16 i;
        IC_Start();
        IC_SendData(command);
        IC_SendData(add);
        IC_SendData(0xFF);        //该字节无效
        IC_Stop();
        for(i=0;i<len;i++)        //可连续读取数据
        {
                table=IC_ReadData();
        }
        IC_Break();                        //结束等待下次通讯
}
//输入密码比较
//password:24位密码
//返回值:0,密码错误;1,密码正确
u8 IC_PasswordCheck(u32 password)
{
        u8 temp[4];
        u8 t;
        u8 p;
        IC_ReadRAM(ReadSafRAM,0xFF,temp,4);                //读取保护区4个字节数据,后三个为密码
        if((temp[0]&0x07)!=0)                                        //第一个数据为密码计数器,如果密码计数器不为0,可进行比对
        {
                if((temp[0]&0x07)==0x07)                        //每比对一次,密码计数器减少一次,从最低位开始减
                        t=0x06;
                else if((temp[0]&0x07)==0x06)
                        t=0x04;
                else if((temp[0]&0x07)==0x04)
                        t=0;
//                IC_Rest();
                IC_WriteOneByte(WriteSafRAM,0,t);        //减少一次的密码计数器写入到存储器中
                for(t=1;t<4;t++)                                        //将输入的密码写入安全校验寄存器中进行校验
                {
                        IC_WriteOneByte(0x33,t,0xFF);
                }
                IC_WriteOneByte(WriteSafRAM,0,0xFF);
                IC_WriteOneByte(WriteSafRAM,0,0xFF);
                IC_ReadOneByte(ReadSafRAM,0);
                IC_ReadRAM(ReadSafRAM,0xFF,temp,4);
                p=temp[0];
                if((p&0x07)==0x07)
                        return 1;
        }
        return 0;
}




[/mw_shl_code]

另外还有一种卡接口芯片TDA8024、DS8113等,有没有谁使用过,我看了半天表示不知道单片机和芯片怎么通讯的,芯片和单片机的接口数据只有一个IO脚没有CLK,有没有大神给个提示
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。