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

📄 fm1702.c

📁 FM1702SL.rar
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
* 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 + -