📄 at88sc102.c
字号:
return _C102Write(16, 64, iz);
}
int C102WriteCPZ(int offset, int len, unsigned char *cpz)
{
/*
功能:写代码保护区。写代码保护区为8字节。
输入:offset: 0-7,一般应为偶数,如果offset为奇数,len必须为奇数
len: 1-8
cpz: 8字节
输出:返回值: -1 = 卡不在位;
-2 = 写入失败,与读出的不一致。
-3 = 参数错误,要写入的内容超出存储区; 如果offset为奇数,len必须为奇数
0 = 正确
*/
if( offset+len > 8 )
return -3;
if( offset%2 == 1 )
{//如果offset为奇数,len必须为奇数
if(len%2 != 1)
return -3;
}
_C102Erase(112 + offset*8, len*8);
return _C102Write(112 + offset*8, len*8, cpz);
}
int C102UpdateSC(unsigned char *sc)
{
/*
功能:更新密码。密码为2字节。
输入:sc:2字节
输出:返回值: -1 = 卡不在位;
-2 = 写入失败,与读出的不一致。
0 = 正确
*/
_C102Erase(80, 16);
return _C102Write(80, 16, sc);
}
int C102ReadAZ(int zone, int offset, int len, unsigned char *msg)
{
/*
功能:读应用区1和2中的数据。应用区为64字节。
输入:offset: 0-63
len: 1-64
输出:msg: 返回内容,字节形式
返回值: -1 = 卡不在位;
-3 = 参数错误,要写入的内容超出存储区
0 = 正确
*/
int address;
if( offset+len > 64 )
return -3;
if(zone == 1)
address = 176;
else
address = 736;
address = address + offset*8;
return _C102Read(address, len*8, msg);
}
int C102WriteAZ(int zone, int offset, int len, unsigned char *msg)
{
/*
功能:向应用区1或者2中写数据。应用区为64字节,每个应用区的第0字节的最高2位被强制置为0。
输入:zone: 1-应用区1; 2-应用区2;
offset: 0-63, 一般应为偶数,如果offset为奇数,len必须为奇数
len: 1-64
msg: 要写的内容
输出:返回值: -1 = 卡不在位;
-2 = 写入失败,与读出的不一致。
-3 = 参数错误,要写入的内容超出存储区;如果offset为奇数,len必须为奇数
0 = 正确
*/
int address;
if( offset+len > 64 )
return -3;
if( offset%2 == 1 )
{//如果offset为奇数,len必须为奇数
if(len%2 != 1)
return -3;
}
//将第0字节的最高2位强制置为0。
if(offset + len == 0)
*msg &= 0x3F;
if(zone == 1)
address = 176;
else
address = 736;
address = address + offset*8;
_C102Erase(address, len*8);
return _C102Write(address, len*8, msg);
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
int _C1604Erase(int address, int bitlen)
{
/*
功能:从IC卡地址address开始,擦除IC卡中bitlen个比特数据。如果address不小于0,先执行上电和复位操作。
输入:address:起始比特地址, 如果小于0, 从当前地址开始, 如果等于-2,擦除后地址不加, bitlen应为1
bitlen: 要擦除的比特长度,应该是8的倍数,否则msg应左对齐
msg: 要写的内容,字节形式
输出:返回值: -1 = 卡不在位;
-2 = 擦除失败,与读出的不一致。
0 = 正确
*/
int i;
if(address >= 0)
{
if( _C102Addressing(address) < 0)
return -1;
}
for(i=0; i<bitlen; i+=8)
{
_CardSetClock(LOW);
_CardSetPGM(HIGH);
_CardDelay(TDV); //Tdv=2us
if(_CardPutIO(HIGH) < 0)
return -1;
_CardDelay(TSPR);
_CardSetClock(HIGH);
_CardDelay(THPR); //Thpr=0.2us
_CardSetPGM(LOW);
usleep(TCHP1604);
_CardSetClock(LOW);
_CardDelay(TDV); //Tdv=2us
if( _CardReadIO() != 1 )
return -2;
if(address != -2)
_C102AddsInc(8);
}
return 0;
}
int _C1604Write(int address, int bitlen, unsigned char *msg)
{
/*
功能:从IC卡地址address开始向IC卡写bitlen个比特数据。如果address不小于0,先执行上电和复位操作。
输入:address:起始比特地址, 如果小于0, 从当前地址开始, 如果等于-2,写后地址不加, bitlen应为1
bitlen: 要写的比特长度,应该是8的倍数,否则msg应左对齐
msg: 要写的内容,字节形式
输出:返回值: -1 = 卡不在位;
-2 = 写入失败,与读出的不一致。
0 = 正确
*/
int i, k;
int ch;
if(address >= 0)
{
if( _C102Addressing(address) < 0)
return -1;
}
for(i=0, k=7; i<bitlen; i++)
{
ch = *msg;
ch = ch >> k;
ch &= 1;
k--;
if(k < 0)
{
msg++;
k = 7;
}
////////////////////////////////////////////////
if(ch == 0)
{
_CardSetClock(LOW);
_CardSetPGM(HIGH);
_CardDelay(TDV); //Tdv=2us
if(_CardPutIO(LOW) < 0)
return -1;
_CardDelay(TSPR); //Tspr
_CardSetClock(HIGH);
_CardDelay(THPR); //Thpr=0.2us
_CardSetPGM(LOW);
usleep(TCHP1604);
_CardSetClock(LOW);
_CardDelay(TDV); //Tdv=2us
}
if( _CardReadIO() != ch )
return -2;
if(address != -2)
_C102AddsInc(1);
}
return 0;
}
int C1604ReadFZ(unsigned char *fz)
{
/*
功能:读厂商代码。厂商代码为2字节。
输入:无
输出:fz: 厂商代码
返回值: -1 = 卡不在位;
0 = 正确
*/
return _C102Read(0, 16, fz);
}
int C1604ReadIZ(unsigned char *iz)
{
/*
功能:读卡商代码。卡商代码为8字节。
输入:无
输出:iz: 返回内容,字节形式
返回值: -1 = 卡不在位;
0 = 正确
*/
return _C102Read(16, 64, iz);
}
int C1604ReadSCAC()
{
/*
功能:读密码(或区密码)校验错误计数。
输入:无
输出:返回值: -1 = 卡不在位;
0-8 = 允许错误次数,为0表示卡已被锁住
*/
unsigned char scac;
unsigned char ch;
int i, count=0;
if(_C102Read(96, 8, &scac) < 0)
return -1;
for(i=0; i<8; i++)
{
ch = (scac >> i) & 1;
if( ch == 1)
count++;
}
return count;
}
int C1604ReadCPZ(int offset, int len, unsigned char *cpz)
{
/*
功能:读代码保护区。代码保护区为8字节。
输入:offset: 0-7
len: 1-8
输出:cpz: 返回内容,字节形式
返回值: -1 = 卡不在位;
-3 = 参数错误,要写入的内容超出存储区
0 = 正确
*/
if(offset+len > 8)
return -3;
return _C102Read(104+offset*8, len*8, cpz);
}
int C1604ReadMTZ(unsigned char *mtz)
{
/*
功能:读测试区。测试区为2字节。
输入:无
输出:mtz: 返回内容,字节形式
返回值: -1 = 卡不在位;
0 = 正确
*/
return _C102Read(16040, 16, mtz);
}
int C1604WriteMTZ(unsigned char *mtz)
{
/*
功能:写测试区。测试区为2字节。
输入:mtz:2字节
输出:返回值: -1 = 卡不在位;
-2 = 写入失败,与读出的不一致。
0 = 正确
*/
_C1604Erase(16040, 16);
return _C1604Write(16040, 16, mtz);
}
int C1604CheckSC(unsigned char *sc)
{
/*
功能:比较密码。密码为2字节。
输入:sc:2字节
输出:返回值: 0 = 正确
其它 = 错误
*/
return C102CheckSC(sc);
}
int C1604WriteIZ(unsigned char *iz)
{
/*
功能:写卡商代码。卡商代码为8字节。
输入:iz:8字节形式
输出:返回值: -1 = 卡不在位;
-2 = 写入失败,与读出的不一致。
0 = 正确
*/
_C1604Erase(16, 64);
return _C1604Write(16, 64, iz);
}
int C1604WriteCPZ(int offset, int len, unsigned char *cpz)
{
/*
功能:写代码保护区。写代码保护区为8字节。
输入:offset: 0-7
len: 1-8
cpz: 8字节
输出:返回值: -1 = 卡不在位;
-2 = 写入失败,与读出的不一致。
-3 = 参数错误,要写入的内容超出存储区
0 = 正确
*/
if( offset+len > 8 )
return -3;
_C1604Erase(104 + offset*8, len*8);
return _C1604Write(104 + offset*8, len*8, cpz);
}
int C1604UpdateSC(unsigned char *sc)
{
/*
功能:更新密码。密码为2字节。
输入:sc:2字节
输出:返回值: -1 = 卡不在位;
-2 = 写入失败,与读出的不一致。
0 = 正确
*/
_C1604Erase(80, 16);
return _C1604Write(80, 16, sc);
}
int C1604ReadAZ(int zone, int offset, int len, unsigned char *msg)
{
/*
功能:读应用区1-4中的数据。
应用区1为1195字节: 27--1221。
应用区2为256字节: 1227--1482。
应用区3为256字节: 1488--1743。
应用区4为256字节: 1749--2004。
总共1963字节
输入:zone: 1-4
offset: 字节偏移
len: 字节长度
输出:msg: 返回内容,字节形式
返回值: -1 = 卡不在位;
-3 = 参数错误,要写入的内容超出存储区
0 = 正确
*/
int address;
int total;
switch(zone)
{
case 1:
address = 216;
total = 1195;
break;
case 2:
address = 9816;
total = 256;
break;
case 3:
address = 11904;
total = 256;
break;
case 4:
address = 13992;
total = 256;
break;
default:
return -3;
}
if( offset+len > total )
return -3;
address = address + offset*8;
return _C102Read(address, len*8, msg);
}
int C1604WriteAZ(int zone, int offset, int len, unsigned char *msg)
{
/*
功能:向应用区1-4中写数据。每个应用区的第0字节的最高2位被强制置为0。
应用区1为1195字节: 27--1221。
应用区2为256字节: 1227--1482。
应用区3为256字节: 1488--1743。
应用区4为256字节: 1749--2004。
总共1963字节
输入:zone: 1-4
offset: 字节偏移
len: 字节长度
msg: 要写的内容,字节形式
输出:返回值: -1 = 卡不在位;
-2 = 写入失败,与读出的不一致。
-3 = 参数错误,要写入的内容超出存储区
*/
int address;
int total;
switch(zone)
{
case 1:
address = 216;
total = 1195;
break;
case 2:
address = 9816;
total = 256;
break;
case 3:
address = 11904;
total = 256;
break;
case 4:
address = 13992;
total = 256;
break;
default:
return -3;
}
if( offset+len > total )
return -3;
//将第0字节的最高2位强制置为0。
if(offset + len == 0)
*msg &= 0x3F;
address = address + offset*8;
_C1604Erase(address, len*8);
return _C1604Write(address, len*8, msg);
}
////////////////////////////////////////////////////////
int GetBufferLength(int StartBitAddress, int length)
{
int k;
int s;
s = StartBitAddress;
for(k=0; k<length; k++)
{
if( ((s>=9776) && (s<9824))
||((s>=11864) && (s<11912))
||((s>=13952) && (s<14000)) )
{
return k;
}
s += 8;
}
return k;
}
int C1604ReadAZBuffer(int offset, int len, unsigned char *msg)
{
/*
功能:从应用区中读数据。将4个应用区串联起来,向上层提供一个1959字节大小的区域。
应用区1为1195字节: 27--1221。
应用区2为256字节: 1227--1482。
应用区3为256字节: 1488--1743。
应用区4为256字节: 1749--2004。
总共1963字节,每个区的第0字节不能使用,因为含有读写控制位。
可用空间为1963-4=1959字节
输入:offset: 字节偏移
len: 字节长度
输出:msg: 返回内容,字节形式
返回值: -1 = 卡不在位;
-3 = 参数错误,要写入的内容超出存储区
0 = 正确
*/
int i;
int ret;
int address;
int t;
int wlen=0; //已经读取的字节数
if( offset+len > 1959 )
return -3;
address = 216+8;
address = address + offset*8;
for(i=0; i<len; )
{
if( ((address>=9776) && (address<9824))
||((address>=11864) && (address<11912))
||((address>=13952) && (address<14000)) )
{
address += 8;
}
else
{
t = GetBufferLength(address, len-wlen);
ret = _C102Read(address, 8*t, msg);
if(ret < 0)
return ret;
msg += t;
i += t;
address += 8*t;
wlen += t;
}
}
return 0;
}
int C1604WriteAZBuffer(int offset, int len, unsigned char *msg)
{
/*
功能:向应用区中写数据。将4个应用区串联起来,向上层提供一个1959字节大小的区域。
应用区1为1195字节: 27--1221。
应用区2为256字节: 1227--1482。
应用区3为256字节: 1488--1743。
应用区4为256字节: 1749--2004。
总共1963字节,每个区的第0字节不能使用,因为含有读写控制位。
可用空间为1963-4=1959字节
输入:offset: 字节偏移
len: 字节长度
msg: 要写的内容,字节形式
输出:返回值: -1 = 卡不在位;
-2 = 写入失败,与读出的不一致。
-3 = 参数错误,要写入的内容超出存储区
0 = 正确
*/
int i;
int ret;
int address;
int t;
int wlen=0; //已经写入的字节数
if( offset+len > 1959 )
return -3;
address = 216+8;
address = address + offset*8;
for(i=0; i<len; )
{
if( ((address>=9776) && (address<9824))
||((address>=11864) && (address<11912))
||((address>=13952) && (address<14000)) )
{
address += 8;
}
else
{
t = GetBufferLength(address, len-wlen);
ret = _C1604Erase(address, 8*t);
if(ret < 0)
return ret;
ret = _C1604Write(address, 8*t, msg);
if(ret < 0)
return ret;
msg += t;
i += t;
address += 8*t;
wlen += t;
}
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -