zoukankan      html  css  js  c++  java
  • 7816协议时序和采用UART模拟7816时序与智能卡APDU指令协议

    7816时序

    7816时一个比较早的老通讯时序了,最近项目上需要用UART模拟所以,简单学习时序。

     时序比较简单,熟悉UART的一眼看着就像是串口的时序,只是他没有停止位,取而代之的就是保护时间guradtime,一般是两个etu所以可以使用两个停止位来模拟。电路图上就是将RX和TX短接,在发送关闭串口的接受功能反之接收时关闭发送功能就可以了。

    APDU指令

    1、报文格式。

    C-APDU有4字节的必备长度和1个可变长度条件体组成

    CLA:命令报文类别字节

    INS:命令报文指令字节

    P1:参数1

    P2:参数2

    LC:条件体数据域的实际长度

    DATA:数据域

    Le:期望返回数据的长度

    CLA  INS P1 P2 LC  DATA  Le 这里需注意的就是在物理链路上给卡发送APUD指令时需要按一下时序发送,先发送前5个字节然后等待卡回应INS 后才可继续发送余下的DATA,LE可以没有。

    串口模拟7816参考程序

    初始化同普通接口初始化相同

    初始化代码

        GPIO_InitTypeDef GPIO_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
    
        USART_InitTypeDef USART_InitStructure;
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
    
        GPIO_InitStructure.GPIO_Pin = FM151_TXD_PIN;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(FM151_PORT, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = FM151_RXD_PIN;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(FM151_PORT, &GPIO_InitStructure);
    
        USART_InitStructure.USART_BaudRate = 9600;
        USART_InitStructure.USART_WordLength = USART_WordLength_9b;//9位数据
        USART_InitStructure.USART_StopBits = USART_StopBits_1;//1位停止位
        USART_InitStructure.USART_Parity = USART_Parity_Even;//偶校验
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制失能
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //发送和接受使能
        USART_Init(USART3, &USART_InitStructure);
    
        //Usart1 NVIC 配置
        NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4 ; //抢占优先级4
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        //子优先级0
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器
    
        USART_Cmd(USART3, ENABLE);
    
        USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);        //开始都不允许接受中断

    这里采用中断接受,所以需要字节实现自己的中断服务函数。

    发送数据

    static void UartSendByte(u8 *dat)
    {
       
        while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
        USART_SendData(USART3, *dat);
    
        while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
        USART_ClearFlag(USART3, USART_FLAG_TC);
    
        delay_us(guardtime);
    }

    发送一定字节数据

    void SendData(u8 *data, u16 datalenth)
    {
        u16 i;
        SetUartDir(TX);
        for (i = 0; i < datalenth - 1; i++)
        {
            UartSendByte(data + i);
        }
        UartSendLastByte(data + i);
        SetUartDir(RX);
    }

    这里注意最后一个字节不需要额外的保护时间。最后就是配置UART的接受和发送的寄存器函数。

    void SetUartDir( u8 dir)
    {
        u32 reg;
        //发送时禁止接收,发送完成才开始接收
        if (dir == RX)
        {
            reg = USART3->CR1;
            reg |= USART_Mode_Rx;
            reg &= (~USART_Mode_Tx);
            USART3->CR1 = reg;            
    
            USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);        
        }
        else if (dir == UART_TXD)
        {
            reg = USART3->CR1;
            reg |= USART_Mode_Tx;
            reg  &= (~USART_Mode_Rx);
            USART3->CR1 = (u16)reg;            
    
            USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);    
        }
    }
  • 相关阅读:
    201871010114李岩松《面向对象程序设计(java)》第十二周学习总结
    201871010114李岩松《面向对象程序设计(java)》第十六周学习总结
    201871010114李岩松《面向对象程序设计(java)》第八周学习总结
    201871010114李岩松《面向对象程序设计(java)》第七周学习总结
    201871010114李岩松《面向对象程序设计(java)》第六、七周学习总结
    一分钟秒解数据库三大范式
    反射机制获取类的方法
    hashMap和hashTable的区别
    ssm+maven 框架整合
    Hibernate从零开始的反向工程
  • 原文地址:https://www.cnblogs.com/w-smile/p/13168944.html
Copyright © 2011-2022 走看看