📄 ecrcard.c
字号:
#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 + -