📄 read_write_card.txt
字号:
#include<c8051F310.h>
#include <stdio.h>
#include<intrins.h>
#define SYSCLK 24500000 // 选择时钟
#define BAUDRATE 9600//选择波特率
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned char BYTE;
//L/////////////////////////////////////////////
sbit LEDST=P0^6;//LOAD
sbit LEDCP=P1^0;//CLK
sbit LEDDS=P0^7;//DI
sbit GUN=P1^5;
///////////全局变量////////////
uchar rxdi;//rxdbuff[rxdi]位置
BYTE CardData[16],//共用空间
card_ad[16]={0},//卡的固定空间
CardNO1[5],rxdbuff[24];//卡中数据,卡号,缓冲区
//L/////////////卡中需要存储的数据说明////////////
//------------------
//发票税号 1 [扇区0 块1] [最大16字节]
//持卡人 2 [扇区0 块2] [姓名 /前0~13字节 第14字节结尾 7个汉字/,
// 性别 /第15字节 00=男 0F=女/]
//-------------------
//单位 4~6 [扇区1 块0~2] [15个汉字 /块2第14字节结尾/]
//-------------------
//电话 8 [扇区2 块0] [00xx-0xxx-xxxxxxxx /块0 国际区号0~1 区号2~4 电话号5~15 共16字节 不足前面补零/]
//循环存储 9 [扇区2 块1] [最老的数据位置 /位0 从3~14增量循环存储
// 最新的数据位置 /位1
//密码 10 [扇区2 块2] [最大密码16字节]
//-------------------
//12次加油 [扇区3~14 块0~2] [时间 /年xxxx-月xx-日xx-周x-时xx-分xx-秒xx 块0 0~14字节/,
// 12~14 15~17...56~58 油站号 /块1 最大128位/,
// 加油重量,单价,金额 /块2 按LEDBUF的顺序存储,使用fanyibuf()译码 共16字节/]
//-------------------
//循环存储 [扇区15] [保留]
/*
BYTE fapiao[16];
BYTE name[16];
BYTE xingbie;
BYTE workplace[24];
BYTE phone[16];
BYTE old_pdata;
BYTE new_pdata;
BYTE key;
BYTE oil_time;
BYTE oil_place_num;*/
//L////////////////显示数据///////////////////
uchar leddata[]={
0x7e,//0
0x30,//1
0x6d,//2
0x79,//3
0x33,//4
0x5b,//5
0x5f,//6
0x70,//7
0x7f,//8
0x7b,//9
0x00//NULL
};
//L/////////////////////////////////////////
BYTE LEDBUF[16]=0;//L 与SMS1612E的接受数据缓存空间LCDBUF公用
float zhongliang=0;//L 重量KG
float midu=0; //L 密度 金额
float tiji=0; //L 体积 单价
/*
sfr p0=0x80;
sfr p1=0x90;
sfr p2=0xa0;
sfr p3=0xb0;
sbit FMQ=p1^7;
sbit NO15=p2^4;
sbit NO30=P2^5;
sbit NO45=P2^6;
sbit JDQ=p1^2;
*/
// unsigned char LCnumber;
//L////////////声明///////////////////////////
//0=t 1=f 2=x
void lcdint(void);//接受数据初始化
int fanyi(BYTE in);//字符翻译
void uarttxd(uchar n);//字符串LEDBUF的翻译
void Delay_10ms(void);//延时10ms
BYTE CardReady() ;//判断是否有卡//寻卡012
BYTE CloseCard();//关闭卡片01
BYTE SetPassword();//密码验证(只用A密码)01
BYTE ReadCard(BYTE BlockNo) ;//读指定块号处得到16位01
BYTE WriteCard(BYTE BlockNo) ;//在指定地方写卡01
void delay(unsigned int count);//延时足够长时间
BYTE XORCheck(BYTE *psData,BYTE length);//异或
unsigned char write_card(unsigned char cardNO);//写卡号012
void SYSCLK_Init (void);
void UART0_Init (void);
void Timer1_Init (void);
///////////////////////////*mark*////////////////////////////
void t1(void) interrupt 3 using 1{}
//L///////////////////////接受数据初始化////////////////////////
void lcdint(void)
{
LEDST=0;//LOAD
LEDCP=1;//CLK
LEDDS=0;//DI
}
//L///////////////////////字符翻译////////////////////////
int fanyi(BYTE in)
{
uchar i;
for(i=0;i<=10;i++)
{
if(leddata[i]==in)
{
if(i==10) return 0;
return i;
}
}
}
//L///////////////////////字符串LEDBUF的翻译/////////////////
void fanyibuf(void)
{
BYTE newdate;
float date,sdate;
uchar i,//16个字节
j,//8个位
k;
//L///////////////////开始翻译////////////////////////
//翻译16位数据
//15~10重量 数组0~5 最后有小数
//9~4体积 6~11 无
//3~0密度 12~15 无
//L//**************运算重量***************************//
j=k=1;//关于小数点的判断位,运算该位为整数
newdate=0.1;//运算小数系数
date=sdate=0;//清空
for(i=0;i<=5;i++)
{
if(!(LEDBUF[i]&0x80))j=0;//判断出小数点
LEDBUF[i]&=0x7f;//成为纯数字
if(k)
{//整数运算
date=date*10+fanyi(LEDBUF[i]);
if(!j)k=0;//结束整数运算
}
else
{//小数运算
sdate=sdate+fanyi(LEDBUF[i])*newdate;
newdate*=0.1;//系数变小
}
}
zhongliang=date+sdate;
//L//*****************运算体积*********************//
j=k=1;//关于小数点的判断位,运算该位为整数
newdate=0.1;//运算小数系数
date=sdate=0;//清空
for(;i<=11;i++)
{
if(!(LEDBUF[i]&0x80))j=0;//判断出小数点
LEDBUF[i]&=0x7f;//成为纯数字
if(k)
{//整数运算
date=date*10+fanyi(LEDBUF[i]);
if(!j)k=0;//结束整数运算
}
else
{//小数运算
sdate=sdate+fanyi(LEDBUF[i])*newdate;
newdate*=0.1;//系数变小
}
}
tiji=date+sdate;
//L//*****************运算密度*********************//
j=k=1;//关于小数点的判断位,运算该位为整数
newdate=0.1;//运算小数系数
date=sdate=0;//清空
for(;i<=15;i++)
{
if(!(LEDBUF[i]&0x80))j=0;//判断出小数点
LEDBUF[i]&=0x7f;//成为纯数字
if(k)
{//整数运算
date=date*10+fanyi(LEDBUF[i]);
if(!j)k=0;//结束整数运算
}
else
{//小数运算
sdate=sdate+fanyi(LEDBUF[i])*newdate;
newdate*=0.1;//系数变小
}
}
midu=date+sdate;
}
//L///////////////////////接收信息////////////////////////
void led_interruupt(void) interrupt 0//int0
{
BYTE newdate;
uchar i,//16个字节
j;//8个位
static uchar num=10;//10次接收一个
if(--num)return;
//接收16位数据
for(i=0;i<16;i++)
{
newdate=0x00;//清缓冲区 接收一字节
for(j=0;j<8;j++)
{
while(LEDCP);//出现负跳变表示接受一位
newdate>>=1;//从低向高发送位
if(LEDDS)
newdate+=0x80;
while(!LEDCP);//结束低电平出现正跳变
}
LEDBUF[15-i]=newdate;
}
fanyibuf();//翻译为数字
num=10
}
//L///////////////////////写读卡////////////////////////
void card_interruupt(void) interrupt 2//int1
{
uchar i;
for(i=0;i<16;i++)
if(card_ad[i]!=0x00)return;
switch(CardReady())//寻卡
{
case 0://成功
{
Delay_10ms(); Delay_10ms();
for(i=0;i<10;i++)//读卡可失败10次
if(!ReadCard(0x09))break;//成功读到CardData中
if(i>=10)return;//读失败返回
if(CardData[0]==0||CardData[1]==0)//新卡
{
CardData[0]=CardData[1]=0x03;//初始化卡位置数据
}
else//老卡
{
if(CardData[1]>=14)//首位置
{
if(CardData[0]<=3)//末位置
{
CardData[0]++;//老数据删除
}
CardData[1]=0x03;//加入新数据
}
else
{
CardData[1]++;//加数据
if(CardData[1]==CardData[0])
CardData[0]++;//末加
if(CardData[0]>=14)CardData[0]=0x03;
}
}
//写位置数据
WriteCard(0x09);
//写时间
for(i=0;i<16;i++)
CardData[i]=0x00;
WriteCard(CardData[1]*4);
//写油站号
WriteCard(CardData[1]*4+1);
//写数据
for(i=0;i<16;i++)
CardData[i]=card_ad[i];
WriteCard(CardData[1]*4+2);
break;
};
case 1://寻卡失败
default ://找不到
return;
}
}
///////////////////中断服务接受///////////////////////////
void uartrxd(void) interrupt 4 using 3
{ uint t;
if (REN0)// 允许接受
{
t=0;
while ((RI0==0)&&(t<60000)) t++;
RI0=0;
rxdbuff[rxdi++]=SBUF0;
}
}
/////////////////发送数据/////////////////////////////
void uarttxd(uchar n)//发送N字节
{uchar i;
// uint t;
REN0=0;//不许接收
for (i=0;i<=n;i++)
{
// _nop_();_nop_();_nop_();
SBUF0=rxdbuff[i];
// _nop_();_nop_();_nop_();
// t=0;
// while (!TI&&t<60000) {t++;};
while (TI0==0);//发送结束
TI0=0;
}
REN0=1;//允许接受
}
/////////////////延时10ms/////////////////////////////
void Delay_10ms(void)
{
BYTE i;
for(i = 0; i < 1000; i++)//0.01ms 1e-5s
{
// _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
// _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
// _nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
};
}
/////////////////判断是否有卡/////////////////////////////
BYTE CardReady() //耗时167.6ms
{
uint n=0;//i,n=0;
// BYTE i;
//下传命令:3C 04 01 70 00(寻卡模式00(IDLE)或01(ALL)) 00 BCC 0D
//成功返回:3C 05 四字节卡号 00 BCC 0D
//错误返回:3C 01 FF(错误返回代码) BCC 0D
// for (i=0;i<20;i++) Delay_10ms();
Delay_10ms(); Delay_10ms();
rxdbuff[0]=0x3c;
rxdbuff[1]=0x04;
rxdbuff[2]=0x01;
rxdbuff[3]=0x70;
rxdbuff[4]=0x01;//0x01;
rxdbuff[5]=0x00;
rxdbuff[6]=XORCheck(rxdbuff,6);
rxdbuff[7]=0x0d;
uarttxd(7);
rxdi=0;//清空
// rxdbuff[1]=0x01;
Delay_10ms();
n=0;
while (n<30)
{
if (rxdbuff[4]==0x0d) break;//失败
if (rxdi>=9) break;//接受结束
Delay_10ms();
n++;
}
if (rxdi==0) return 2;//没有收到
rxdi=0;//接受完成
CardNO1[0]=rxdbuff[2];
CardNO1[1]=rxdbuff[3];
CardNO1[2]=rxdbuff[4];
CardNO1[3]=rxdbuff[5];
if (rxdbuff[1]==0x05)//判断成功与否
return 0;//成功
else
return 1;//失败
}
/////////////////////关闭卡片//////////////////
BYTE CloseCard() //耗时77.4ms
{
uint n=0;
//关闭卡片:3C 04 01 68 00 00 51 0D
//正确返回:3C 02 00 00 3E 0D
//错误返回:3C 01 FF (错误返回代码)BCC 0D
Delay_10ms(); Delay_10ms();
rxdbuff[0]=0x3c;
rxdbuff[1]=0x04;
rxdbuff[2]=0x01;
rxdbuff[3]=0x68;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -