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

📄 main.c

📁 射频卡读写程序和读写器原理图,常用的射频卡读写器源程序,源程序和原理图均是最终应用的程序,该读卡器已经批量生产,性能稳定.
💻 C
📖 第 1 页 / 共 5 页
字号:
		tr_buf[1]=0xff;
		tr_buf[2]=0x04;
		tr_buf[3]=0xaa;
		tr_buf[4]=0;
		//把读出的数据转换为正常格式
		ls1=card_wrrd_buf[0];
		ls2=card_wrrd_buf[1];
		ls1<<=4;
		ls1&=0xf0;
		ls2&=0x0f;
		ls1|=ls2;
		tr_buf[7]=ls1;
		ls1=card_wrrd_buf[2];
		ls2=card_wrrd_buf[3];
		ls1<<=4;
		ls1&=0xf0;
		ls2&=0x0f;
		ls1|=ls2;
		tr_buf[6]=ls1;
		ls1=card_wrrd_buf[4];
		ls2=card_wrrd_buf[5];
		ls1<<=4;
		ls1&=0xf0;
		ls2&=0x0f;
		ls1|=ls2;
		tr_buf[5]=ls1;
		ls1=tr_buf[2];
		for (i=3;i<8;i++) ls1+=tr_buf[i];
		tr_buf[8]=ls1;
		nd_uart_tr_nu=9;
		goto rf_ins_proc_p2;
	}
	else if (ls1==0x44)	//写入卡指定区域
	{
		sector_rh=re_buf[2];
		sector_rl=re_buf[3];
		card_block=re_buf[4];
		card_key_mode=re_buf[21];
rf_ins_proc_p44:
		ack_to_main_par=authentication_p(sector_rl,card_key_mode);	//认证
		if (ack_to_main_par!=0) 
		{
			card_opr_er_ct++;
			if (card_opr_er_ct>=3) goto rf_ins_proc_p1;
			else goto rf_ins_proc_p44;
		}
		
		delay_ms(15);
rf_ins_proc_p45:
		ack_to_main_par=write_card(sector_rl*4+card_block);				//写入
		if (ack_to_main_par!=0) 
		{
			card_opr_er_ct++;
			if (card_opr_er_ct>=3) goto rf_ins_proc_p1;
			else goto rf_ins_proc_p45;
		}
		goto rf_ins_proc_p1;
	}
	else if (ls1==0x66)	//读出卡指定区域
	{
		sector_rh=re_buf[2];
		sector_rl=re_buf[3];
		card_block=re_buf[4];
		card_key_mode=re_buf[5];
rf_ins_proc_p64:
		ack_to_main_par=authentication_p(sector_rl,card_key_mode);	//认证
		if (ack_to_main_par!=0) 
		{
			card_opr_er_ct++;
			if (card_opr_er_ct>=3) goto rf_ins_proc_p1;
			else goto rf_ins_proc_p64;
		}
		delay_ms(15);
rf_ins_proc_p65:	
		ack_to_main_par=read_card(sector_rl*4+card_block);				//读出
		if (ack_to_main_par!=0) 
		{
			card_opr_er_ct++;
			if (card_opr_er_ct>=5) goto rf_ins_proc_p1;
			else goto rf_ins_proc_p65;
		}
		tr_buf[0]=0xff;
		tr_buf[1]=0xff;
		tr_buf[2]=17;
		tr_buf[3]=0x66;
		tr_buf[4]=0;
		for (i=0;i<16;i++)	tr_buf[i+5]=card_wrrd_buf[i];
		ls1=tr_buf[2];
		for (i=3;i<21;i++)	ls1+=tr_buf[i];
		tr_buf[21]=ls1;
		nd_uart_tr_nu=22;
		goto rf_ins_proc_p2;
	}
	else if (ls1==0x88)	//空操作
	{
		tr_buf[0]=0xff;
		tr_buf[1]=0xff;
		tr_buf[2]=0x02;
		tr_buf[3]=0x88;
		tr_buf[4]=0;
		tr_buf[5]=0;
		tr_buf[6]=0x8a;		//sum
		nd_uart_tr_nu=7;
		goto rf_ins_proc_p2;
	}
	else if ((ls1&0xf0)==0x90)	//向读卡器写入密钥置换盒
	{
		for (i=0;i<8;i++)
		{
			static_key_1[i]=re_buf[2+i];
		}
		tr_buf[0]=0xff;
		tr_buf[1]=0xff;
		tr_buf[2]=0x01;
		tr_buf[3]=0x99;
		tr_buf[4]=0x9a;		//sum
		nd_uart_tr_nu=5;
		goto rf_ins_proc_p2;
		
	}
	else if (ls1==0xaa)	//应答回复
	{
		return;
	}
	else if (ls1==0xbb)	//已经处理完毕本张卡片
	{
		reque_delay_t=re_buf[2];	//延时时间
		rfcard_in_flg=0;		//清"查询到卡标志"
	}
	else if (ls1==0x77)
	{
		card_chk_p();
		if (!rfcard_in_flg) 
		{
			ack_to_main_par=0x10;
			goto rf_ins_proc_p1;
		}
		tr_buf[0]=0xff;
		tr_buf[1]=0xff;
		tr_buf[2]=0x08;
		tr_buf[3]=0x77;
		for (i=0;i<8;i++)
		{
			tr_buf[i+4]=rfcard_sn_buf[i];
		}
		ls1=tr_buf[2];
		for (i=3;i<12;i++)
		{
			ls1+=tr_buf[i];
		}
		tr_buf[12]=ls1;
		nd_uart_tr_nu=13;
		goto rf_ins_proc_p2;
	}
	else
	{
	}
