关于stm32 smartcard功能调试,官方提供的例程是配合8024芯片进行控制的。程序可从地址:http://www.pudn.com/downloads420/sourcecode/embedded/detail1781544.html下载。

经过摸索,终于调试出不用8024的程序设计。

首先确定电路连接,stm32的USART3_CK(PB12)连接到接触式IC卡的CLK端(触点4),stm32的USART3_TX(PB10)连接到接触式IC卡的IO端(触点3),然后stm32选一个GPIO作为输出连接到接触式IC卡的RST端(触点5)。ic卡的vcc和gnd当然也是要接好的了。

然后是程序设计,

1、设置时钟,关键的有三个地方,

A、在设置系统时钟为72M之后,设置PCLK1频率为36M

RCC_PCLK1Config(RCC_HCLK_Div2);

B、使能GPIOB总线时钟,即USART3的端口所在的IO;并使能复用时钟。

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

C、使能USART3总线时钟。

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

2、设置IO,

GPIO_InitTypeDef GPIO_InitStructure;

  /* Configure USART3 CK(PB.12) as alternate function push-pull */

    GPIO_InitStructure.GPIO_Pin = SAM0_CLK;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(SAM0_Port, &GPIO_InitStructure);
 
   /* Configure USART3 Tx (PB.10) as alternate function open-drain */

    GPIO_InitStructure.GPIO_Pin = SAM0_IO;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;

    GPIO_Init(SAM0_Port, &GPIO_InitStructure);

  /* Configure Smartcard Reset  */

    GPIO_InitStructure.GPIO_Pin = SAM0_RST;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(SAM0_Port, &GPIO_InitStructure);

其中已经定义SAM0_CLK为GPIO_Pin_12,定义SAM0_Port为GPIOB,定义SAM0_RST为GPIO_Pin_11,定义SAM0_IO为GPIO_Pin_10,

3、设置USART3

USART_InitTypeDef USART_InitStructure;

   USART_ClockInitTypeDef USART_ClockInitStructure;

     /* USART Clock set to 3.6 MHz (PCLK1 (36 MHZ) / 10) */

  USART_SetPrescaler(USART3, 0x05);

  /* USART Guard Time set to 16 Bit */

  USART_SetGuardTime(USART3, );

  USART_StructInit(&USART_InitStructure);

  USART_InitStructure.USART_BaudRate = ;

  USART_InitStructure.USART_WordLength = USART_WordLength_9b;

  USART_InitStructure.USART_StopBits = USART_StopBits_1_5;

  USART_InitStructure.USART_Parity = USART_Parity_Even;

  USART_Init(USART3, &USART_InitStructure);

  USART_ClockInitStructure.USART_Clock = USART_Clock_Enable;

  USART_ClockInit(USART3, &USART_ClockInitStructure);  

  /* Enable the USART3 Parity Error Interrupt */

  USART_ITConfig(USART3, USART_IT_PE, ENABLE);

  /* Enable the USART3 Framing Error Interrupt */

  USART_ITConfig(USART3, USART_IT_ERR, ENABLE);

  /* Enable USART3 */

  USART_Cmd(USART3, ENABLE);

  /* Enable the NACK Transmission */

  USART_SmartCardNACKCmd(USART3, ENABLE);

  /* Enable the Smartcard Interface */

  USART_SmartCardCmd(USART3, ENABLE);

主要配置USART3的时钟为3.6M,并且使能时钟,波特率为9677(这个值是参考官方例程的,9600也可以),字节长度为9bits(stm32中文参考资料上介绍smartcard功能时,应该设为8bits,但是设为8bits调试不成功,这个郁闷),停止位设为1.5bits,校验位设为偶校验(奇校验也可以的),其它的使能smartcard功能,都要设置好。

4、编写复位程序,ISO7816中,对IC卡的操作,重要的一步就是获取复位返回信息。

以下是我调试好的程序

unsigned char PSAMInit_usart(u8 *card, u8 length)

{

      u8 Data;

         //u8 card[40];

         u8 i;

         GPIO_WriteBit(SAM0_Port, SAM0_RST, (BitAction));//set the rst to low

         ;i<length;i++)

            card[i] = 0x00;

         Data = 0x00;

         ;i<length;i++)//for delay

            Data = 0x00;

         GPIO_WriteBit(SAM0_Port, SAM0_RST,(BitAction));//set the rst to high

         ; i < length; i++)//get the atr

      {

        if((USART_ByteReceive(&Data, SC_Receive_Timeout)) == SUCCESS)

        {

          card[i] = Data;

        }

      }

         ])

         {

            ;

         }

         else

            ;

}

这个子函数是复位子函数。

然后参考官方例程中,smartcard.c中的第62行的函数SC_Handler函数,将其中第107行调用的函数SC_AnswerReq(SCState, &SC_ATR_Table[0], 40);改为,自己编写的复位函数,

temp_flag = PSAMInit_usart(&SC_ATR_Table[], );

                     if(temp_flag == 0x01)

                        *SCState = SC_ACTIVE;

                  else

                        *SCState = SC_POWER_OFF; 

然后在测试程序中调用SC_Handler函数,即可调试。

测试程序如下:

SC_State SCState;// = SC_POWER_OFF;

       u8 i;

       SCState = SC_POWER_ON;

    SC_ADPU.Header.CLA = 0x00;

    SC_ADPU.Header.INS = SC_GET_A2R;

    SC_ADPU.Header.P1 = 0x00;

    SC_ADPU.Header.P2 = 0x00;

    SC_ADPU.Body.LC = 0x00;

    while(SCState != SC_ACTIVE_ON_T0) 

    {

      SC_Handler(&SCState, &SC_ADPU, &SC_Responce);

    }

    /* Apply the Procedure Type Selection (PTS) */

SC_PTSConfig();

这其中的变量定义,宏定义,都是官方例程中的。

在函数PSAMInit_usart调用完之后,即可看到SC_ATR_Table数组中得到的复位返回信息。

然后是SC_PTSConfig();(smartcard.c第202行)这个函数的修改,主要是要根据SC_ATR_Table返回信息中的第3个字节(即ISO7816中所说TA1),来修改串口波特率,程序中208到284行,是发送并接收PTS,根据本人测试,有些卡可以完全一步一步通过这个过程,有些卡是不行的,但是后面的

if(PTSConfirmStatus == 0x01)

      {

        workingbaudrate = apbclock * D_Table[(SC_A2R.T[] & (u8)0x0F)];

        workingbaudrate /= F_Table[((SC_A2R.T[] >> ) & (u8)0x0F)];

        USART_StructInit(&USART_InitStructure);

        USART_InitStructure.USART_BaudRate = workingbaudrate;

        USART_InitStructure.USART_WordLength = USART_WordLength_9b;

        USART_InitStructure.USART_StopBits = USART_StopBits_1_5;

        USART_InitStructure.USART_Parity = USART_Parity_Even;

        USART_InitStructure.USART_Clock = USART_Clock_Enable;

        USART_Init(USART3, &USART_InitStructure);

      }

这一段程序是必须要执行的,否则,以后的调试就没有返回值了。所以可以去掉if(PTSConfirmStatus == 0x01)这一句。这个设置好之后,可以根据不同的内部协议进行通信了,手机卡也好,电话卡也好,不同的卡,内部协议不一样,但是发送命令、数据,接收返回数据都可以,将SC_ADPU这个结构体赋值之后,调用SC_Handler(&SCState, &SC_ADPU, &SC_Responce);这个函数。当SCState为SC_ACTIVE_ON_T0时,就可以发送命令,并接收返回值了。

stm32 smartcard调试--不用st8024的更多相关文章

  1. STM32硬件调试详解

    STM32的基本系统主要涉及下面几个部分: 一.电源 1).无论是否使用模拟部分和AD部分,MCU外围出去VCC和GND,VDDA.VSSA.Vref(如果封装有该引脚)都必需要连接,不可悬空: 2) ...

  2. stm32 HardFault_Handler调试及问题查找方法

    STM32出现HardFault_Handler故障的原因主要有两个方面: 1.内存溢出或者访问越界.这个需要自己写程序的时候规范代码,遇到了需要慢慢排查. 2.堆栈溢出.增加堆栈的大小. 出现问题时 ...

  3. iOS9 以上的真机调试 不用证书

    具体流程如下: 首次使用AppleID  的注意事项:  要在设置中 进行 如下操作  设置--通用--描述文件   ---添加信任 但是有时候  还是 会不能调试,  显示信息  是这样的   : ...

  4. ubuntu下使用openocd+jlink进行STM32开发调试

    安装openocd就不用多说了,使用 apt-get install openocd 这个命令就可以做到. 对于使用stm32w系列的MCU,需要下载新的openocd-0.7及以上版本才能支持.0. ...

  5. STM32 低功耗 调试心得

    MCU在进入STOP模式的时候,GPIO的状态都是保持在进入低功耗模式之前的状态,在最小系统中,MCU的GPIO都是悬空的,所以设置为何种状态都不会影响到功耗.但当连接到外设后,外设的电平状态和所连接 ...

  6. stm32 HardFault_Handler调试及问题查找方法——飞思卡尔

    看到有朋友遇到Hard Fault 异常错误,特地找到一篇飞思卡尔工程师写的一片经验帖,定位Hard Fault 异常. Kinetis MCU 采用 Cortex-M4 的内核,该内核的 Fault ...

  7. STM32 ARM调试问题总结

    文章转载自:http://xfjane.spaces.eepw.com.cn/articles/article/item/77908 基于ADS的ARM调试有关问题总结 1.  在添加文件的过程中你可 ...

  8. scrapy 在pycharm中调试 不用到命令行中启动爬虫方法

    (目录结构如上图) 在主目录中加入main.py,在其中加入代码,运行此文件就可以运行整个爬虫: # -*- coding: utf-8 -*- __author__='pasaulis' #在程序中 ...

  9. 线上Bug无法复现怎么办?老司机教你一招,SpringBoot远程调试不用愁!

    前言 在部署线上项目时,相信大家都会遇到一个问题,线上的 Bug 但是在本地不会复现,多么无奈. 此时最常用的就是取到前端传递的数据用接口测试工具测试,比如 POSTMAN,复杂不,难受不? 今天陈某 ...

随机推荐

  1. InstallShield 12 制作安装包

    目  录 一. 二. 三. (一) 打开project... 2 (二) project助手页面... 3 1.Application Information:程序信息... 4 2.Installa ...

  2. PHP面向对象之旅:模板模式(转)

    抽象类的应用就是典型的模版模式 抽象类的应用就是典型的模版模式,先声明一个不能被实例化的模版,在子类中去依照模版实现具体的应用. 我们写这样一个应用: 银行计算利息,都是利率乘以本金和存款时间,但各种 ...

  3. GCC相关的环境变量

    介绍GCC在编译阶段和程序运行阶段用到的环境变量. GCC编译时用到的环境变量 GCC编译时用到的变量. C_INCLUDE_PATH GCC编译时查找头文件的目录列表.比如: echo $C_INC ...

  4. Jboss image upload and http access to show image--reference

    question I am uploading images to jboss server by getting the absolute path using the following code ...

  5. linux device driver —— 环形缓冲区的实现

    还是没有接触到怎么控制硬件,但是在书里看到了一个挺巧妙的环形缓冲区实现. 此环形缓冲区实际为一个大小为bufsize的一维数组,有一个rp的读指针,一个wp的写指针. 在数据满时写进程会等待读进程读取 ...

  6. css背景图与html插入img的区别

    一直以来都认为css背景图与直接插入img图片的效果是差不多的,直到最近拜读了一位大神的作品,发现大部分图片都是通过背景图形式显示的,于是通过搜索各相关资料,在此总结了下二者的区别: 1. css中的 ...

  7. C#开发学习——内联表达式

    <%@ 表示:引用 <%# 表示:绑定 <%= 表示:取值     <%= 变量名%> Response.Write()输出和<%=%>输出最后的效果是一样的 ...

  8. Asp.net中向前端输出JS的一些调用

    最近突然写ASP.NET项目,用到向前台输出JS脚本,但是以前在MVC里是通过异步或者一些方法来调用,但是ASP.net用到的很少.在网上找到一个HELPER.CS.保存一下,以后再用. using ...

  9. c#迭代算法

    //用迭代算法算出第m个值 //1,1,2,3,5,8...;           //{1,0+1,1+1,1+2,2+3 ,3+5} static void Main(string[]   arg ...

  10. 【转】 UINavigationItem UINavigationBar 关系分析

    原文:http://blog.csdn.net/luoyeffcs/article/details/16106707 目录 1.关系分析 2.关系综述 3.概念点 4.疑问 1.关系分析 UIBarI ...