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

📄 car_cad.c

📁 用RFM001多页读写32MM的TI玻璃管卡,采用严格的时钟控制
💻 C
字号:
#include <STC12C2052AD.h>
#include <stdio.h>
#include <string.h>
#include <intrins.h>


#define uchr unsigned char
#define uint unsigned int

//================读指令==============
#define DRF_R	0x7e	  		//只读
#define DRF_r/w	0xfe			//读写

//================写指令==============


#define INBUF_LEN	25

sbit WORK_LED = P1^7;
sbit OPEN = P1^5;
sbit TXCT = P1^2;				//控制选通(低电平有效)
sbit SCIO = P1^3;				//数据输出
unsigned char rece_ok,g_cReceNum;
uchr  RF_read_buf[INBUF_LEN];	//读缓冲区
uchr  In_buf[INBUF_LEN];			//

//union
//{
//	uchr crc[2];
//	uint i;
//}Hex ;

bit timer_3ms;
bit timer_15ms;
bit timer_20ms;
bit timer_50ms;

bit read_flag;

uchr bdata	get_chr;
sbit Bit7 = get_chr ^ 7;


void delay(uint i)
{
	while(-- i);
}

void RF_init(void)
{
	TXCT = 1;
	SCIO = 1;
}

void RF_charge()
{
	
	TXCT = 0;
	delay(39500);	  //50ms
	TXCT = 1;

		
}


void RF_program()
{
	
	TXCT = 0;
	delay(11850);  			//写完之后延时15 ms 
	TXCT = 1;
}

//===================================
//向串口发送一个字符 
void send_char_com(uchr ch) 
{
	SBUF=ch;
	while(TI==0);
	TI=0;
}

//向串口发送一个字符串,strlen为该字符串长度 
void send_string_com(uchr *str,uint strlen)
{
	uint k=0;
	do 
	{
		send_char_com(*(str + k));
		k++;
	} while(k < strlen);
}


//=================================================
// *ptr指向发送数据块的首地址, len是数据块以字节为单位的长度.
uint RF_crc(unsigned char *ptr, unsigned char len)
{
	unsigned char i;

	uint crc = 0;
	while(len -- != 0)
	{
		for(i = 0x01;i!=0;i <<= 1)
		{
			if((crc & 0x0001)!=0) 
			{
				crc >>= 1;
				crc ^= 0x8408;
			}
			else
				crc >>= 1;
			if((*ptr&i)!=0) crc ^= 0x8408;
		}
		ptr ++;
	}
	return(crc);
} 

//===============读程序=============
uchr RF_read_byte(void)
{
	uchr temp;
	
	get_chr = 0;
	while(1)
	{
 		if(SCIO == 1)     // 开始位
		{

			delay(75);		//96us
			for(temp = 0;temp < 8;temp ++)
			{	
				get_chr = get_chr >> 1;
				Bit7 = SCIO;
				Bit7 = ~ Bit7;
				delay(46);	  //64us
			}
	 
			delay(46);
			return (get_chr);
		}
	 }
}

void RF_read()
{
	uchr temp1;
	TR0 = 1;
	timer_20ms = 0;
	while(1)		
   	{	
   		if(timer_20ms == 1)			
		{
			timer_20ms = 0;
			TR0 = 0;
			return ;
		}
		if(SCIO == 1)
		{
			RF_read_buf[0] = RF_read_byte();

			if(RF_read_buf[0] == 0x7e)
			{
				for(temp1 = 1;temp1 < 14;temp1 ++)
				{
					RF_read_buf[temp1] = RF_read_byte();
				}
			}
			send_string_com(RF_read_buf,14);
			return;
		}
	}
}


//==============写程序==============

void RF_write_byte(uchr i)
{
	uchr temp;

		WORK_LED = 0;
			 
	for(temp = 0;temp < 8;temp ++)
	{
		
		if((i & 0x01)  == 0)
		{
			delay(235);     //0.3ms
			TXCT = 0;
			delay(1340);	//1.7ms
			TXCT = 1;
		}
		else
		{
	 		delay(789);	//1ms
			TXCT = 0;
			delay(789);	//1ms
			TXCT = 1;
		}
		i >>= 1;
	}
	TXCT = 1;
}



void RF_write(unsigned char choose,unsigned char *write_buf)
{
	uchr temp;
	uchr i;
	uint crc_check = 0;
    unsigned char RF_write_buf[INBUF_LEN];

	temp = 0;
	i = 0;

	if(choose==0)  //写第一页
  	  RF_write_buf[0] = 0x05;		            //第1页 写入
	else if(choose==1) //写第二页
	  RF_write_buf[0]=0x09;
	else if(choose==2) //写第三页
	  RF_write_buf[0]=0x0d;
  	  for(temp = 1;temp < 9;temp ++)	 		//要写入的8位ID号 
  	  {
		RF_write_buf[temp] = write_buf[temp-1];	
	  }	
  	  crc_check = RF_crc(RF_write_buf + 1,8);		//ID号的CRC校验值
	  RF_write_buf[9] = (uchr)(crc_check & 0x00ff);	    //crc的低8位
	  RF_write_buf[10] = (uchr)(crc_check >> 8);		 //crc的高8位
	  crc_check = RF_crc(RF_write_buf ,11);		//前11个值的CRC校验值	
	  RF_write_buf[11] = (uchr)(crc_check & 0x00ff);
	  RF_write_buf[12] = (uchr)(crc_check >> 8); 
  	  RF_init();
	  RF_charge();
	  for(temp = 0;temp < 13;temp ++)
	   {
		RF_write_byte(RF_write_buf[temp]);
	   }
	  RF_program();	 			//写完之后延时15 ms
}

void RF_comd()
{
	uchr temp = 0;
	uchr j = 0;
	uchr m = 0;
	uint i = 0;


//	memset(RF_write_buf,0,31);
//	RF_write_buf[0] = 0x01;				//包头
//	for(temp = 1 ;temp < 9; temp ++)
//	{
//		RF_write_buf[temp] = RF_read_buf[temp];		  //id
//	}
/*
	RF_charge();
							//					地址	 读命令
	RF_write_byte(0x08);	//写入第二页读地址(000010 + 00   )	车属单位

	RF_read();				//读程序
	
	for(temp = 1;temp < 9;temp ++)
	{
		RF_write_buf[temp + 8] = RF_read_buf[temp];
	}

	RF_charge();
							//					地址	 读命令
	RF_write_byte(0x0c);	//写入第三页读地址(000011 + 00   )	 车号1
	RF_read();				//读程序
	
	for(temp = 1;temp < 9;temp ++)
	{
		RF_write_buf[temp + 16] = RF_read_buf[temp];
	}

	
	RF_charge();
							//					地址	 读命令
	RF_write_byte(0x10);	//写入第三页读地址(000100 + 00   )	  车号2
	RF_read();				//读程序
	
	for(temp = 1;temp < 5;temp ++)
	{
		RF_write_buf[temp + 24] = RF_read_buf[temp];
	}

	i = dallas_CRC_8005(RF_write_buf,29,0);
	RF_write_buf[29] = ((i >> 8) & 0x00ff);
	RF_write_buf[30] = (i & 0x00ff);
 
	send_string_com(RF_write_buf,31);
	memset(RF_write_buf,0,31);
*/
}

void main()
{
    unsigned char old_buf[9];

	timer_20ms = 0;
    rece_ok=0;
	WORK_LED = 1;
	OPEN = 1;
    g_cReceNum=0;
	memset(RF_read_buf,0,INBUF_LEN);
	memset(In_buf,0,INBUF_LEN);

	RF_init();
 
	TMOD = 0x21;
	TL0 = 0;
	TH0 = 0xB8;
//	TR0 = 1;

	TH1 = 0xFD;
	TL1 = 0xFD;
	SCON = 0x50;
	TR1 = 1;
	IE = 0x82;
    IE |= 0x90;
    while(1)
    {
     if(rece_ok==0)
       continue;
	memset(RF_read_buf,0,INBUF_LEN);
     send_char_com(In_buf[0]);
	 switch(In_buf[0])
	  {
       case 0x55:  //读玻璃管卡ID
			RF_charge();
								//					地址	 读命令
			RF_write_byte(0x04);	//写入第一页读地址(000001 + 00   )
		
			RF_read();				//读程序
			RF_comd();
           break;
       case 0x56:  //读签卡单位
			RF_charge();
								//					地址	 读命令
			RF_write_byte(0x08);	//写入第二页读地址(000001 + 00   )
		
			RF_read();				//读程序
			RF_comd();
           break;
       case 0x57:  //读车牌号(8)+(4)
			RF_charge();
								//					地址	 读命令
			RF_write_byte(0x0c);	//写入第二页读地址(000001 + 00   )
		
			RF_read();				//读程序
			RF_comd();
           break;
	   case 0x66:  //写玻璃管卡ID)
	        memcpy(old_buf,In_buf+2,8);
	        RF_write(0,In_buf+2);

	  		RF_read();				//读程序
			RF_comd();
            if(memcmp(old_buf,RF_read_buf+1,8))
			{ 
			 send_string_com("\xAA\x01",2);
			 send_string_com(old_buf,8);
             send_string_com(RF_read_buf+1,8);
  		    }
			else
			{
			 send_string_com("\xAA\x00",2);
			}
            break;
	   case 0x67:  //签卡单位(8)
	        memcpy(old_buf,In_buf+2,8);
	        RF_write(1,In_buf+2);

	  		RF_read();				//读程序
			RF_comd();
            if(memcmp(old_buf,RF_read_buf+1,8))
			{ 
			 send_string_com("\xAA\x01",2);
			 send_string_com(old_buf,8);
             send_string_com(RF_read_buf+1,8);
  		    }
			else
			{
			 send_string_com("\xAA\x00",2);
			}
            break;
/*	   case 0x68:  //车牌号(12)
	        memcpy(old_buf,In_buf+2,12);
	        RF_write(In_buf+2);

	  		RF_read();				//读程序
			RF_comd();
            if(memcmp(old_buf,RF_read_buf+1,12))
			{ 
			 send_string_com("\xAA\x01",2);
			 send_string_com(old_buf,12);
             send_string_com(RF_read_buf+1,12);
  		    }
			else
			{
			 send_string_com("\xAA\x00",2);
			}
            break;
*/
	   default:    //缺省
	          break;
	  }
	 g_cReceNum=0;
     rece_ok=0;
     ES=1;
    }
}
 
void timer0 (void) interrupt 1 
{ 
	TL0 = 0;
	TH0 = 0xB8;
	timer_20ms = 1;
}


 
/////////////////////////////////////////////////////////////////////
//串行中断,接收上位机数据
/////////////////////////////////////////////////////////////////////
seri_int () interrupt 4 using 1
{
   unsigned char rece_data = SBUF;
   unsigned char verify = 0;

   if (RI)
   {    
       RI = 0;
       In_buf[g_cReceNum++]=rece_data;
	   if(g_cReceNum>INBUF_LEN)
	     g_cReceNum=0;
       if(g_cReceNum==(In_buf[1]+3))  //句柄1+长度(1)+数据(N)+疑惑校验(1)
	    {
	     rece_ok=1;
		 ES=0;
		}	    
    }
    if (TI)
    {	TI = 0;   }
}

⌨️ 快捷键说明

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