贴上自己的代码,目前测试通过,但我感觉结构不是很好,希望和大家交流共同提高。

.H文件

#define  ACKN             -1
#define  ACKY             -2
#define  RESEND           -3
#define  ONSENDNEXT       -4
#define  SENDDEL          -5
#define  SENDWTX          -6
#define  DONOTHING        -12

#define  BLOCK_MASK       0XC0
#define  IBLOCK           0X00
#define  RBLOCK           0X80
#define  SBLOCK           0XC0
#define  NACK_MASK        0X10
#define  CID_MASK         0X08
#define  BNUM_MASK        0X01
#define  WTX_DEL_MASK     0X30
#define  LINK_MASK        0X10
#define  WTX              0X30
#define  DELSECT          0X00 

.c文件

unsigned char  near     CCID;
unsigned char  near  Frame_Data_Len_Card;
unsigned char  near currentflag;
unsigned ];
unsigned char  near lastframelen;
unsigned ],CardBuffer[];
unsigned short near PBufferLength,PBufferPoint,CardBufPoint,CardBufferLength;
bit cblock_num,CCid_En; 

unsigned char AckN(void)
{
  unsigned ];
  buf[] = 0XA2|cblock_num;
  buf[] = CCid_En?buf[]|];
  buf[] = CCID;
  WriteCardFifo(buf,);
  SetRecvOrSend(START_SEND_AND_RECV);
//  PutDatUart(buf, 2);
  return OK;
}
unsigned char AckY(void)
{
  unsigned ];
  cblock_num=!cblock_num;
  buf[] = 0XA2|cblock_num;
  buf[] = CCid_En?buf[]|];
  buf[] = CCID;
  WriteCardFifo(buf,(unsigned ));
//  PutDatUart(buf, 2);
  return SetRecvOrSend(START_SEND_AND_RECV);
}

char CardRecvFrameProcess(unsigned char *tempbuf,unsigned char inlen)
{
   unsigned short near len;
   unsigned char near PCB;
   unsigned char near Cid;
   unsigned char near lastflag = currentflag;
   len = inlen;
   )
   {
      return DONOTHING;
   }
   PCB = tempbuf[];
   Cid = PCB&CID_MASK;
   )&&(CCID!=)&&(Cid==)) || ((CCid_En==)&&(Cid==))) return DONOTHING;
   if((PCB&BLOCK_MASK) ==IBLOCK)//i-block
   {
     if(PCB&CID_MASK)//带CID时,长度应该不少于2字节
     {
        ) return DONOTHING;
     }
     else //不带CID时长度不应少于1个字节
     {
        )  return DONOTHING;
     }
     if((PCB&0X02)!=0X02) return DONOTHING;
     currentflag = PCB & LINK_MASK;
     if(currentflag)
     {
       if(lastflag)
       {
           - (unsigned char)CCid_En)>BUFFERLENGTH)
          {
             PBufferLength=;
             PBufferPoint =;
             return DONOTHING;
          }
          memcpy(&PBuffer[PBufferPoint],&tempbuf[+(unsigned -(unsigned char)CCid_En);
          PBufferPoint = PBufferPoint + len -  - (unsigned char)CCid_En;
          PBufferLength = PBufferLength + len -  - (unsigned char)CCid_En;
       }
       else
       {
          PBufferPoint  = ;
          PBufferLength  = ;
          memcpy(&PBuffer[PBufferPoint],&tempbuf[+(unsigned -(unsigned char)CCid_En);
          PBufferPoint = PBufferPoint + len -  - (unsigned char)CCid_En;
          PBufferLength = PBufferLength + len -  - (unsigned char)CCid_En;
        }
        return ACKY;
      }
      else
      {
        if(lastflag)
        {
           - (unsigned char)CCid_En)>BUFFERLENGTH)
          {
            PBufferLength=;
            PBufferPoint =;
            return DONOTHING;
          }
          memcpy(&PBuffer[PBufferPoint],&tempbuf[+(unsigned -(unsigned char)CCid_En);
          PBufferPoint = PBufferPoint + len -  - (unsigned char)CCid_En;
          PBufferLength = PBufferLength + len -  - (unsigned char)CCid_En;
       }
       else
       {
         PBufferPoint  = ;
         PBufferLength = ;
         memcpy(&PBuffer[PBufferPoint],&tempbuf[+(unsigned -(unsigned char)CCid_En);
         PBufferPoint = PBufferPoint + len -  - (unsigned char)CCid_En;
         PBufferLength = PBufferLength + len -  - (unsigned char)CCid_En;
       }
       return FM_OK;
    }
 }
 else if((PCB&BLOCK_MASK) ==RBLOCK) //rblock
 {
  if(PCB&CID_MASK)//带CID时,长度应该不少于2字节
  {
    ) return DONOTHING;
  }
  else //不带CID时长度不应少于1个字节
  {
    )  return DONOTHING;
  }
  if((PCB&0X40)==0X00)   return DONOTHING;
  if(PCB&NACK_MASK)
  {
   if((PCB&BNUM_MASK)!=cblock_num)
   {
    return ACKN;//表示重发NAK,因帧号不对
   }
   else
   {
    return RESEND; //表示重发上一帧
   }
  }
  else  //ack
  {
   if((PCB&BNUM_MASK)!=cblock_num)
   {
    return SENDNEXT; //表示继续发下一帧
   }
   else
   {
    return RESEND; //表示重发上一帧
   }
  }
    }
 else if((PCB&BLOCK_MASK) ==SBLOCK) //sblock
 {
   if((PCB&0X04)!=0X00)   return DONOTHING;
  if((PCB&WTX_DEL_MASK)==DESELECT)
  {
   if(PCB&CID_MASK)
   {
    if(len!=0x02)         return  DONOTHING;
    else                  return    SENDDEL;
   }
   else
   {
    if(len!=0x01)   return  DONOTHING;
    else                    return  SENDDEL;
   }
  }
  else if((PCB&WTX_DEL_MASK)==WTX)
  {
   if(PCB&CID_MASK)
   {
    if(len!=0x03)         return  DONOTHING;
    else                  return    SENDWTX;
   }
   else
   {
    if(len!=0x02)    return    DONOTHING;
    else                  return  SENDWTX;
   }
  }
  else
  {
   return DONOTHING;
  }
 }
 else
 {
    return  DONOTHING;
 }
}
char CardCosInsProcess()
{
 Timer0Delay(FIFTY_MINISECOND); //这个时间根据卡返回的ATS中的参数确定,默认为4.8ms,在定时器中断中发WTX,并禁止再次中断,停止定时器
 EnableTimer0Int();

 StopTimer0();
 return OK;
 }
char CardSendFrameProcess(char STA)
{
 unsigned ];
 unsigned char  near  len;
 char  near Sta=STA;
 unsigned -(unsigned ;
 //WTimeS = 0;
 switch(Sta)
 {
  case ACKY:
       AckY();
       break;
  case ACKN:
       AckN();
       break;
  case RESEND:
       memcpy(tempbuf,lastframe,lastframelen);
    WriteCardFifo(tempbuf,lastframelen);
       SetRecvOrSend(START_SEND_AND_RECV);
//     PutDatUart(tempbuf,lastframelen);
       break;
  case ONSENDNEXT:
       cblock_num = !cblock_num;
       wtempfc[] = CCid_En?0X0A:0X02;
       wtempfc[]=  CardBufferLength>CardMLen?((tempbuf[] | ] | cblock_num);
       wtempfc[] = CCID;
       len =  (CardBufferLength>(CardMLen))?CardMLen:CardBufferLength;
       memcpy(&tempbuf[(unsigned ],&CardBuffer[CardBufPoint],len);
       WriteCardFifo(tempbuf,(unsigned ));
       SetRecvOrSend(START_SEND_AND_RECV);
//     PutDatUart(tempbuf,(unsigned char)(len+((unsigned char)CCid_En)+1));
       CardBufPoint = CardBufPoint + len;
       CardBufferLength = CardBufferLength - len;
       break;
  case SENDDEL:
       SDeselect();
       SetCardIdle();
       break;
  case SENDWTX:
       Timer0Delay(FIFTY_MINISECOND);
       //这个时间根据卡返回的ATS中的参数确定,默认为4.8ms,在定时器中断中发WTX,并禁止再次中断,停止定时器
       EnableTimer0Int();
       break;
  case GETDATA:
       cblock_num= !cblock_num;
       tempbuf[] = CCid_En?0X0A:0X02;
       tempbuf[] = CardBufferLength>CardMLen?((tempbuf[] | ] | cblock_num)
       tempbuf[] = CCID;
       CardBufPoint = ;
       len = (CardBufferLength>CardMLen)?CardMLen:CardBufferLength;
       memcpy(&tempbuf[(unsigned ],&CardBuffer[CardBufPoint],len+(unsigned );
    WriteCardFifo(tempbuf,(unsigned ));
    SetRecvOrSend(START_SEND_AND_RECV);
//    PutDatUart(tempbuf,(unsigned char)(len+((unsigned char)CCid_En)+1));
    CardBufPoint = CardBufPoint + len;
    CardBufferLength = CardBufferLength - len;
    break;
  case DONOTHING:
  default:break;
 } return OK;
}

最后,关于WTX的处理,需要一个定时器,其初值由ATS的内容确定,这里不再叙述

ISO14443-4块传输的实现(卡)的更多相关文章

  1. IC卡的传输协议(2)-块传输协议T=1【转】

    转自:http://bbs.ednchina.com/BLOG_ARTICLE_172024.HTM 2.4 块传输协议T=1 T=1协议中,在TAL和IC卡之间传送的命令.R-APDU和传输控制信息 ...

  2. IC卡的传输协议(2)-块传输协议T=1续【转】

    转自:http://bbs.ednchina.com/BLOG_ARTICLE_172025.HTM (3)容错操作 先来看一下容错的规则定义. * 复位应答后,第一个数据块是由终端发往IC卡的,而且 ...

  3. ISO7816协议的块传输协议

    1.块传输协议中的前三个字节是强制必须有的 NAD节点地址: 当终端支持多个卡槽,终端和这些卡槽以总线的方式通讯时,该字节有用,其他情况下,默认为0 bit1-3:定义了源地址 bit5-7:定义了目 ...

  4. ISO14443-4块传输协议的实现

    ISO1444-3块传输协议主要用于应用数据的传输,其实现如下: unsigned char Apdu(unsigned char *comm,unsigned short len,unsigned ...

  5. 第14章 位图和位块传输_14.4 GDI位图对象(3)

    14.4.10 非矩形的位图图像 (1)“掩码”位图——单色位图,要显示的像素对应的掩码置1,不显示置0(2)光栅操作(点这里,见此文分析) (3)MaskBlt函数 ①MaskBlt(hdcDest ...

  6. 第14章 位图和位块传输_14.4 GDI位图对象(2)

    14.4.7 在位图上绘图 (1)在内存设备环境中绘图(与真实DC不同的是,内存DC的显示表面是个位图) (2)GetTextExtentPoint32函数:用于确定文本字符串的像素大小.(此大小就是 ...

  7. 第14章 位图和位块传输_14.4 GDI位图对象(1)

    14.4.1 创建DDB (1)创建 HBITMAP= CreateBitmap(cx,cy,cPlanes,cBitsPixel,lpBits); 参数 说明 cx,cy 指定位图宽度和高度,单位为 ...

  8. PBOC第八部分和第十一部分关于TYPEA总结(二)——传输协议(ISO14443-4)

    二.传输协议(ISO14443-4)(8,P50 11,P30) 1.选择应答请求(RATS) 使用RATS命令和PICC协商通讯的最大帧长度(FSD和FSC).帧等待时间(FWT)和启动帧保护时间( ...

  9. 智能IC卡与终端(读卡器)之间的传输协议

    1.有两种协议 T=0,异步半双工字符传输协议 T=1,异步半双工块传输协议 终端一般都支持这两种协议,IC卡可以选择支持其中的一种.(因为终端可能需要面对各种类型的卡片,所以必须两种协议都支持,而卡 ...

随机推荐

  1. Android获取cpu和内存信息、网址的代码

      android获取手机cpu并判断是单核还是多核 /** * Gets the number of cores available in this device, across all proce ...

  2. Effective C++ 总结(二)

    四.设计与声明          条款18:让接口容易被正确使用,不易被误用      理想上,如果客户企图使用某个接口而却没有获得他所预期的行为,这个代码不该通过编译:如果代码通过了编译,它的行为就 ...

  3. LeanCloud使用入门(android)

    LeanCloud算是一个简单易用的云服务器,其中包含了强大的数据库支持,我们只需要将此服务器应用到本地的代码即可实现后台的存储与交互. 那么,如何简单实现本地代码和LeanCloud服务器的交互呢? ...

  4. State 状态模式

    简介 状态模式允许一个对象在其内部[状态]改变的时候改变其[行为].这个对象看上去就像是改变了它的类一样. 用一句话来表述,状态模式把所研究的对象的[行为]包装在不同的[状态对象]里,[每一个状态对象 ...

  5. 【开源java游戏框架libgdx专题】-01-libgdx介绍

    libgdx是一款开源的java游戏框架,而且还实现了Desktop/Android/BlackBerry/iOS/HTML5这些些平台的跨平台开发.官方网址:https://libgdx.badlo ...

  6. Have trouble in your life

    当你烦恼的时候不知道如何是好时,你可以下载此程序,可以帮助你化解烦恼! 下载地址: http://pan.baidu.com/s/1i3FtxHF

  7. SQL中 patindex函数的用法

    语法格式:PATINDEX ( '%pattern%' , expression ) 返回pattern字符串在表达式expression里第一次出现的位置,起始值从1开始算. pattern字符串在 ...

  8. Android之ListView/GridView 优化

    一.效率最低的getView实现 我们知道,ListView和GridView的显示都是通过Adapter的getView实现的. ListView/GridView数据量较小时,我们的处理方式一般是 ...

  9. 实现textarea限制输入字数

    实现textarea限制输入字数(包含中文只能输入10个,全ASCII码能够输入20个) textarea称文本域,又称文本区,即有滚动条的多行文本输入控件,在网页的提交表单中经常用到.与单行文本框t ...

  10. ubuntu系统mysql.h no such file or directory

    在Ubuntu系统中,你已经安装了mysql,即你使用sudo apt-get install mysql-server mysql-client然而使用C语言访问mysql数据库时,却发现出现了如下 ...