📄 fm1702.c
字号:
/****************************************************************************
* File : main.c *
* COPYRIGHT BY HUOYAN LTD.COMPANY *
* Version: V1.3 *
* *
* Created: 18.10.2005 *
* Last Change: 21.10.2005 *
* *
* Author: NIL *
* *
* Compiler: KEIL C51 V7.10 *
* *
* Description: AT89S52-Firmware for FM1702 Demo Serial Reader *
* *
****************************************************************************/
#define __SRC
#include "main.h"
#undef __SRC
#include <string.h>
#include <stdio.h>
#include <absacc.h>
#include <intrins.h>
#include "sm5964.h"
#include "FM1702.h"
#define uchar unsigned char
#define uint unsigned int
//pin define mcu控制管脚定义
sbit RF_NSS = P1^4;
sbit RF_MISO = P1^3;
sbit RF_MOSI = P1^2;
sbit RF_SCK = P1^1;
sbit RF_RST = P3^5; //由高变低时启动内部复位程序
sbit CARD_LED = P3^3;
sbit SPEAKER = P3^4;
sbit LCD_CS = P2^4;
sbit LCD_RD = P2^5;
sbit LCD_WR = P2^6;
sbit LCD_DATA = P2^7;
//sfr P4 = 0xD8;
sbit key = P4^3;
// Release Number of the Firmware
//uchar code HY_Rel[] = "\n\r HUO YAN V1.3 21.Oct.05 \n\r";
// Module address
// uchar code addr[]="0xff";
///////////////////////////////////////////////////////////////////////
// 主函数
///////////////////////////////////////////////////////////////////////
void main(void)
{ //设置变量
uchar baud;
if(!P2_0) //P2.0=0则进入ISP服务程序
{
SPEAKER = 0;
GoToIsp();
}
InitSystem(); //初始化系统
while (1)
{
//检查命令标志
if (CmdValid) //if LEVEL 1
{
CmdValid = FALSE;
if(RevBuffer[0]==11) //if LEVEL 2
{
RevBuffer[2]=RevBuffer[1];
RevBuffer[0]=1;
RevBuffer[1]=0;
CALL_isr_UART(); //equal to 'SETB TI', defined in main.h
SPEAKER=0; //开蜂鸣器和指示灯
CARD_LED=ON;
delay_10ms(RevBuffer[2]);
SPEAKER=1;
CARD_LED=OFF;
}
else if(RevBuffer[0]==13) //设置通讯波特率 //if LEVEL 2
{
switch(RevBuffer[1])
{
case 0:
baud=BAUD_9600;
break;
case 1:
baud=BAUD_14400;
break;
case 2:
baud=BAUD_19200;
break;
case 3:
baud=BAUD_28800;
break;
case 4:
baud=BAUD_38400;
break;
case 5:
baud=BAUD_57600;
break;
case 6:
baud=BAUD_115200;
break;
default:
baud=BAUD_19200;
break;
} //switch body
RevBuffer[0]=1; //contact
RevBuffer[1]=0;
CALL_isr_UART();
delay_10ms(5);
TR1 = 0;
TH1 = baud;
TL1 = TH1;
delay_10ms(2);
TR1 = TRUE;
}//if LEVEL 2
else
{
cmd_process(); // 进入IC卡处理程序
CALL_isr_UART();
}
}
}//while循环体
}//main函数
///////////////////////////////////////////////////////////////////////
// 系统初始化
///////////////////////////////////////////////////////////////////////
void InitSystem(void)
{
RF_NSS=1;
RF_RST=0;
SCONF=0x03; //SM5964A system control register: enable on chip 1K RAM and disable ALE output
ET2 = 0; //Timer 2 disabled
T2CON = 0x04; //start Timer 2(internal timer, auto reload)
PCON = 0x00; //baud rate double
SCON = 0x70; //UART mode 1, enable receive, if No valid stop bit, RI not activated.
//TMOD = 0x22;
TMOD = 0x21; //Timer 1 8bit auto reload TR1 control
//Timer 0 16bit TR0 control
TH1 = BAUD_19200; //默认波特率
TL1 = TH1;
TR1 = TRUE; // 波特率发生器
TH0 = 0x60;
TL0 = 0x60;
TR0 = 0; //Timer 0 doesn't run
ET0=0;
ET1=0;
EA=1;
EX0=1;
IT0 = 1;
TR2=0;
ES = TRUE; //enable UART interrupt
CmdValid=0; //flag initiation
//喇叭和指示灯测试
// SPEAKER=0;
// CARD_LED=OFF;
// delay_10ms(30);
SPEAKER=0;
CARD_LED=ON;
delay_10ms(10);
SPEAKER=1;
CARD_LED=OFF;
Init_FM1702(0);
}
///////////////////////////////////////////////////////////////////////
// 串口接收和发送中断
///////////////////////////////////////////////////////////////////////
void isr_UART(void) interrupt 4 using 1
{
uchar len, i;
unsigned int j=0;
if(RI)
{
len=SBUF;
RI=0;
for(i=0;i<len;i++)
{
while(!RI)
{
j++;
if(j>1000)
{
break;
}
}
if(j<1000)
{
RevBuffer[i]=SBUF;
RI=0;
j=0;
}
else
{
break;
}
}
if(i==len)
{
REN=0;
CmdValid=1;
}
}
else if(!RI && TI)
{
TI=0;
len=RevBuffer[0];
for(i=0;i<len+1;i++)
{
SBUF=RevBuffer[i];
while(!TI);
TI=0;
}
REN=1;
}
}
///////////////////////////////////////////////////////////////////////
// IC卡处理函数
///////////////////////////////////////////////////////////////////////
void cmd_process(void)
{
uchar cmd;
uchar status;
cmd = RevBuffer[0];
switch(cmd)
{
case 1: // Halt the card //终止卡的操作
status=MIF_Halt();
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
case 2:
//MIF_Halt(); //RF_CMD_REQUEST_ALL=0x52,request all
status = Request(RF_CMD_REQUEST_ALL); //RF_CMD_REQUEST_STD=0x26, request Idle
if(status != FM1702_OK)
{
status = Request(RF_CMD_REQUEST_ALL);
if(status != FM1702_OK)
{
RevBuffer[0] = 1;
RevBuffer[1] = FM1702_REQERR;
break;
}
}
if(tagtype[0]==2)
cardtype=mifarepro; // Mifare Pro 卡
else if(tagtype[0]==4)
cardtype=mifare1; // Mifare One 卡
else if(tagtype[0]==16)
cardtype=mifarelight; // Mifare Light 卡
else
cardtype=unknowncard;
RevBuffer[0]=3;
RevBuffer[1]=status;
RevBuffer[2]=tagtype[0];
RevBuffer[3]=tagtype[1];
break;
case 3: // 防冲突 读卡的系列号 MLastSelectedSnr
status = AntiColl();;
if(status!=FM1702_OK)
{
RevBuffer[0]=1;
RevBuffer[1]=FM1702_ANTICOLLERR;
break;
}
//memcpy(MLastSelectedSnr,&RevBuffer[2],4);
RevBuffer[0]=5;
RevBuffer[1]=status;
RevBuffer[2]=UID[0];
RevBuffer[3]=UID[1];
RevBuffer[4]=UID[2];
RevBuffer[5]=UID[3];
break;
case 4: // 选择卡 Select Card
status=Select_Card();
if(status!=FM1702_OK)
{
RevBuffer[0]=1;
RevBuffer[1]=FM1702_SELERR;
break;
}
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
case 6: //下载密钥
status = Load_keyE2_CPY(RevBuffer[2],RevBuffer[1]); //%40
status = Authentication(UID, RevBuffer[2], RevBuffer[1]);
if(status != FM1702_OK)
{
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
}
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
case 8: //读卡
status=MIF_READ(&RevBuffer[2],RevBuffer[1]);
if(status != FM1702_OK)
{
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
}
else
{
if(cardtype==mifare1||cardtype==mifarepro)
RevBuffer[0]=17;
else if(cardtype==1)
RevBuffer[0]=9;
else
RevBuffer[0]=16;
}
RevBuffer[1]=status;
break;
case 9: //写卡
status=MIF_Write(&RevBuffer[2],RevBuffer[1]);
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
case 10: //加值减值
if(RevBuffer[1] == RF_CMD_INC)
{
status = MIF_Increment(&RevBuffer[3],RevBuffer[2]);
MIF_Transfer(RevBuffer[2]);
}
else if(RevBuffer[1] == RF_CMD_DEC)
{
status = MIF_Decrement(&RevBuffer[3],RevBuffer[2]);
MIF_Transfer(RevBuffer[2]);
}
else
{
status = 1;
}
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
case 12:
RevBuffer[0]=1;
RevBuffer[1]=0;
break;
default:
RevBuffer[0] = 1;
RevBuffer[1] = 1;
break;
}
}
void delay1(unsigned char dlength)
{
unsigned char i;
for (i=0;i<dlength;i++)
{
_nop_();
}
}
/****************************************************************/
/*名称: Clear_FIFO */
/*功能: 该函数实现清空FM1702中FIFO的数据*/
/*输入: N/A */
/*输出: TRUE, FIFO被清空*/
/* FALSE, FIFO未被清空*/
/****************************************************************/
uchar Clear_FIFO(void)
{
uchar temp;
uint i;
temp = SPIRead(Control); /* 清空FIFO */
temp = (temp | 0x01);
SPIWrite(Control,temp);
for(i = 0; i < RF_TimeOut; i++) /* 检查FIFO是否被清空 */
{
temp = SPIRead(FIFO_Length);
if(temp == 0)
{
return TRUE;
}
}
return FALSE;
}
/****************************************************************/
/*名称: Write_FIFO */
/*功能: 该函数实现向FM1702的FIFO中写入x bytes数据*/
/*输入: count, 待写入字节的长度*/
/* buff, 指向待写入数据的指针*/
/*输出: N/A */
/****************************************************************/
void Write_FIFO(uchar count, uchar idata *buff)
{
uchar i;
for(i = 0; i < count; i++)
{
SPIWrite(FIFO,*(buff + i));
}
}
/****************************************************************/
/*名称: Read_FIFO */
/*功能: 该函数实现从FM1702的FIFO中读出x bytes数据*/
/*输入: buff, 指向读出数据的指针*/
/*输出: N/A */
/****************************************************************/
uchar Read_FIFO(uchar idata *buff)
{
uchar temp;
uchar i;
temp = SPIRead(FIFO_Length);
if(temp == 0)
{
return 0;
}
if(temp >= 24)
{
temp = 24;
}
for(i = 0; i < temp; i++)
{
*(buff + i) = SPIRead(FIFO);
}
return temp;
}
/****************************************************************/
/*名称: Judge_Req */
/*功能: 该函数实现对卡片复位应答信号的判断*/
/*输入: *buff, 指向应答数据的指针*/
/*输出: TRUE, 卡片应答信号正确*/
/* FALSE, 卡片应答信号错误*/
/****************************************************************/
uchar Judge_Req(uchar idata *buff)
{
uchar temp1, temp2;
temp1 = *buff;
temp2 = *(buff + 1);
if((temp1 == 0x02) || (temp1 == 0x04) || (temp1 == 0x05) || (temp1 == 0x53) || (temp1 == 0x03))
{
if (temp2 == 0x00)
{
return TRUE;
}
}
return FALSE;
}
/****************************************************************/
/*名称: Check_UID */
/*功能: 该函数实现对收到的卡片的序列号的判断*/
/*输入: N/A */
/*输出: TRUE: 序列号正确*/
/* FALSE: 序列号错误*/
/****************************************************************/
uchar Check_UID(void)
{
uchar temp;
uchar i;
temp = 0x00;
for(i = 0; i < 5; i++)
{
temp = temp ^ UID[i];
}
if(temp == 0)
{
return TRUE;
}
return FALSE;
}
/****************************************************************/
/*名称: Save_UID */
/*功能: 该函数实现保存卡片收到的序列号*/
/*输入: row: 产生冲突的行*/
/* col: 产生冲突的列*/
/* length: 接収到的UID数据长度*/
/*输出: N/A */
/****************************************************************/
void Save_UID(uchar row, uchar col, uchar length)
{
uchar i;
uchar temp;
uchar temp1;
if((row == 0x00) && (col == 0x00))
{
for(i = 0; i < length; i++)
{
UID[i] = RevBuffer[i];
}
}
else
{
temp = RevBuffer[0];
temp1 = UID[row - 1];
switch(col)
{
case 0: temp1 = 0x00; row = row + 1; break;
case 1: temp = temp & 0xFE; temp1 = temp1 & 0x01; break;
case 2: temp = temp & 0xFC; temp1 = temp1 & 0x03; break;
case 3: temp = temp & 0xF8; temp1 = temp1 & 0x07; break;
case 4: temp = temp & 0xF0; temp1 = temp1 & 0x0F; break;
case 5: temp = temp & 0xE0; temp1 = temp1 & 0x1F; break;
case 6: temp = temp & 0xC0; temp1 = temp1 & 0x3F; break;
case 7: temp = temp & 0x80; temp1 = temp1 & 0x7F; break;
default: break;
}
RevBuffer[0] = temp;
UID[row - 1] = temp1 | temp;
for(i = 1; i < length; i++)
{
UID[row - 1 + i] = RevBuffer[i];
}
}
}
/****************************************************************/
/*名称: Set_BitFraming */
/*功能: 该函数设置待发送数据的字节数*/
/*输入: row: 产生冲突的行*/
/* col: 产生冲突的列*/
/*输出: N/A */
/****************************************************************/
void Set_BitFraming(uchar row, uchar col)
{
switch(row)
{
case 0: RevBuffer[1] = 0x20; break;
case 1: RevBuffer[1] = 0x30; break;
case 2: RevBuffer[1] = 0x40; break;
case 3: RevBuffer[1] = 0x50; break;
case 4: RevBuffer[1] = 0x60; break;
default: break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -