打印

共享一下SLE4442IC卡芯片的操作程序,C51的

[复制链接]
7474|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhaoyu2005|  楼主 | 2008-5-29 10:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间需要编写SLE4442的操作程序,想找一个参考一下(公司里有PIC的,但是感觉有点乱,倒是也能参考,并且帮了不少忙),上网上查了一下,只在一个网站上发现有,但是需要缴费注册或者上传10篇高质量的源代码换积分,没办法,只有靠自己了,现在测试通过了,特共享一下,希望用到的少走弯路。

先写一下中间的经历(有表达不清的地方请见谅):

1.写了程序,开始连读都不正确,结果发现读是正确的,只是读的区域不同,所以读到的正确数据与期望的数据不一致,这一点很快解决了

2.接下来是密码校验,弄了两天时间才调好,一直以为是时序问题,昨天才发现是多谢了一行复位代码造成的,是这样的:写数据都先复位,问题就出在在这里,密码校验十一个不能被打断的序列,必须严格按照序列操作,具体看datasheet。

3.最后一步是修改数据,因为修改数据必须在密码校验通过以后才行,这个弄好的快点,因为密码校验过程就有数据修改的部分,既然那个能过,说明程序没有大问题,最后发现,先复位一下就行了。

4.总结一下:每次操作(不论是读、写、修改数据)都要记的复位(使用复位操作)一下,一直到本次操作结束,中间不要复位,尤其是密码校验,其他的没什么难的,只要按照datasheet上的时序就能操作。

5.说一点俺程序的亮点:就是processing mode,datasheet和参考程序都是发送固定个时钟脉冲的,俺改了一下,就是判断是不是仍在processing mode,是的话就一直发时钟脉冲,不是就退出,代码少了,执行的也快

啰嗦了这么多,下面把最重要的部分拿出:

/*-------------------------------------------------------------------
ic卡操作时钟频率必须在7-50kHz,即时钟脉冲宽度在10-71us之间
   操作            命令    地址    数据    执行结果(凡是数据修改或者写入须通过密码验证)
读主存储区:    0x30     0-ff    无效    从输入的地址开始连续读出数据
读保护区:        0x34    无效    无效    连续读出4个字节
读安全区:        0x31    0        无效    连续读出4个字节,第一个为错误计数
修改主存贮区:    0x38    0-ff    有效    将数据写入到输入的地址
写改保护区:    0x3c    0-1f    有效    将数据与输入的地址数据对比,一致后将对应保护位清零
修改安全区:    0x39    0-3        有效    将数据写入到输入的地址,其中错误计数只能从1改为0
比较校验数据:    0x33    1-3        有效    将数据与输入地址的数据对比,全部一致后将错误计数擦除
-------------------------------------------------------------------*/
void ic_clk_delay(void)
        {
         unsigned char i=70;    //使用STC12C5052AD时的值
         //unsigned char i=6;     //使用AT89C2051时的值
         for(;i!=0;i--) ;
        }



/*-------------------------------------------------------------------
IC卡操作启动函数  Ic_clk=1时,Ic_data电平由高向低跳变
-------------------------------------------------------------------*/
void ic_star(void)
        {
         Ic_data=1;
         Data_led=Ic_data;    //映射IC卡数据,驱动发光二极管
         ic_clk_delay();
         Ic_clk=1;
         ic_clk_delay();
         Ic_data=0;
         ic_clk_delay();
         Ic_clk=0;
        }



/*-------------------------------------------------------------------
IC卡操作结束函数  Ic_clk=1时,Ic_data电平由低向高跳变
-------------------------------------------------------------------*/
void ic_stop(void)
        {
         Ic_data=0;
         ic_clk_delay();
         Ic_clk=1;
         ic_clk_delay();
         Ic_data=1;
         Data_led=0;
        }



/*------------------------------------------------------------------
IC卡数据写函数
------------------------------------------------------------------*/
void ic_write(unsigned char in_data)
        {
         unsigned char i;
         for(i=8;i!=0;i--)        //将数据串行输出,低位在前
             {
             Ic_data=(bit)(in_data&0x01);
             in_data>>=1;
             ic_clk_delay();
             Ic_clk=1;
             ic_clk_delay();
             Ic_clk=0;
            }
        }






/*-------------------------------------------------------------------
IC数据读函数
-------------------------------------------------------------------*/
unsigned char ic_reads(void)
        {
         unsigned char i,out_data;
         Ic_clk=0;
         ic_clk_delay();
         for(i=8;i!=0;i--)                    //循环接收IC卡数据
             {
             Ic_clk=1;
             ic_clk_delay();
             out_data>>=1;
             if(Ic_data) out_data|=0x80;    //先接收低位数据
             Ic_clk=0;
             ic_clk_delay();
            }
         return(out_data);                    //返回接收数据
        }




