贴上自己的代码,目前测试通过,但我感觉结构不是很好,希望和大家交流共同提高。
.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的内容确定,这里不再叙述