📄 ic.c
字号:
#include "dtm_v3.h"
#include "dtm.h"
#include "externdef.h"
#include <stdio.h>
#define ICPAGESIZE 32
/****************************************************************************
* 名称:ICWriteByte()
* 功能:向IC卡发送一字节数据
* 入口参数:cData 要发送的数据
* 出口参数:无
* 说明:发送数据时,高位先发送。
****************************************************************************/
_BYTE ICWriteByte(_BYTE cData)
{
_WORD i;
pCPLD[0x0a]=0x03;
// DelayMCK4(1);
for(i=0; i<8; i++) { // 发送8位数据
/* 设置PIO的DATA输出值 */
if ((cData&0x80)!=0) {
gcpCPLDReg[4] |= CPLD_IC_DATA;
pCPLD[8]=gcpCPLDReg[4];
}
else {
gcpCPLDReg[4] &=~CPLD_IC_DATA;
pCPLD[8]=gcpCPLDReg[4];
}
cData <<= 1;
gcpCPLDReg[4] |= CPLD_IC_CLK;
pCPLD[8]=gcpCPLDReg[4]; // SCL = 1
DelayMCK4(SPI_BASE_DELAY_TIME);
gcpCPLDReg[4] &= ~CPLD_IC_CLK;
pCPLD[8]=gcpCPLDReg[4]; // SCL = 0
DelayMCK4(SPI_BASE_DELAY_TIME-2);
}
gcpCPLDReg[4] |=CPLD_IC_DATA; pCPLD[8]=gcpCPLDReg[4];
pCPLD[0x0a]=0x01;
gcpCPLDReg[4] |=CPLD_IC_CLK; pCPLD[8]=gcpCPLDReg[4];
DelayMCK4(1); // SCL = 1
for(i=0; i<0x900; i++){
if ((pCPLD[8] & 0x01) == 0) {
gcpCPLDReg[4] &= ~CPLD_IC_CLK; pCPLD[8]=gcpCPLDReg[4]; // SCL = 0
return(C_OK);
}
}
return(C_NOTOK);
}
/****************************************************************************
* 名称:ICReadByte()
* 功能:IC卡读一字节数据
* 入口参数:cData 要发送的数据
* 出口参数:无
* 说明:发送数据时,高位先发送。
****************************************************************************/
_BYTE ICReadByte(void)
{
_BYTE i;
_BYTE cData;
pCPLD[0x0a]=0x01;
DelayMCK4(1);
for(i=0; i<8; i++) { // 发送8位数据
gcpCPLDReg[4] |= CPLD_IC_CLK; pCPLD[8]=gcpCPLDReg[4]; // SCL = 1
cData*=2;
DelayMCK4(SPI_BASE_DELAY_TIME);
if ((pCPLD[8] &0x01) == 0x01 ) cData++;
gcpCPLDReg[4] &=~CPLD_IC_CLK; pCPLD[8]=gcpCPLDReg[4]; // SCL = 0
DelayMCK4(SPI_BASE_DELAY_TIME);
}
return(cData);
}
/****************************************************************************
* 名称:ICSendStartBit()
* 功能:发送IC卡读写的起始位
****************************************************************************/
void ICSendStartBit(void) /*起始*/
{
pCPLD[0x0a]=0x03; //0x00000011,写数据
DelayMCK4(1);
//while(1){
gcpCPLDReg[4] |= CPLD_IC_DATA; pCPLD[8]=gcpCPLDReg[4]; //SDA=1
gcpCPLDReg[4] |= CPLD_IC_CLK; pCPLD[8]=gcpCPLDReg[4]; //SCL=1
DelayMCK4(SPI_BASE_DELAY_TIME);
gcpCPLDReg[4] &=~CPLD_IC_DATA; pCPLD[8]=gcpCPLDReg[4]; //SDA=0
DelayMCK4(SPI_BASE_DELAY_TIME);
//}
gcpCPLDReg[4] &=~CPLD_IC_CLK; pCPLD[8]=gcpCPLDReg[4]; //SCL=0
}
/****************************************************************************
* 名称:ICSendStopBit()
* 功能:发送IC卡读写的中止位
****************************************************************************/
void ICSendStopBit(void) /*停止*/
{
pCPLD[0x0a]=0x03;
DelayMCK4(1);
gcpCPLDReg[4] &=~CPLD_IC_DATA; pCPLD[8]=gcpCPLDReg[4]; // SDA = 0
gcpCPLDReg[4] |=CPLD_IC_CLK; pCPLD[8]=gcpCPLDReg[4]; // SCL = 1
DelayMCK4(SPI_BASE_DELAY_TIME);
gcpCPLDReg[4] |=CPLD_IC_DATA; pCPLD[8]=gcpCPLDReg[4]; // SDA = 1
}
/****************************************************************************
* 名称:ICSendAckBit()
* 功能:发送IC卡读写的应答位
****************************************************************************/
void ICSendAckBit (void) /*Ack发送*/
{
pCPLD[0x0a]=0x03;
gcpCPLDReg[4] &=~CPLD_IC_DATA; pCPLD[8]=gcpCPLDReg[4]; // SDA = 0
gcpCPLDReg[4] |=CPLD_IC_CLK; pCPLD[8]=gcpCPLDReg[4]; // SCL = 1
DelayMCK4(SPI_BASE_DELAY_TIME);
gcpCPLDReg[4] &=~CPLD_IC_CLK; pCPLD[8]=gcpCPLDReg[4]; // SCL = 0
}
/***************************************************************
* 把BUF中的数据写入IC卡
* 入口 wAddress;
* cLength
* cpBuf 不超过32个字节
***************************************************************/
_BYTE ICWritePage (_WORD wAddress,_BYTE cLength,_BYTE * cpBuf)
{
_BYTE j,cRetCode;
ICSendStartBit();
DelayMCK4(SPI_BASE_DELAY_TIME);
cRetCode=ICWriteByte(0xa0);
if(cRetCode!=C_OK) {
ICSendStopBit();
return(cRetCode);
}
j = (_BYTE)(wAddress>>8);
cRetCode=ICWriteByte(j);
if(cRetCode!=C_OK) {
ICSendStopBit();
return(cRetCode);
}
j = (_BYTE) (wAddress);
cRetCode=ICWriteByte(j);
if(cRetCode!=C_OK) {
ICSendStopBit ();
return(cRetCode);
}
for(j=0;j<cLength;j++) {
cRetCode= ICWriteByte(*(cpBuf+j));
if(cRetCode!=C_OK) {
ICSendStopBit();
return(cRetCode);
}
}
ICSendStopBit();
return(C_OK);
}
/*********************************************************
* 从IC卡读数据
* 入口 wAddress;
* cLength
* cpBuf 不超过32个字节
**********************************************************/
_BYTE ICReadPage (_WORD wAddress,_BYTE cLength,_BYTE *cpBuf)
{
_BYTE j,cRetCode;
ICSendStartBit ();
DelayMCK4(SPI_BASE_DELAY_TIME);
cRetCode = ICWriteByte(0xa0);
if(cRetCode!=C_OK) {
ICSendStopBit ();
return(cRetCode);
}
j=(_BYTE) (wAddress>>8);
cRetCode = ICWriteByte(j);
if(cRetCode!=C_OK) {
ICSendStopBit ();
return(cRetCode);
}
j=(_BYTE) (wAddress);
cRetCode = ICWriteByte(j);
if(cRetCode!=C_OK) {
ICSendStopBit ();
return(cRetCode);
}
ICSendStartBit();
cRetCode = ICWriteByte(0xa1);
if(cRetCode!=C_OK) {
ICSendStopBit ();
return(cRetCode);
}
*(cpBuf)=(ICReadByte());
if(cLength>1){
ICSendAckBit ();
for(j=1;j<cLength-1;j++){
*(cpBuf+j)=(ICReadByte());
ICSendAckBit ();
}
*(cpBuf+cLength-1)=(ICReadByte());
}
ICSendStopBit ();
return(C_OK);
}
//***********************************************************************************
//写入信息到IC卡中
//其中:
//函数的返回值为C_OK或C_NOTOK
//wAddress:读写或写入信息在IC卡中的起始地址
//wLength:读取或写入信息的长度
//cpBlockBuf:读取或待写入的信息
//***********************************************************************************
_BYTE ICWriteBlock(_WORD wAddress,_WORD wLength,_BYTE *cpBlockBuf)
{
_BYTE cLength,cAddL,cRetCode;
_WORD wAdd,wCurLen;
wAdd=wAddress;
wCurLen = 0;
while (wCurLen<wLength) {
if ((wAdd&0x001f)==0) { // 一页的起始
cLength = (_BYTE)((wCurLen+ICPAGESIZE>=wLength)?wLength-wCurLen:ICPAGESIZE);
}
else { // 一页的中间
cAddL = (_BYTE)(wAdd&0x1f);
cLength = ICPAGESIZE - cAddL; // 本页剩余字节的长度
if (wCurLen + cLength >wLength) { // 剩余字节长度不够
cLength = (_BYTE)(wLength - wCurLen);
}
}
cRetCode = ICWritePage(wAdd,cLength,cpBlockBuf);
DelayMCK4(5000*SPI_BASE_DELAY_TIME);
if (cRetCode!=C_OK) return(cRetCode);
wAdd += cLength;
wCurLen += cLength;
cpBlockBuf += cLength;
}
return(C_OK);
}
//***********************************************************************************
//读取信息到IC卡中
//其中:
//函数的返回值为C_OK或C_NOTOK
//wAddress:读写或写入信息在IC卡中的起始地址
//wLength:读取或写入信息的长度
//cpBlockBuf:读取或待写入的信息
//***********************************************************************************
_BYTE ICReadBlock(_WORD wAddress,_WORD wLength,_BYTE *cpBlockBuf)
{
_BYTE cLength,cAddL;
_WORD wAdd,wCurLen;
wAdd=wAddress;
wCurLen = 0;
while (wCurLen<wLength) {
if ((wAdd&0x001f)==0) { // 一页的起始
cLength = (_BYTE)((wCurLen+ICPAGESIZE>=wLength)?wLength-wCurLen:ICPAGESIZE);
}
else { // 一页的中间
cAddL = (_BYTE)(wAdd&0x1f);
cLength = ICPAGESIZE - cAddL; // 本页剩余字节的长度
if (wCurLen + cLength >wLength) { // 剩余字节长度不够
cLength = (_BYTE)(wLength - wCurLen);
}
}
ICReadPage(wAdd,cLength,cpBlockBuf);
DelayMCK4(5000*SPI_BASE_DELAY_TIME);
wAdd += cLength;
wCurLen += cLength;
cpBlockBuf += cLength;
}
return(C_OK);
}
//**********************************************
//有卡插入返回C_OK
//否则返回C_NOTOK
//**********************************************
_BYTE ICCheckCardInsert(void)
{
if ((PIO_PDSR & IC_IN) == 0)
return(C_OK);
else
return(C_NOTOK);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -