打印
[STM32F1]

三问读取SIM卡的问题

[复制链接]
2804|29
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
JY-DX-JY|  楼主 | 2015-6-11 12:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用STM32F103C8T6读取SIM卡,前面都没问题,就是这个地方
static uint8_t SC_decode_Answer2reset(uint8_t *card)
{
  uint32_t i = 0, flag = 0, buf = 0, protocol = 0;
  SC_A2R.TS = card[0];  /* Initial character */  //0X3B
  SC_A2R.T0 = card[1];  /* Format character */  //0X1A
  SC_A2R.Hlength = SC_A2R.T0 & (uint8_t)0x0F;

  if ((SC_A2R.T0 & (uint8_t)0x80) == 0x80)
  {
    flag = 1;
  }
  for (i = 0; i < 4; i++)
  {
    SC_A2R.Tlength = SC_A2R.Tlength + (((SC_A2R.T0 & (uint8_t)0xF0) >> (4 + i)) & (uint8_t)0x1);
  }
///////////////////



  for (i = 0; i < SC_A2R.Tlength; i++)
  {
    SC_A2R.T = card[i + 2];
  }
  protocol = SC_A2R.T[SC_A2R.Tlength - 1] & (uint8_t)0x0F;                                                          //这个地方计算出protocol=0x01,可是=0x00才是T0协议。

USART_SendData(USART1,protocol );
for(ii=3000;ii>0;ii--);

  while (flag)
  {
    if ((SC_A2R.T[SC_A2R.Tlength - 1] & (uint8_t)0x80) == 0x80)
    {
      flag = 1;
    }
    else
    {
      flag = 0;
    }
    buf = SC_A2R.Tlength;
    SC_A2R.Tlength = 0;
    for (i = 0; i < 4; i++)
    {
      SC_A2R.Tlength = SC_A2R.Tlength + (((SC_A2R.T[buf - 1] & (uint8_t)0xF0) >> (4 + i)) & (uint8_t)0x1);
    }
    for (i = 0;i < SC_A2R.Tlength; i++)
    {
      SC_A2R.T[buf + i] = card[i + 2 + buf];
    }
    SC_A2R.Tlength += (uint8_t)buf;
  }
  for (i = 0; i < SC_A2R.Hlength; i++)
  {
    SC_A2R.H = card[i + 2 + SC_A2R.Tlength];
  }
  return (uint8_t)protocol;
}
前面发帖子已经证明就是T0协议,可是为什么译码后是0x01呢?请问大神,哪里出错了?谢谢!
沙发
JY-DX-JY|  楼主 | 2015-6-11 12:57 | 只看该作者
高手支招啊!

使用特权

评论回复
板凳
JY-DX-JY|  楼主 | 2015-6-11 15:10 | 只看该作者
大神救命啊!

使用特权

评论回复
地板
JY-DX-JY|  楼主 | 2015-6-11 15:10 | 只看该作者
大神救命啊!

使用特权

评论回复
5
JY-DX-JY|  楼主 | 2015-6-11 15:26 | 只看该作者
case SC_RESET_LOW:
      if(SC_ADPU->Header.INS == SC_GET_A2R)
      {
        /* If card is detected then Power ON, Card Reset and wait for an answer) */
        if (SC_Detect())
        {
          while(((*SCState) != SC_POWER_OFF) && ((*SCState) != SC_ACTIVE))
          {
            SC_AnswerReq(SCState, &SC_ATR_Table[0], 40); /* Check for answer to reset */
          }
        }
        else
        {
          (*SCState) = SC_POWER_OFF;
        }
      }
    break;
STM32库里面原来是这样的,
我把  if (SC_Detect())
改为  if (SC_Detect()==0)了,不知会不会有影响?

使用特权

评论回复
6
JY-DX-JY|  楼主 | 2015-6-11 16:20 | 只看该作者
没人理我的帖子,自己顶一下。

使用特权

评论回复
7
JY-DX-JY|  楼主 | 2015-6-11 17:33 | 只看该作者
有没有搞STM32读取SIM卡的朋友?

使用特权

评论回复
8
JY-DX-JY|  楼主 | 2015-6-11 20:54 | 只看该作者
又沉了。

使用特权

评论回复
9
FireRiver9| | 2015-6-11 21:08 | 只看该作者
帮你顶起,大家讨论

使用特权

评论回复
10
泰山特曲123| | 2015-6-11 23:44 | 只看该作者
与其在这里乱求助,不如自己踏踏实实看资料,检查代码

使用特权

评论回复
11
JY-DX-JY|  楼主 | 2015-6-12 08:49 | 只看该作者
泰山特曲123 发表于 2015-6-11 23:44
与其在这里乱求助,不如自己踏踏实实看资料,检查代码

怎么叫乱求助?我的是官网例程,难道有错?

使用特权

评论回复
12
LZR13179| | 2015-6-12 09:06 | 只看该作者
不一定要要使用iuart的iso7816模式,我以前利用定时器和普通的io可以模拟出ISO7816的。其实7816是uart的变异来的。
也弄过使用一些普通uart(单线模式)直接模拟出7816来的。认真的先去看我之前发的那个文档。


深入理解7816(1)---- 关于F/D和etu
对于刚接触智能卡的工程师来说,在阅读7816-3规范的时候,常常被其中的一些术语迷惑,读起来会觉得有些别扭。尤其是在看到复位应答中的F和D设置以及对应的etu的时候,会觉得有些复杂和难以理解。
其实从本质上说7816-3定义了智能卡(这里指的是接触式CPU卡,对于逻辑加密卡以及非接触IC卡不在此列)和读写设备之间的通讯协议,说白了就是数据位传输的格式。
如果学习或者接触过单片机,那么对于RS232一定不会陌生,它属于异步串行通讯接口(UART),通过RxD、TxD进行数据的收发,RS232曾经是PC机的标配,但是目前在多数PC上基本不复存在了(当然还可以通过USB-232转换器来扩展)。
接下来我们看看7816-3定义的通讯协议,其实基本上可以说是RS232的翻版并在此基础上进行的改进,7816中只有一个IO同时兼具数据收发的功能,这点和RS232用RxD和TxD进行数据收发是不同的。在RS232中我们有9600波特率、起始位、奇偶校验位、停止位这些概念,而在7816-3中都完整地保留了下来,只不过7816-3中引入了etu,没有使用bps,但是基本原理是一致的。etu的定义可以更加精确地描述每个数据位在传输过程中收发双方的职责和角色转换。
根据定义在智能卡上电复位的时候 1 etu = 372 / f ,其中f = 读写设备通过CLK管脚提供给智能卡的时钟频率,通常在1--5 MHz之间。
etu的单位是时间单位秒(毫秒、微秒),等同于传输每个数据位所需的时间。对其取倒数得出来的就是每秒传输的数据位,也就是bps。我们取f = 3.579545 MHz,用3579545除以372结果等于9622.4约为9600 bps。
通用的etu计算公式: 1 etu = (F / D) * (1 / f) ,F和D的值根据7816-3规范中的约定来进行设置。对于上电复位时的取值 F = 372,D = 1即作为默认值Fd和Dd。如果智能卡支持其他速率则需要在ATR中的TA1来指出其他的F和D的值,比如设定F=372,可以把D分别设定为2/4,那么智能卡能支持的通讯速率可以分别为19200/38400。
那么为什么要选择时钟频率为3.579545 MHz?为什么默认的F值选择为372呢?首先3.579545 MHz 是常用石英晶振的标称值,9600 * 372 = 3.5712 MHz,与之最为接近。再说为什么是372,372 = 12 * 31。标准的8051单片机每个指令周期为12个时钟周期,而且定时/计数器也按照1/12 进行分频后再计数的,这样设定对于智能卡芯片来说可以比较容易实现对IO数据通讯的控制,也可以更好地和PC机串口9600速率配合(当然这是指上个世纪80年代的时候,对于现在的智能卡芯片设计技术而言实现任意分频的控制都不是问题了)。
由此可见,这些参数的选择都是为了能够更好地利用当时既有的标准和技术,要知道7816-3在1989年的时候就已经制定了,按照当时的主流PC机配置把串口速率设为9600,用一个232接口芯片(比如Max232)再加上3.579545MHz的晶振,再配合几片74系列的门电路外加5伏的直流电源和几个阻容器件,这就是最基本的RS232串口读卡器了。

使用特权

评论回复
13
LZR13179| | 2015-6-12 09:16 | 只看该作者
或者你可以看看<MSP430操作CPU卡原程序-(命令接收)-侃单片机 - 21ic电子技术论坛>这个还行。

使用特权

评论回复
14
LZR13179| | 2015-6-12 09:22 | 只看该作者
这是一份ISO7816的数据交换的数据

SoTech.pdf

402.21 KB

使用特权

评论回复
15
luchen66| | 2015-6-12 09:24 | 只看该作者

使用特权

评论回复
16
JY-DX-JY|  楼主 | 2015-6-12 09:27 | 只看该作者
LZR13179 发表于 2015-6-12 09:22
这是一份ISO7816的数据交换的数据

谢谢!我看看吧

使用特权

评论回复
17
JY-DX-JY|  楼主 | 2015-6-12 10:35 | 只看该作者
我发送
SC_ADPU.Header.CLA = 0x00;
    SC_ADPU.Header.INS = 0xC0;
    SC_ADPU.Header.P1 = 0x00;
    SC_ADPU.Header.P2 = 0x00;
    SC_ADPU.Body.LC = 0x2B;
                SC_ADPU.Body.LE = 0x2B;
收到6e00,类不支持。

使用特权

评论回复
18
JY-DX-JY|  楼主 | 2015-6-12 10:52 | 只看该作者
我现在试了CLA从00-07,80都不支持。A0,提示域长度错误。

使用特权

评论回复
19
sinshine| | 2015-6-12 11:15 | 只看该作者
JY-DX-JY 发表于 2015-6-12 10:52
我现在试了CLA从00-07,80都不支持。A0,提示域长度错误。

LZ应该好好看看7816-3的协议
老SIM卡都是ICC的,CLA都是A0。LZ只发了C0 apdu,肯定得不到正确的回复。这个是当卡回9Fxx或者6Cxx后,才能发的。
按照前文的ATR,解析是这样的
TS   - 3B
T0   - 1A (只有TA1,10个history byte)
TA1 - 11 --> DI/FI
剩下的都是history byte。TD1不存在,则T0。

LZ的ATR解析有问题的,对照7816好好看一下,没有判断TD是否存在就得出了T1。
还有SC_A2R.T = card[i + 2]; 有问题的

使用特权

评论回复
20
sinshine| | 2015-6-12 11:15 | 只看该作者
JY-DX-JY 发表于 2015-6-12 10:52
我现在试了CLA从00-07,80都不支持。A0,提示域长度错误。

LZ应该好好看看7816-3的协议
老SIM卡都是ICC的,CLA都是A0。LZ只发了C0 apdu,肯定得不到正确的回复。这个是当卡回9Fxx或者6Cxx后,才能发的。
按照前文的ATR,解析是这样的
TS   - 3B
T0   - 1A (只有TA1,10个history byte)
TA1 - 11 --> DI/FI
剩下的都是history byte。TD1不存在,则T0。

LZ的ATR解析有问题的,对照7816好好看一下,没有判断TD是否存在就得出了T1。
还有SC_A2R.T = card[i + 2]; 有问题的

使用特权

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

本版积分规则

个人签名:晴天响霹雳,平地一声雷。

245

主题

3351

帖子

30

粉丝