/*-------------------------------------------------------------------
IC卡复位及复位应答
-------------------------------------------------------------------*/
void ic_rest (void)
        {
         Data_led=1;
         Ic_clk=0;
         ic_clk_delay();
         Ic_rest=1;
         ic_clk_delay();
         Ic_clk=1;
         ic_clk_delay();
         Ic_clk=0;
         ic_clk_delay();
         Ic_rest=0;
         ic_clk_delay();
         ic_reads();
         ic_reads();
         ic_reads();
         ic_reads();
         Data_led=0;
        }




/*-------------------------------------------------------------------
发送IC卡操作命令函数
-------------------------------------------------------------------*/
void ic_command(unsigned char command,unsigned char address,unsigned char ic_in_data)
        {
         ic_star();
         ic_write(command);        //发送命令
         ic_write(address);        //发送地址
         ic_write(ic_in_data);    //发送数据
         ic_stop();                //操作命令结束
        }



/*-------------------------------------------------------------------
IC卡读函数
-------------------------------------------------------------------*/
void ic_bytes_read(unsigned char command,unsigned char address,unsigned char number)
        {
         ic_rest();
         ic_command(command,address,0);
         p=parameter_last_time;
         for(;number!=0;number--)
             {
             *p=ic_reads();
             p++;
            }
         p--;
         Ic_clk=1;
         ic_clk_delay();
         Ic_clk=0;
         ic_clk_delay();
         Data_led=0;
        }



/*-------------------------------------------------------------------
IC卡字节修改
-------------------------------------------------------------------*/
void ic_byte_write(unsigned char command,unsigned char address,unsigned char ic_data)
        {
         if(command!=0x39&&command!=0x33) ic_rest();
         ic_command(command,address,ic_data);
         Ic_clk=0;                     //从这一行开始的8行是processing mode
         ic_clk_delay();
         Data_led=1;
         while(!Ic_data)
             {
              Ic_clk=!Ic_clk;
             ic_clk_delay();
            }
         Data_led=0;
        }





/*-------------------------------------------------------------------
IC卡核对密码:
-------------------------------------------------------------------*/
void ic_password_compare(void)
        {
         unsigned char i,data_temp;
         //EA=0;
         ic_bytes_read(0x31,0,4);            //读安全区数据
         data_temp=parameter_last_time[0];
         if(data_temp)                            //判断错误计数器是否为零
             {
             switch(data_temp)
                 {
                 case 1: data_temp=0;break;
                 case 3: data_temp=1;break;
                 case 7: data_temp=3;break;
                 default: data_temp=7;break;
                }
             ic_byte_write(0x39,0,data_temp);    //将错位计数器的一位清零
             for(i=3;i!=0;i--)     ic_byte_write(0x33,(4-i),ic_password[3-i]);    //核对密码
             ic_byte_write(0x39,0,0xff);        //擦除错误计数器
            }
         ic_bytes_read(0x31,0,4);            //读安全区数据
         if(parameter_last_time[0]==7) Ic_password_ok=1;
         //EA=1;
        }

相关帖子

沙发
huangqi412| | 2008-5-29 12:19 | 只看该作者

顶你

使用特权

评论回复
板凳
zgy_1218| | 2012-6-4 13:54 | 只看该作者
你好,我现在也在开发SLE4442卡的产品,但是我用你的程序,怎么都不能读卡,不知道为什么,调试了好几天了也没出结果,不知道能不能指教一下,我的QQ是446854846

使用特权

评论回复
地板
种豆桃花源| | 2013-8-28 15:48 | 只看该作者
读写前进行复位??会不会对卡里面原来的信息由损害,比如卡里面剩余金额什么的。。

使用特权

评论回复
5
NE5532| | 2013-8-28 17:10 | 只看该作者
种豆桃花源 发表于 2013-8-28 15:48
读写前进行复位??会不会对卡里面原来的信息由损害,比如卡里面剩余金额什么的。。 ...

复位是复位地址,请仔细看一下逻辑加密卡的介绍。

使用特权

评论回复
6
alex_li0824| | 2015-11-14 17:40 | 只看该作者
楼主还在线吗?空白卡,需要校验密码吗?

使用特权

评论回复
7
wpppmlah| | 2020-4-3 16:31 | 只看该作者
网上大把的源代码,可以参考一下 https://pan.baidu.com/s/1EK2JqbbYUVvcpfDR051hTg 提取码:n3vd

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

78

主题

2940

帖子

9

粉丝