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

📄 reader.c

📁 基于at89s52的读mifare1卡c51源程序.单片机与rfid读卡模块yhy502相连。单片机与上位机通过串口进行通信
💻 C
字号:
#include<reg52.h>
#include<intrins.h>
sfr16   RCAP2LH                = 0xCA;
sfr16   T2LH                   = 0xCC;
#define TRUE   1
#define FALSE  0
#define SUCCESS 1
#define FAILURE 0


// 定义IIC端口
sbit     SDA        =    P1^6;
sbit     SCL        =    P1^7;

unsigned char idata SelectedSnr[4];//卡序列号 

//-----------------------------------------------------------------------------------------SendBuffer
unsigned char  data cp[30];      // HY502 buffer  
unsigned char  idata g_cReceBuf[30];	//uart Receive buffer

unsigned char g_cReceNum;		//bytes of received, used in interrupt
bit           g_bReceCommandOk;	//flag of command receive OK
bit           g_bReceAA;		//flag of last received byte is "0xaa", used in interrupt
bit           g_bCard;			//flag of card in


//设置波特率
#define OSC_FREQ                11059200L

#define BAUD_115200             256 - (OSC_FREQ/192L)/115200L   // 255
#define BAUD_57600              256 - (OSC_FREQ/192L)/57600L    // 254
#define BAUD_38400              256 - (OSC_FREQ/192L)/38400L    // 253
#define BAUD_28800              256 - (OSC_FREQ/192L)/28800L    // 252
#define BAUD_19200              256 - (OSC_FREQ/192L)/19200L    // 250
#define BAUD_14400              256 - (OSC_FREQ/192L)/14400L    // 248
#define BAUD_9600               256 - (OSC_FREQ/192L)/9600L     // 244
// Timer2
#define RCAP2_50us             65536L - OSC_FREQ/240417L
#define RCAP2_1ms              65536L - OSC_FREQ/12021L
#define RCAP2_10ms             65536L - OSC_FREQ/1200L
#define RCAP2_1s               65536L - OSC_FREQ/12L



#define   CMD_OK	   0
#define   CMD_ERR      1 

// Define the commands
#define   PCD_PN       0x01		  // 设备型号
#define   PCD_SN       0x02		  // 设备序列号
#define   PWR_DOWN     0x03		  //设备掉电,需重新加电复位!,不带DOG时有效
#define   BAUD_SET     0x04		  //波特率设置
#define   FW_REL       0x10		  //PCD固件版本号
#define   SOFTDOWN     0x11		  //HY502模块软掉电
#define   HALT_CARD    0x12		  //中止卡操作
#define   AUTOSEARCH   0x13		  //自动寻卡
#define   BEEP         0x14		  //蜂鸣器开关
#define   BEEP_TIME    0x15		  //鸣响时间
#define   CARD_TYPE    0x19		  //读取卡类型
#define   CARD_SN      0x20		  //读卡序列号
#define   READ_BLOCK   0x21		  //读块数据
#define   WRITE_BLOCK  0x22		  //写块数据
#define   INIT_PURSE   0x23		  //初始化钱包
#define   READ_PURSE   0x24		  //读钱包
#define   ADD_PURSE    0x25		  //钱包充值
#define   DEC_PURSE    0x26		  //钱包扣款
#define   READ_SECTOR  0x2a       // 读扇区
#define   WRITE_SECTOR 0x2b       // 写扇区
#define   READ_E2      0x30       // 读E2
#define   WRITE_E2     0x31       // 写E2          


// Define the error commands return from HY502 chip

#define   ERR_HALT         0xed		  //中止卡操作错误
#define   ERR_AUTO         0xec		  //自动寻卡错误
#define   ERR_TYPE         0xe6		  //读取卡类型错误
#define   ERR_SN           0xdf		  //读卡序列号错误
#define   ERR_READ_BLOCK   0xde		  //读块数据错误
#define   ERR_WRITE_BLOCK  0xdd		  //写块数据错误
#define   ERR_INIT_PURSE   0xdc		  //初始化钱包错误
#define   ERR_READ_PURSE   0xdb		  //读钱包错误
#define   ERR_ADD_PURSE    0xda		  //钱包充值错误
#define   ERR_DEC_PURSE    0xd9		  //钱包扣款错误
///////////////////////////////////////////////////////////////////

char code reserve[3]_at_ 0x3b; //保留0x3b开始的3个字节


void InitializeSystem()
{
  
	unsigned char i=0;
	for(i=0;i<30;i++)
		cp[i]='\0';

  SCON = 0x50; //设定串口工作方式1,接收使能
  PCON = 0x00; //波特率不倍增

  TMOD = 0x20; //定时器1工作于8位自动重载模式, 用于产生波特率
  EA = 1;
  TL1 = 0xfd;
  TH1 = 0xfd; //波特率9600
  TR1 = 1;
	g_bReceCommandOk=0;	   		 					
}

/////////////////////////////////////////////////////////////////////////////////////////////////////
// 延时函数
void delay(unsigned int x)
{
	while(x)
	{
		x--;
	}
}

///////////////////////////////////////////////////////////////////////
// Delay 50us
///////////////////////////////////////////////////////////////////////
void delay_50us(unsigned char _50us)
{
  RCAP2LH = RCAP2_50us;
  T2LH    = RCAP2_50us;
  ET2 = 0;    	// Disable timer2 interrupt
  T2CON = 0x04;	// 16-bit auto-reload, clear TF2, start timer

  while (_50us--)
  {
	while (!TF2);
	TF2 = FALSE;
  }

  TR2 = FALSE;
}

void delay_1ms (unsigned int _1ms)
{

  RCAP2LH = RCAP2_1ms;
  T2LH    = RCAP2_1ms;
  ET2 = 0;   	// Disable timer2 interrupt
  T2CON = 0x04;	// 16-bit auto-reload, clear TF2, start timer

  while (_1ms--)
  {
	while (!TF2);
	TF2 = FALSE;
  }
  TR2 = FALSE;

}


//---------------------IIC function define ---------------------------------------------
#define	READ_HY502		0xA1           //module address (综合型的是默认内部地址,通过模块上的地址设置而不是引脚上的)
#define	WRITE_HY502	    0xA0           //这点区别于独立的iic模式,独立的模式是指的引脚上的地址!
/*****************************************************************************
*function: IIC start condition
*****************************************************************************/
void I2CStart(void)
{
	SDA = 1;
	SCL = 1;
	SDA = 0;
	_nop_();
	SCL = 0;
}
/*****************************************************************************
*function: IIC stop condition
*****************************************************************************/
void I2CStop(void)
{
	SCL = 0;
	SDA = 0;
	_nop_();
	SCL = 1;
	SDA = 1;
}
/*****************************************************************************
*function: IIC wait ACK
*****************************************************************************/
bit I2CWaitAck(void)
{
	unsigned char cErrTime = 255;
	SDA = 1;
	_nop_();
	SCL = 1;
	while(SDA)
	{
		cErrTime--;
		delay(10);
		if (0 == cErrTime)
		{
			I2CStop();
			return FAILURE;
		}
	}
	SCL = 0;
	return SUCCESS;
}
/*****************************************************************************
*function: IIC send ACK
*****************************************************************************/
void I2CSendAck(void)
{
	SDA = 0;
	_nop_();
	SCL = 1;
	SCL = 0;
}
/*****************************************************************************
*function: IIC send Not ACK
*****************************************************************************/
void I2CSendNotAck(void)
{
	SDA = 1;
	_nop_();
	SCL = 1;
	SCL = 0;
}
/*****************************************************************************
*function: send a byte over IIC bus
*****************************************************************************/
void I2CSendByte(unsigned char cSendByte)
{
	unsigned char data i = 8;
	while (i--)
	{
		SCL = 0;
		SDA = (bit)(cSendByte & 0x80);
		cSendByte += cSendByte;
		_nop_();
		SCL = 1;
	}
	SCL = 0;
}
/*****************************************************************************
*function: receive a byte over IIC bus
*****************************************************************************/
unsigned char I2CReceiveByte(void)
{
	unsigned char data i = 8;
	unsigned char data cR_Byte = 0;
	SDA = 1;
	while (i--)
	{
		cR_Byte += cR_Byte;
		SCL = 0;
		_nop_();  
		_nop_();
		SCL = 1;
		cR_Byte |= (unsigned char)SDA;
	}
	SCL = 0;
	return cR_Byte;
}
/*****************************************************************************
*function: read data from HY502 over IIC bus
*****************************************************************************/
unsigned char IicReadHY502(unsigned char *cP)
{
	unsigned char cCnt;
	unsigned char cCheckSum = 0;
	for (cCnt=0; cCnt<0xFF; cCnt++)	// wait HY502 working, while it's working, it will send "not ACK" to IIC master
	{
		delay(1);
		I2CStart();
		I2CSendByte(READ_HY502);
		if (I2CWaitAck() == SUCCESS)
		{
			break;
		}
	}
	if (0xFF == cCnt)
	{
		return FAILURE;
	}
	cP[0]=2;
	for (cCnt=0; cCnt<cP[0]; cCnt++)	// in the protocol, cP[0] is the length of this data package
	{
		cP[cCnt] = I2CReceiveByte();
		I2CSendAck();
		cCheckSum ^= cP[cCnt];
	}
	cP[cCnt] = I2CReceiveByte();
	I2CSendNotAck();
	I2CStop();
	if (cCheckSum != cP[cCnt])
	{
		return FAILURE;
	}
	else
	{
		return SUCCESS;
	}
}
/*****************************************************************************
*function: send data to HY502 over IIC bus
*****************************************************************************/
unsigned char IicSendHY502(unsigned char *cP)
{
	unsigned char i;
	unsigned char cCheckSum = 0;
	I2CStart();
	I2CSendByte(WRITE_HY502);
	if (I2CWaitAck() == SUCCESS)
	{
		for(i=0; i<cP[0]; i++)	// in the protocol, cP[0] is the length of this data package
		{
			cCheckSum ^= cP[i];
			I2CSendByte(cP[i]);
			if (I2CWaitAck() != SUCCESS)
			{
				return FAILURE;
			}
		}
		I2CSendByte(cCheckSum);
		if (I2CWaitAck() != SUCCESS)
		{
			return FAILURE;
		}		 
		I2CStop();
        return SUCCESS;
        }
	else
	{
		return FAILURE;
	}
}

void send_str(unsigned char *str)
{
  unsigned char i = 0;

  while (str[i] != '\0')
  {
    SBUF = str[i++];
    while (!TI)
      ;
    //等待数据传送完毕
    TI = 0; //清中断标志
  }
}

void main(void)
{
	unsigned char idata cStatus;
	P2=0xff;	    
	InitializeSystem();		   // 初始化系统   


	IT0 = 0; //低电平触发
  	//   IT0=1;              //下降沿触发
  	//IT1 = 0; //低电平触发
  	//   IT1=1;              //下降沿触发

  	EA = 1; //总中断允许
  	//EX1 = 1; //开启INT1中断
  	EX0 = 1; //开启INT0中断
	cp[0]='f';
	cp[1]='u';
	cp[2]='c';
	cp[3]='k';
	cp[4]=' ';
	cp[5]='y';
	cp[6]='o';
	cp[7]='u';
	send_str(cp);
	g_cReceBuf[0]=0x2;
	g_cReceBuf[1]=0x20;
	cStatus =IicSendHY502(g_cReceBuf);//ComSearchCard);	  // 发送寻卡命令  
	if(cStatus==0)
		P2=0x00;		         
	cStatus =IicReadHY502(cp);		  // 读取卡号并存入到cP
	send_str(cp);
	while(1);
}

void INT0_Proc(void) interrupt 0
{
	EX0=0;
	P2=0x00;
	delay_1ms(2000);
	P2=0xff;
	EX0=1;

}

⌨️ 快捷键说明

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