📄 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 + -