rf_ins_proc_p1:
	tr_buf[0]=0xff;
	tr_buf[1]=0xff;
	tr_buf[2]=0x01;
	tr_buf[3]=0xaa;
	tr_buf[4]=ack_to_main_par;
	ls1=tr_buf[2]+tr_buf[3]+tr_buf[4];
	tr_buf[5]=ls1;
	nd_uart_tr_nu=6;
rf_ins_proc_p2:
	tr_uart_count=0;
	comming_spi_flg=1;
	spi_tr_strt_ct=0;
	spi_tr_strt_flg=0;
	comming_uart_flg=1;
	tran_uartenable();
	ins_spi_flg=0;
	ins_uart_flg=0;
}



//----------------------------------------------------------------------//
//UART通讯 发送数据处理程序
//----------------------------------------------------------------------//
void uart_tr_sub(void)
{
	if (comming_uart_flg)
	{
		if (SCS1_TC)
		{
			if (tr_uart_count<nd_uart_tr_nu)
			{
				SCDR=tr_uart_buf[tr_uart_count];
				tr_uart_count++;
			}
			else
			{
				comming_uart_flg=0;
				tran_uartdisable();
			}
		}
	}
}



//----------------------------------------------------------------------//
//SPI通讯收发数据处理程序
//起始位接收计数器spi_re_strt_ct
//检索是否有时钟信号低电平, 有则循环检测是否是开始位,不是则返回,是则继续接收,直到完成,并把指令放在指令缓冲区设置标志ins_spi_flg
//指令处理程序处理完指令后,组织发送数据,并设置发送标志,清spi_tr_strt_ct, 本程序查询到有发送标志comming_spi_flg,则开始发送.
//接收处理方法:检测到低电平开始计时,出现高电平停止计时,如果时间超过5毫秒,则是起始位,否则是正常数据位处理
//接收中,每8位为一个字节,第1字节是参数长度,这个数加上3就是接收总长度(包括它本身)
//收到第1字节放在计数单元,以后的接收数量以此为准,这个数同时放接收缓冲区
//以后每8位组成一个字节, 接收完成则设置标志,指令转移至指令寄存器待处理
//接收中,出现电平变化,必须连续两次位同一电平方认为电平发生变换.
//----------------------------------------------------------------------//
void spi_com_p(void)
{
	uchar i,j,k,ls1;

	if(!comming_spi_flg) goto spi_com_p1;
//发送处理
	if (!spi_tr_strt_flg)
	{//发送头
		com_trck_kx=0;
		if (spi_tr_strt_ct>=15)
		{
			spi_tr_strt_flg=1;
		}
		return;
	}
	for (j=0;j<nd_spi_tr_nu;j++)
	{
		spitrbuf=tr_spi_buf[j+2];		//SPI发送数据缓冲区与UART为同一个,SPI不发送前面的两个0XFF
		for (i=0;i<8;i++)
		{
			com_trck_kx=0;
			com_trdt_kx=spitrbuf_7;
			spitrbuf<<=1;
			for (k=0;k<50;k++) Nop();	//延时50微秒
			com_trck_kx=1;
			for (k=0;k<50;k++) Nop();	//延时50微秒
		}
	}
	com_trck_kx=1;
	comming_spi_flg=0;
	nd_spi_tr_nu=0;
//接收处理
spi_com_p1:
	spi_tr_strt_ct=0;
	spi_tr_strt_flg=0;
	EnableInterrupts;	//开中断

	if (!com_reck_kx)
	{
		if (spi_re_strt_ct>3)
		{//收到起始位
			re_spi_count=0;
			re_spi_bit_count=0;
			spi_re_strt_flg=1;
			DisableInterrupts;		//关断中断
			goto spi_com_p3;
		}
		else return;
	}
	else
	{
		spi_re_strt_ct=0;
	}
	return;
//开始接收数据
spi_com_p3:
	ls1=spi_re1byte_p();
//	if (!spi_re_strt_flg) return;	//因为接收故障的原因,会清除头标志
	if (re_spi_count==0)
	{//收到的第1个字节
		if (ls1>19)
		{//收到的数据个数超限,故障返回
			spi_re_strt_flg=0;
			EnableInterrupts;	//开中断
			return;
		}
		i=ls1+2;	//应接收数据个数
	}
	re_spi_buf[re_spi_count]=ls1;
	re_spi_count++;
	if (re_spi_count>=i)
	{//接收完成,设置有指令需要处理,直接返回,处理出现,直接处理接收缓冲区数据即可
		EnableInterrupts;	//开中断
		ins_spi_flg=1;
		spi_re_strt_flg=0;
		return;
	}
	else goto spi_com_p3;
}

//----------------------------------------------------------------------//
//SPI通讯,接收一个字节函数-----不带滤波处理
//----------------------------------------------------------------------//
uchar spi_re1byte_p(void)
{
	Nop();
spi_re1byte_p2:
	while (com_reck_kx)
	{
	}
	Nop();
	//收到低电平
	while (!com_reck_kx)
	{//等待高电平
	}
	Nop();
	//收到高电平
	spirebuf_0=com_redt_kx;
	re_spi_bit_count++;
	if (re_spi_bit_count>=8)
	{//收完一个字节
		re_spi_bit_count=0;
		return(spirebuf);
	}
	else 
	{
		spirebuf<<=1;
		goto spi_re1byte_p2;
	}
}

/*
//----------------------------------------------------------------------//
//SPI通讯,接收一个字节函数-----带滤波处理, 但速度慢, 只能接收每位超过500毫秒的数据
//----------------------------------------------------------------------//
uchar spi_re1byte_p(void)
{
	uchar re_ck_ct;	//接收时钟脉冲电平次数
	uchar re_dt_ct;	//接收数据脉冲电平次数
spi_re1byte_p2:
	re_ck_ct=0;
	while (re_ck_ct<2)
	{
		if (!com_reck_kx)
		{
			re_ck_ct++;
		}
		else
		{
			re_ck_ct=0;
		}
	}
	re_ck_ct=0;
	//收到可靠的低电平
	while (!com_reck_kx)
	{//等待高电平
	}
	while (re_ck_ct<2)
	{
		if (com_reck_kx)
		{
			re_ck_ct++;
		}
		else
		{
			re_ck_ct=0;
		}
	}
	//收到可靠的高电平
	re_dt_ct=0;
	spirebuf_0=com_redt_kx;
	while(re_dt_ct<2)
	{
		if (spirebuf_0!=com_redt_kx)
		{
			spirebuf_0=com_redt_kx;
			re_dt_ct=0;
		}
		else
		{
			re_dt_ct=2;
		}
	}
	//收到可靠的数据位
	re_spi_bit_count++;
	if (re_spi_bit_count>=8)
	{//收完一个字节
		re_spi_bit_count=0;
		return(spirebuf);
	}
	else 
	{
		spirebuf<<=1;
		goto spi_re1byte_p2;
	}
}

*/
//----------------------------------------------------------------------//
//UART通讯接收处理程序
//接收完成,设置标志ins_spi_flg
//指令处理程序处理完指令后,组织发送数据,并设置发送标志,发送程序查询到有发送标志comming_uart_flg,则开始发送.
//----------------------------------------------------------------------//
void uart_recv_isrp(void)
{
	uchar ls1;
	ls1=SCDR;
	

	if (ls1==0xff)
	{
		if (uart_re_ff_flg)
		{
			if (re_uart_strt_ct>=20)
			{//收到头的第2个ff离第1个ff时间间隔超过20毫秒,无效
				uart_re_ff_flg=0;
			}
			else
			{//收到头
				uart_re_strt_flg=1;
				uart_re_ff_flg=0;
				re_uart_count=0;
				return;
			}
		}
		else
		{
			if (re_uart_strt_ct>=20)
			{
				uart_re_ff_flg=1;
				re_uart_strt_ct=0;
			}
		}
	}
	re_uart_strt_ct=0;
	if (!uart_re_strt_flg) return;
	if (re_uart_count==0)
	{//收到头后的第1个字节,是参数个数
		if (ls1>19)
		{//参数个数超过19已经出现错误,则不再继续接收
			uart_re_strt_flg=0;
			uart_re_ff_flg=0;
		}
		ndre_uart_count=ls1+2;
	}
	re_uart_buf[re_uart_count]=ls1;
	re_uart_count++;
	if (re_uart_

⌨️ 快捷键说明

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