?? cpu_com.c
字號:
//#include "type.h"
#include "reg51.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "INTRINS.H"
#include "CPU_COM.h"
unsigned char xdata OutData[255] _at_ 0x0200;
void main()
{
unsigned char idata pATR[1],InData[32]={0x05,0xAA,0x55,0x00,0x00,0x08};
unsigned char ndata[2] = {0xAA,0x55};
//unsigned char idata OutData[64];
PLY_APDU();
Inttime0(); //定時器0初始化
com_Open(); //打開串口
// SendCom()
//cpu_Open(); //CPU卡上電并讀ATR并把ATR通過串口發送,如果讀ATR錯誤則輸出FF
// ICC_INS(&InData[1],OutData,*InData);
// SendChar(0x36);
//ICC_INS:輸入數據指針*InData,輸入數據長度lnin,輸出數據指針*OutData,輸出數據長度為*OutData
// if (ICC_INS(&InData[1],OutData,*InData)!=TRUE)
// {
// OutData[0] = 1;
// OutData[1] = 0xff;
// }
while(1)
{
//SendCom(2,&InData[1]);
if(readCom(InData) == TRUE)
{
if(!memcmp(ndata,InData+1,2))
{
SendCom(2,"OK");
break;
}
else
SendCom(2,"ER");
}
else
SendCom(2,"ER");
}
ndata[0]=0xaa;
while(1)
{
if(readCom(InData) == TRUE)
{
if(*InData == 1)
continue;
else
{
if (ICC_INS(&InData[1],*InData)!=TRUE)
{
OutData[0] = 1;
OutData[1]=0xff;
}
// Extra_guardtime_N = Extra_guardtime_N_bak;
//if(OutData[0]<=64)
SendCom(OutData[0],&OutData[1]);
//else
//SendCom((OutData[0]-64),OutData1);
}
}
else
{
OutData[0] = 1;
OutData[1]=0xff;
SendCom(OutData[0],&OutData[1]);
}
}
}
//=============初始化定時器================================
void Inttime0()
{
TMOD|=0x02; /*定時器0為模式2(8位自動重裝) */
TR0=0; //在發送或接收才開始使用
TF0=0; //清定時器溢出標志
TH0=0XA0; //9600是1000000/9600=104.167微秒104.167*11.0592/12=96 (256-96=0XA0)
TL0=TH0;
ET0=1; //開定時器中斷
EA=1; //開CPU中斷
}
//=========================================================
//=============定時器中斷子程序============================
void IntTimer0() interrupt 1
{
F_TM=1; //定時器溢出引起中斷,置標志位
}
//=========================================================
//=============發送一個字符傳入發送數據返回是否發送正確====
//=============返回錯誤時則啟用釋放終端====================
unsigned char SendChar(unsigned char ch)
{
unsigned char i = 0,bak; //p為1的個數
unsigned char idata b=0;
bit a = 0;
//bak = ch;
if(CPUCD_Format != 0)
ch = ~ch;
bak = ch;
if(CPUCD_Format == 0)
{
F_TM=0; //關中斷標志
start:
BT_SND = 0; //發送起始位
TH0 = 0xB6;
TL0 = 0xB6;
TR0 = 1;
//TIMER0_ENABLE; //啟動定時器
while(!F_TM); //檢測到中斷標志后開始發送一個字符(8位)
while(i<8)
{
if(ch&1)
{
BT_SND = 1;
a=(~a);
}
else
{
BT_SND = 0;
a = a;
}
TH0 = 0xBF;
TIMER0_ENABLE;
F_TM=0; //發送一位之后關標志準備發送下一位
while(!F_TM);
i++;
ch>>=1;
} //結束位(9+0.268)etu~(10+0.098)etu
if(a)
{
BT_SND = 1; //數據位1的個數為偶數則發送0保證數據位和效驗1的個數為偶數
}
else
{
BT_SND = 0; //數據位1的個數為奇數則發送1保證數據位和效驗1的個數為偶數
}
TH0 = 0xAD;
TIMER0_ENABLE;
F_TM=0;
while(!F_TM);
//上面是起始+8位數據+1位校驗 //(10+0.098)etu
BT_SND = 1;
TH0 = 0xB2;
TIMER0_ENABLE;
F_TM=0;
while(!F_TM);
TH0 = 0xA5;
TIMER0_ENABLE; //(11+0.135)etu 11etu處檢測
if(BT_SND == 0) //如果IC卡有誤
{
if(b == 4)
return FALSE;
F_TM=0;
while(!F_TM);
// BT_SND = 1;
F_TM=0;
while(!F_TM);
F_TM=0;
// TH0 = 0xFF;
// TIMER0_ENABLE; //(11+0.135)etu 11etu處檢測
i = 0;
b++;
ch = bak;
goto start;
}
TH0 = 0xB4;
TIMER0_ENABLE;
F_TM=0;
while(!F_TM);
for(i=0;i<Extra_guardtime_N;i++)
{
TH0 = 0xB6;
TIMER0_ENABLE;
F_TM=0;
while(!F_TM);
}
TIMER0_DISABLE; //停止定時器
return TRUE;
}
else
{
F_TM=0; //關中斷標志
start1:
BT_SND = 0; //發送起始位
TH0 = 0x54;
TL0 = 0x54;
TR0 = 1;
//TIMER0_ENABLE; //啟動定時器
while(!F_TM); //檢測到中斷標志后開始發送一個字符(8位)
while(i<8)
{
if(ch&0x80)
{
BT_SND = 1;
a=(~a);
}
else
{
BT_SND = 0;
a = a;
}
TH0 = 0x5F;
TIMER0_ENABLE;
F_TM=0; //發送一位之后關標志準備發送下一位
while(!F_TM);
i++;
ch<<=1;
} //結束位(9+0.268)etu~(10+0.098)etu
if(a)
{
BT_SND = 0; //數據位1的個數為偶數則發送0保證數據位和效驗1的個數為偶數
}
else
{
BT_SND = 1; //數據位1的個數為奇數則發送1保證數據位和效驗1的個數為偶數
}
TH0 = 0x4E;
TIMER0_ENABLE;
F_TM=0;
while(!F_TM);
//(10+0.098)etu
BT_SND = 1;
TH0 = 0x51;
TIMER0_ENABLE;
F_TM=0;
while(!F_TM);
TH0 = 0x43;
TIMER0_ENABLE; //(11+0.135)etu
if(BT_SND == 0) //如果IC卡有誤
{
if(b == 4)
return FALSE;
F_TM=0;
while(!F_TM);
F_TM=0;
while(!F_TM);
// TH0 = 0x45;
// TIMER0_ENABLE; //(11+0.135)etu 11etu處檢測
b++;
ch = bak;
goto start1;
}
TH0 = 0x55;
TIMER0_ENABLE;
F_TM=0;
while(!F_TM);
for(i=0;i<Extra_guardtime_N;i++)
{
TH0 = 0x57;
TIMER0_ENABLE;
F_TM=0;
while(!F_TM);
}
TIMER0_DISABLE; //停止定時器
return TRUE;
}
}
//=======================================================================
/*===接收一個字符(*ndata)返回如果為FALSE表示數據和校驗位不符合將口線拉低后
//等待兩個ETU后從新接收,但不包括接收ATR
FALSE1表示超時============================TRUE則成功==========*/
unsigned char GetChar(unsigned char *ndata1)
{
unsigned char i = 0,ch = 0,b = 0;//,a1; //i:位計數,ch:接收的字符存儲位置
unsigned char idata count = 0; //超時計數器
unsigned int idata count1 = 0;
bit a = 0,a1 = 0;
if(CPUCD_Format == 0)
{
statr:
while(BT_REC) //等待開始位
{
count++;
if(count == 0xFF)
{
// count = 0;
count1++;
if(count1 == 0x0415)
{
// if(tc2 == 0)
return FALSE1; //等待起始位超時
// else
// {
// count1 = 0;
// tc2 = tc2-1;
// }
}
}
}
/*----接收一個字節的數據-----*/
//TIMER0_ENABLE; //啟動定時器
for(i=0;i<=1;i++);
TH0 = 0x8F;
TL0 = 0x8F;
// TH0 = 0xA0;
// TL0 = 0xA0;
TR0 = 1;
//TH0 = 0x9;
//TH0=0XB0;
//F_TM = 0;
while(i<10)
{
F_TM = 0;
while(!F_TM); //等待溢出準備接收一個字節的數據
ch>>=1;
if(BT_REC)
{
TH0 = 0xB2;
TIMER0_ENABLE;
ch|=0x80;
a = (~a);
}
else
{
TH0 = 0xB2;
TIMER0_ENABLE;
ch = ch;
a = a;
}
i++;
}
//TH0=0XB0;
//TIMER0_ENABLE;
F_TM = 0;
while(!F_TM); //等待溢出準備接收一個字節的數據
_nop_();
_nop_();
_nop_();
_nop_();
if(BT_REC)
a1 = 1;
else
a1 = 0;
TH0 = 0xB3;
TIMER0_ENABLE;
F_TM = 0;
while(!F_TM); //等待溢出準備接收一個字節的數據
if(a1!=a)
{
//TIMER0_DISABLE ; //停止定時器
BT_REC = 0; //10.5etu
if(b == 4)
return FALSE;
b++;
F_TM = 0;
while(!F_TM); //等待溢出準備接收一個字節的數據
F_TM = 0;
TH0 = 0xAE;
TIMER0_ENABLE
while(!F_TM); //等待溢出準備接收一個字節的數據
BT_REC = 1;
// F_TM = 0;
// TL0 = 0xF0;
// while(!F_TM); //等待溢出準備接收一個字節的數據
//BT_REC =1;
goto statr; //接收數據發生錯誤
}
else
{
TR0=0;
*ndata1 = ch; //將接收的數據以ndata指針返回
//BT_REC=1;
}
return TRUE; //正確接送數據
}
else
{
stara1:
while(BT_REC) //等待開始位
{
count++;
if(count == 0xFF)
{
// count = 0;
count1++;
if(count1 == 0x0430)
{
if(tc2 == 0)
return FALSE1; //等待起始位超時
else
{
tc2--;
count1 = 0;
}
}
}
}
/*----接收一個字節的數據-----*/
//TIMER0_ENABLE; //啟動定時器
for(i=0;i<=1;i++);
TH0 = 0x00;
TL0 = 0x00;
TR0 = 1;
//TH0 = 0x9;
//TH0=0XB0;
//F_TM = 0;
while(i<10)
{
F_TM = 0;
while(!F_TM); //等待溢出準備接收一個字節的數據
ch<<=1;
if(BT_REC)
{
TH0 = 0x50;
TIMER0_ENABLE;
ch|=1;
a = (~a);
}
else
{
TH0 = 0x50;
TIMER0_ENABLE;
ch = ch;
a = a;
}
// TH0=0XB4;
// TIMER0_ENABLE;
i++;
}
//TH0=0XB0;
//TIMER0_ENABLE;
F_TM = 0;
while(!F_TM); //等待溢出準備接收一個字節的數據
if(BT_REC)
a1 = 1;
else
a1 = 0;
TH0 = 0x50;
TIMER0_ENABLE;
F_TM = 0;
while(!F_TM); //等待溢出準備接收一個字節的數據
if(a1!=a)
{
//TIMER0_DISABLE ; //停止定時器
BT_REC = 0; //10.5etu
if(b == 4)
return FALSE;
b++;
F_TM = 0;
while(!F_TM); //等待溢出準備接收一個字節的數據
F_TM = 0;
while(!F_TM); //等待溢出準備接收一個字節的數據
BT_REC = 1;
// F_TM = 0;
// TL0 = 0xF0;
// while(!F_TM); //等待溢出準備接收一個字節的數據
//BT_REC =1;
goto stara1; //接收數據發生錯誤
}
else
{
TR0 = 0;;
*ndata1 = ~ch; //將接收的數據以ndata指針返回
//BT_REC=1;
}
return TRUE;
}
}
//觸點激活子程序冷復位
/*///KTD1101
/*小機器
unsigned char cpu_Open(void)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -