⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ecrcard.c

📁 写IC卡的参考代码,应用于读写IC卡的数据,电表,水表开发场合适用
💻 C
📖 第 1 页 / 共 3 页
字号:
#define uchar	unsigned char
#define uint	unsigned int
#define ulong	unsigned long

#include <intrins.h>
#include <absacc.h>
#include "reg52.h"
#include "upsd.h"
#include "ecrbios.h"

/***********************CPU 卡错误代码*****************************/
#define TIMEO     				0xd3		//超时
#define PARERR     				0xd6		//奇偶错
#define RECEOV    				0xd7		//接受CPU数据超长
#define CPUCARDER 				0xd8		//无法读取该卡
#define TRANER    				0xd9		//与CPU卡通讯错误
#define XORERR    				0xda		//ATR数据异或校验错
#define CARDER    				0xc2		//卡类型错

#define FLASH_CARD 2	//CARD 型号代码定义
#define CPUCARD   1

#define MAXPAGE   2048		//flash card 最大页数
#define MAXBYTE   264		//flash card 每页最大字节数
#define RW_FLASH_CARD	//是否编译FLASH CARD 的相关程序

/*********************定义FLASH CARD的硬件接口模式******************/
//#define	SPI_MODE0	//select transmit mode
//#define	SPI_MODE3
#define	POLARITY_LOW
//#define	POLARITY_HIGH

/*********************定义FLASH CARD的存储交换模式******************/
#define	FLASH_BUFFER
//#define	FLASH_PAGE
//#define	FLASH_ARRAY		//select read mode 

/*******************选择FLASH CARD交换缓冲区*****************/
#define	FLASH_BUFFER1	//select buffer1 or buffer2

#ifdef SPI_MODE0
	#define ARRAY_READ_COM	0xe8	//直接阵列方式读主存储区数据
	#define PAGE_READ_COM	0xd2	//直接页方式读主存储区数据
	#define STATUS_READ_COM	0xd7	//读FLASH CARD 状态
	#ifdef	FLASH_BUFFER1
		#define BUFFER_READ_COM	0xd4	//从FLASH CARD缓冲区读数据
	#else
		#define BUFFER_READ_COM	0xd6
	#endif	//FLASH_BUFFER1
#endif

#ifdef SPI_MODE3
	#define	HIGH
	#define ARRAY_READ_COM	0xe8
	#define PAGE_READ_COM	0xd2
	#define STATUS_READ_COM	0xd7
	#ifdef	FLASH_BUFFER1
		#define BUFFER_READ_COM	0xd4
	#else
		#define BUFFER_READ_COM	0xd6
	#endif	//FLASH_BUFFER1
#endif

#ifdef POLARITY_LOW
	#define ARRAY_READ_COM	0x68
	#define PAGE_READ_COM	0x52
	#define STATUS_READ_COM	0x57
	#ifdef	FLASH_BUFFER1
		#define BUFFER_READ_COM	0x54
	#else
		#define BUFFER_READ_COM	0x56
	#endif	//FLASH_BUFFER1
#endif

#ifdef POLARITY_HIGH
	#define	HIGH
	#define ARRAY_READ_COM	0x68
	#define PAGE_READ_COM	0x52
	#define STATUS_READ_COM	0x57
	#ifdef	FLASH_BUFFER1
		#define BUFFER_READ_COM	0x54
	#else
		#define BUFFER_READ_COM	0x56
	#endif	//FLASH_BUFFER1
#endif

#ifdef	FLASH_BUFFER1
	#define BUFFER_SECTOR_COM	0x53	//将主存储区读到FLASH CARD缓冲区
	#define BUFFER_WRITE_COM	0x82	//写数据到FLASH CARD缓冲区
	#define BUFFER_RWRITE_COM	0x58	//将FLASH CARD缓冲区数据写到主存储区
	#define BUFFER_COMPARE_COM	0x60	//比较FLASH CARD缓冲区与主存储区的数据
#else
	#define BUFFER_SECTOR_COM	0x55
	#define BUFFER_WRITE_COM	0x85
	#define BUFFER_RWRITE_COM	0x59
	#define BUFFER_COMPARE_COM	0x61
#endif	//FLASH_BUFFER1

/*******************IO口定义****************************/
sbit SAM_CARD_VCC=P1^6;
sbit SAM_CARD_RST=P1^5;
sbit SAM_CARD_IO=P1^4;
sbit IC_CARD_IN=P1^3;
sbit IC_CARD_VCC=P1^2;
sbit IC_CARD_RST=P1^1;
sbit IC_CARD_IO=P1^0;	//CPU CARD 的IO口对应FLASH CARD 的CLK脚
sbit FLASH_CARD_CLK=P1^0;
sbit FLASH_CARD_IO=P3^7;
sbit FLASH_CARD_CS=P3^6;
#define en_cpu_clk()	{PAGE=(PAGE&0xef)|0x10;}	//使能位PAGE.4
#define dis_cpu_clk()	{PAGE=PAGE&0xef;}
#define en_sam_clk()	{PAGE=(PAGE&0xf7)|0x08;}	//使能位PAGE.3
#define dis_sam_clk()	{PAGE=PAGE&0xf7;}

/*******************变量定义****************************/
uchar bdata r_w_byte;	//位变量,SPI,IIC总线使用
sbit HBIT=r_w_byte^7;
sbit LBIT=r_w_byte^0;
uchar xdata cpu_t,cpu_ta1,cpu_d,cpu_tc1,cpu_tc2;	//CPU CARD的复位应答特征数据
uchar xdata sam_t,sam_ta1,sam_d,sam_tc1,sam_tc2;	//SAM CARD的复位应答特征数据
uchar xdata card_type;
typedef union { uint word;
                struct{uchar Hi;uchar Lo;} byte;
              } UNST;
UNST crc_value;

uint code crc_tab[256] =	//x16 + x15 + x13 + 1
    {
    0x0000,0xc0c1,0xc181,0x0140,0xc301,0x03c0,0x0280,0xc241,
    0xc601,0x06c0,0x0780,0xc741,0x0500,0xc5c1,0xc481,0x0440,
    0xcc01,0x0cc0,0x0d80,0xcd41,0x0f00,0xcfc1,0xce81,0x0e40,
    0x0a00,0xcac1,0xcb81,0x0b40,0xc901,0x09c0,0x0880,0xc841,
    0xd801,0x18c0,0x1980,0xd941,0x1b00,0xdbc1,0xda81,0x1a40,
    0x1e00,0xdec1,0xdf81,0x1f40,0xdd01,0x1dc0,0x1c80,0xdc41,
    0x1400,0xd4c1,0xd581,0x1540,0xd701,0x17c0,0x1680,0xd641,
    0xd201,0x12c0,0x1380,0xd341,0x1100,0xd1c1,0xd081,0x1040,
    0xf001,0x30c0,0x3180,0xf141,0x3300,0xf3c1,0xf281,0x3240,
    0x3600,0xf6c1,0xf781,0x3740,0xf501,0x35c0,0x3480,0xf441,
    0x3c00,0xfcc1,0xfd81,0x3d40,0xff01,0x3fc0,0x3e80,0xfe41,
    0xfa01,0x3ac0,0x3b80,0xfb41,0x3900,0xf9c1,0xf881,0x3840,
    0x2800,0xe8c1,0xe981,0x2940,0xeb01,0x2bc0,0x2a80,0xea41,
    0xee01,0x2ec0,0x2f80,0xef41,0x2d00,0xedc1,0xec81,0x2c40,
    0xe401,0x24c0,0x2580,0xe541,0x2700,0xe7c1,0xe681,0x2640,
    0x2200,0xe2c1,0xe381,0x2340,0xe101,0x21c0,0x2080,0xe041,
    0xa001,0x60c0,0x6180,0xa141,0x6300,0xa3c1,0xa281,0x6240,
    0x6600,0xa6c1,0xa781,0x6740,0xa501,0x65c0,0x6480,0xa441,
    0x6c00,0xacc1,0xad81,0x6d40,0xaf01,0x6fc0,0x6e80,0xae41,
    0xaa01,0x6ac0,0x6b80,0xab41,0x6900,0xa9c1,0xa881,0x6840,
    0x7800,0xb8c1,0xb981,0x7940,0xbb01,0x7bc0,0x7a80,0xba41,
    0xbe01,0x7ec0,0x7f80,0xbf41,0x7d00,0xbdc1,0xbc81,0x7c40,
    0xb401,0x74c0,0x7580,0xb541,0x7700,0xb7c1,0xb681,0x7640,
    0x7200,0xb2c1,0xb381,0x7340,0xb101,0x71c0,0x7080,0xb041,
    0x5000,0x90c1,0x9181,0x5140,0x9301,0x53c0,0x5280,0x9241,
    0x9601,0x56c0,0x5780,0x9741,0x5500,0x95c1,0x9481,0x5440,
    0x9c01,0x5cc0,0x5d80,0x9d41,0x5f00,0x9fc1,0x9e81,0x5e40,
    0x5a00,0x9ac1,0x9b81,0x5b40,0x9901,0x59c0,0x5880,0x9841,
    0x8801,0x48c0,0x4980,0x8941,0x4b00,0x8bc1,0x8a81,0x4a40,
    0x4e00,0x8ec1,0x8f81,0x4f40,0x8d01,0x4dc0,0x4c80,0x8c41,
    0x4400,0x84c1,0x8581,0x4540,0x8701,0x47c0,0x4680,0x8641,
    0x8201,0x42c0,0x4380,0x8341,0x4100,0x81c1,0x8081,0x4040,
    };
/*--------------------------------------------------------------
	cpu硬件crc校验
	入口参数:
		length == 被校验buffer长度
		clear  == 1
		buffer == 被校验的数据
	出口参数:
		== crc校验值
--------------------------------------------------------------*/
uint crcxdata(uint length,uchar clear,void *buffer)
{
	UNST	temp;
	if(clear)	crc_value.word=0;
	do
	{
		temp.byte.Hi=0;
		temp.byte.Lo=crc_value.byte.Hi;
		crc_value.word= temp.word^crc_tab[crc_value.byte.Lo^(*(uchar *)buffer)];
		((uchar *)buffer)++;
	}while(--length);
	return crc_value.word;
}

void select_card_type(uchar type)       /* 卡型选择TYPE=0 4442卡,TYPE=1 CPU卡 */
{
	card_type=type;
}

/* 插卡检测 有卡插入返回0,否则返回1 */
uchar inserted_card(void)
{
	uchar	i;
	for(i=0;i<100;i++)
	{
		if(IC_CARD_IN)	return 1;	//常开
//		if(!IC_CARD_IN)	return 1;	//常闭
		delayms(250,1);
	}
	IC_CARD_VCC=0;
	delayms(125,1);
	
	IC_CARD_RST=1;	//4442 reset,flash,cpu work
	delayms(10,1);
	
	FLASH_CARD_IO=1;
	if(FLASH_CARD_IO)	//复位脚为1时,是否短路
	{
		IC_CARD_VCC=1;
		IC_CARD_RST=0;
		FLASH_CARD_IO=0;
		return 0;
	}
	
	IC_CARD_RST=0;	//4442work
	FLASH_CARD_IO=1;
	if(FLASH_CARD_IO)	//复位脚为0时,是否短路
	{
		IC_CARD_VCC=1;
		FLASH_CARD_IO=0;
		return 0;
	}
	IC_CARD_VCC=1;	//短路,断电返回无卡
	FLASH_CARD_IO=0;
	return 1;
}

uchar inserted_sam_card(void)
{
	SAM_CARD_VCC=0;
	delayms(125,1);
	
	SAM_CARD_RST=1;	//reset
	delayms(10,1);
	
	SAM_CARD_RST=0;
	SAM_CARD_IO=1;
	if(SAM_CARD_IO)	//复位脚为0时,是否短路
	{
		SAM_CARD_VCC=1;
		delayms(250,2);
		SAM_CARD_IO=0;
		return 0;
	}
	SAM_CARD_VCC=1;	//短路,断电返回无卡
	delayms(250,2);
	SAM_CARD_IO=0;
	delayms(250,100);
	return 1;
}

void card_vcc(uchar vcc)                /* vcc=1 上电,vcc=0 下电 */
{
	if(vcc == 1)
	{
		IC_CARD_RST=0;
		if(card_type==CPUCARD)
		{
			IC_CARD_IO=1;
			en_cpu_clk();	//enable CPU 3.67M
		}
		else
		{
			FLASH_CARD_CLK=0;
			dis_cpu_clk();	//disable CPU 3.67M
		}
		FLASH_CARD_IO=1;
		FLASH_CARD_CS=1;	//FLASH CS
		IC_CARD_VCC=0;
		delayms(250,5);
	}
	else
	{
		FLASH_CARD_CS=1;	//FLASH CS
		IC_CARD_RST=1;
		IC_CARD_VCC=1;
		dis_cpu_clk();	//disable CPU CARD 3.67M
		IC_CARD_RST=0;
		IC_CARD_IO=0;
		FLASH_CARD_IO=0;
		FLASH_CARD_CS=0;	//FLASH CS
		delayms(250,5);
	}
}

void samcard_vcc(uchar vcc)                /* vcc=1 上电,vcc=0 下电 */
{
	if(vcc == 1)
	{
		SAM_CARD_RST=0;
		SAM_CARD_IO=1;
		en_sam_clk();	//enable SAM 3.67M
		SAM_CARD_VCC=0;
		delayms(250,5);
	}
	else
	{
		SAM_CARD_RST=1;
		dis_sam_clk();	//disable SAM 3.679M
		SAM_CARD_VCC=1;
		delayms(250,5);
		SAM_CARD_RST=0;
		SAM_CARD_IO=0;
	}
}

#ifdef RW_FLASH_CARD
/* AT45D041 FLASH CARD*/

#ifdef POLARITY_LOW
/****************************************************************/
                /*写卡命令微指令*/
void w_flash_card(uchar byte) /* write flash card pluse */
{
	uchar i=8;
	r_w_byte=byte;
	do{
		FLASH_CARD_IO=HBIT;
		FLASH_CARD_CLK=1;
		FLASH_CARD_CLK=0;
		r_w_byte=r_w_byte<<1;
	}while(--i);
}
/*********************************************************/
               /*读卡数据微指令*/
uchar r_flash_card(void)  /* read flash card pluse */
{
	uchar i=8;
	FLASH_CARD_IO=1;
	
	do{
		r_w_byte=r_w_byte<<1;
		FLASH_CARD_CLK=1;
		FLASH_CARD_CLK=0;
		LBIT=FLASH_CARD_IO;
	}while(--i);
	return (r_w_byte);
}
#else	//SPI_MODE
/****************************************************************/
                /*写卡命令微指令*/
void w_flash_card(uchar byte) /* write flash card pluse */
{
	uchar i=8;
	r_w_byte=byte;
	do{
		FLASH_CARD_CLK=0;
		FLASH_CARD_IO=HBIT;
		r_w_byte=r_w_byte<<1;
		FLASH_CARD_CLK=1;
	}while(--i);
}
/*********************************************************/
               /*读卡数据微指令*/
uchar r_flash_card(void)  /* read flash card pluse */
{
	uchar i=8;
	FLASH_CARD_IO=1;
	
	do{
		r_w_byte=r_w_byte<<1;
		FLASH_CARD_CLK=1;
		FLASH_CARD_CLK=0;
		LBIT=FLASH_CARD_IO;
	}while(--i);
	return (r_w_byte);
}
#endif	//POLARITY_LOW

/***********************************************************/
           //读卡状态,空闲返回0,否则返回1
uchar read_card_status(void)
{
	uint	i=500;
	do
	{
		FLASH_CARD_CS=1;
		_nop_ ( );
		_nop_ ( );
	
		#ifdef	HIGH
			FLASH_CARD_CLK=1;
		#else
			FLASH_CARD_CLK=0;
		#endif
		FLASH_CARD_CS=0;
		_nop_ ( );
		_nop_ ( );
		w_flash_card(STATUS_READ_COM);
		r_flash_card();
		#ifdef	HIGH
			FLASH_CARD_CLK=1;
		#else
			FLASH_CARD_CLK=0;
		#endif
		_nop_ ( );
		_nop_ ( );
		FLASH_CARD_CS=1;
		if((r_w_byte&0xc0)==0x80) return (0);
	}while(--i);
	return 1;
}

/**************************************************************/
//发送读FLASH卡缓冲区命令及地址
void read_flash_buffer(uint baddr)  
{
	FLASH_CARD_CS=1;
	_nop_ ( );
	_nop_ ( );
	
	#ifdef	HIGH
		FLASH_CARD_CLK=1;
	#else
		FLASH_CARD_CLK=0;
	#endif
	FLASH_CARD_CS=0;
	_nop_ ( );
	_nop_ ( );
	w_flash_card(BUFFER_READ_COM);
	w_flash_card(0);
	w_flash_card((baddr>>8)&0xff);
	w_flash_card(baddr&0xff);
	w_flash_card(0x0);
}
/**************************************************************/
//发送写FLASH卡缓冲区命令及地址
void write_flash_buffer(uint page,uint baddr)  
{
	#ifdef	HIGH
		FLASH_CARD_CLK=1;
	#else
		FLASH_CARD_CLK=0;
	#endif
	FLASH_CARD_CS=0;
	_nop_ ( );
	_nop_ ( );
	w_flash_card(BUFFER_WRITE_COM);             /* command 82h write main page though buffer1 */    
	w_flash_card((page>>7)&0xff);          
	w_flash_card(((page<<1)|(baddr>>8))&0xff);
	w_flash_card(baddr&0xff);
}
/********************************************************************/
//发送FLASH卡缓冲区与主存储区交换或比较命令及地址
uchar write_card_com(uchar command,uint page)           
{
	FLASH_CARD_CS=1;
	_nop_ ( );
	_nop_ ( );

	#ifdef	HIGH
		FLASH_CARD_CLK=1;
	#else
		FLASH_CARD_CLK=0;
	#endif
	FLASH_CARD_CS=0;
	_nop_ ( );
	_nop_ ( );
	w_flash_card(command);
	w_flash_card((page>>7)&0xff);
	w_flash_card((page<<1)&0xff);
	w_flash_card(0x0);
	#ifdef	HIGH
		FLASH_CARD_CLK=1;
	#else
		FLASH_CARD_CLK=0;
	#endif
	_nop_ ( );
	_nop_ ( );
	FLASH_CARD_CS=1;
	return(read_card_status());
}
/********************************************************************/
//发送直接阵列或页方式读FLASH卡命令及地址
void array_page_read(uchar command,uint page,uint baddr)           
{
	FLASH_CARD_CS=1;
	_nop_ ( );
	_nop_ ( );

	#ifdef	HIGH
		FLASH_CARD_CLK=1;
	#else
		FLASH_CARD_CLK=0;
	#endif
	FLASH_CARD_CS=0;
	_nop_ ( );
	_nop_ ( );
	w_flash_card(command);
	w_flash_card((page>>7)&0xff);
	w_flash_card(((page<<1)|(baddr>>8))&0xff);
	w_flash_card(baddr&0xff);
	w_flash_card(0x0);
	w_flash_card(0x0);
	w_flash_card(0x0);
	w_flash_card(0x0);
}

/**************************************************************/
// FLASH CARD卡的上电
void initial_flash_card1(void)       
{
	select_card_type(FLASH_CARD);

	card_vcc(1);
	IC_CARD_RST=1;
	delayms(250,1);
	IC_CARD_RST=0;
	delayms(250,10);
	IC_CARD_RST=1;
	delayms(250,40);
}

#ifdef FLASH_BUFFER	//缓冲区模式
/**************************************************************/
/*BUFFER READ*/
uchar  read_flash_card1(ulong addr,uint leng,uchar xdata *str)
{
	uint sector,card_addr;

	initial_flash_card1();
	
	sector=(addr/0x108)&0xfff;
	if(sector>=MAXPAGE) {card_vcc(0);return 1;}    

	card_addr=(addr%0x108)&0x1ff;
//FLASH卡主存储区数据读到缓冲区
	if(write_card_com(BUFFER_SECTOR_COM,sector)) {card_vcc(0);return 1;}
//发送读FLASH缓冲区命令及地址
	read_flash_buffer(card_addr);
	do
	{
		*str=r_flash_card();	//读1字节缓冲区数据
		str++;
		card_addr++;
		if((card_addr>=MAXBYTE)&&(leng!=1))                    
		{
			#ifdef	HIGH
				FLASH_CARD_CLK=1;
			#else
				FLASH_CARD_CLK=0;
			#endif	//HIGH
			_nop_ ( );
			_nop_ ( );
			FLASH_CARD_CS=1;
			sector++;
			if(sector>=MAXPAGE) {card_vcc(0);return 1;}    
			card_addr=0;
		//FLASH卡主存储区数据读到缓冲区
			if(write_card_com(BUFFER_SECTOR_COM,sector)) {card_vcc(0);return 1;}
		//发送读FLASH缓冲区命令及地址
			read_flash_buffer(card_addr);
		}
	}while(--leng);
	#ifdef	HIGH
		FLASH_CARD_CLK=1;
	#else
		FLASH_CARD_CLK=0;
	#endif
	_nop_ ( );
	_nop_ ( );
	FLASH_CARD_CS=1;
	card_vcc(0);
	return 0;
}
#endif //FLASH_BUFFER

#ifdef FLASH_PAGE	//页模式
/**************************************************************/
/*PAGE READ*/
uchar  read_flash_card1(ulong addr,uint leng,uchar xdata *str)
{
	uint sector,card_addr;

	initial_flash_card1();
	
	sector=(addr/0x108)&0xfff;
	if(sector>=MAXPAGE) {card_vcc(0);return 1;}    

	card_addr=(addr%0x108)&0x1ff;
//发送直接页方式读FLASH卡主存储区命令及地址
	array_page_read(PAGE_READ_COM,sector,card_addr);
	do
	{
		*str=r_flash_card();	//读1字节FLASH卡主存储区数据
		str++;
		card_addr++;
		if((card_addr>=MAXBYTE)&&(leng!=1))                    
		{
			#ifdef	HIGH
				FLASH_CARD_CLK=1;
			#else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -