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

📄 00em4095v2.c

📁 这个也是关于EM4095的读卡程序,通过学习可以更好的了解ID读卡器的原理.
💻 C
📖 第 1 页 / 共 2 页
字号:
	 PORTB &= ~LED;					// LED =off
	 delay_ms(100);					// delay 100ms

   PORTD |= SHD;					// EM4095 shot down												 
   PORTD |= MOD;					// EM4095 max outut
	 PORTB |= LED;					// LED =on
	 delay_ms(100);					// delay 100ms
	 
   PORTD &= ~SHD;					// EM4095 ready
   PORTD &= ~MOD;					// EM4095 min output
	 PORTB &= ~LED;					// LED =off
	 delay_ms(100);					// delay 100ms
}

// *********************************************** 
// Change direction of caturing edge 
// by PB0/ICP input signal from DEMOD output of EM4095
// *********************************************** 
void set_rf_edge(char edge)
{
  if(edge)
	{
    timer1_init(1);		 		// setup timer1 to rising edge
    edge_dir =1;					// status =rf_fe_toggle on
  }
  else
  {
    timer1_init(0); 			// setup timer1 to falling edge
    edge_dir =0;					// status =rf_fe_toggle off
  }
}

// *********************************************** 
// Receiving 64 bits stream from RFID card at Timer1 capture
// output is number of saved bit and received 64 bis in rf buffer
// *********************************************** 
void get_bits_num(char num_bits, char edge)
{
  set_rf_edge(edge);          // change direction of caturing edge?
	// force save flag =1 for must save 1st received bit.
	bit_saved =1;      					 

  // If captured width is more than 40 then bit to inverting
  bit_value =0;								// bit value =0

  rf_buff_ptr	=0;             // byte pointer =0?  rf_bit_ptr =0;             	// bit pointer =0?  bit_trans_num =0;        		// number of save bit =0?  timer_over =0;             	// time over value =0
  old_width =0;								// old width =0

	TCCR1B = 0x00;							// stop Timer1 from EXT-T1 
 	TCNT1H = 0x00;				 							
 	TCNT1L = 0x00;							// tiemr0 =0x0000?	TCCR1B = 0x07;							// start timer1  
	TIMSK |= 0x20; 							// enable timer1 capture interrupt?
	// If number of saved bit is less than num_bits then receiving bit
  while(bit_trans_num < num_bits  && timer_over < 60)
	{
  } 
	// If number of saved bit is more than num_bits 
	// or tiem is more than 60ms then exit receiving bit 
	TIMSK &= ~0x20; 						// stop timer1 capture interrupt?
  rf_buff_ptr = 0; 						// reset buffer pointer?  rf_bit_ptr = 0;             // reset bit pointer?}

// *********************************************** 
// erase all bits in rf buffer
// *********************************************** 
void fill_rf_buff(char num_byte)
{
   int i;

	 rf_buff_ptr =0;
	 rf_bit_ptr =0;
	 
   for(i =0; i <num_byte; ++i)
   {
      rf_buff[i] = 0x00;
   }
}

// *********************************************** 
// Inverting all bits in rf buffer
// *********************************************** 
void invert_rf_buff(void)
{
   int i;

	 rf_buff_ptr =0;
	 rf_bit_ptr =0;

   for(i=0; i<sizeof(rf_buff); ++i)
   {
      rf_buff[i] = ~rf_buff[i];
   }
}

// *********************************************** 
// get bit from rf buffer
// Output is TRUE or FALSE (0x01 or 0x00)
// *********************************************** 
char get_buff_bit(void)
{
  char bit;
  char byte;
	
	if(!(rf_buff_ptr ==sizeof(rf_buff)))
  {
		byte =rf_buff[rf_buff_ptr];
		byte =(byte << rf_bit_ptr);			// bit shift for 0~7
		byte &=0x80;
		
		if (byte ==0x80) bit =0x01;
		else bit =0x00;			 						// make 1 bit result
						
    if(++rf_bit_ptr == 8)						// end of bit pointer?							
    {
      rf_bit_ptr = 0;								// bit pointer =0
      rf_buff_ptr++;	 	 						// byte pointer +1							
    }
  }
  return bit;												// return bit result
}

// *********************************************** 
// gte byte from received buffer?// *********************************************** 
char get_buff_byte(void)
{
  char i;				 		 					// bit counter
  char bit;			 							// get bit
	char byte =0;	 							// get byte
		
  if(!(rf_buff_ptr ==sizeof(rf_buff)))
  {
    for(i=0; i<8; ++i)
    {
		 	bit =get_buff_bit();			// get bit from buffer.

			if (bit) byte |=0x01;			// bit =1?			else byte &=0xfe;					// bit =0?
    	byte =(byte <<1);			 	 	// bit shift to left for make byte?		}
  }
 	return byte;
}

// *********************************************** 
// Find 9 bits header.
// *********************************************** 
void find_header(void)
{
  char i;				 		 					// bit counter?  char bit;			 							// get bit
	
	rf_buff_ptr =0;
	rf_bit_ptr =0; 							// start of buffer?	
	flag_err =0;								// reset flag of error		
  for(i =0; i <9; i++)				// for 9 bits test?  {
  	bit =get_buff_bit();			// 厚飘绰 0 趣篮 1肺 甸绢柯促.
		if (bit ==0) flag_err =1;	// 窍唱扼档 厚飘啊 0捞搁 坷幅
	}
}

// *********************************************** 
// Check horizontal parity.
// *********************************************** 
void checksum_h(void)
{
	char j;											// nibble counter?  char k;				 		 					// bit counter?  char bit;			 							// get bit
	char parity;								// 菩府萍
	
	parity_err =0; 							// reset parity error 
	for (j=0;	j < 10; j++)			// for 10 of nibbles?	{
	  parity =0;								// result =0 for parity calulation?		for(k =0; k < 4; k++)			// for 4 of bits. 
		{
  	  bit =get_buff_bit();		// get bit for 0x00 or 0x01.
			if (bit) parity ^=0x01;	// calculate parity for 4 bits.
		}

 		bit =get_buff_bit();			// 5th bit is parity.
		if (bit !=parity) parity_err =1;	// not match is found error.
	}
}

// *********************************************** 
// Check vertical parity.
// *********************************************** 
void checksum_v(void)
{

}

// *********************************************** 
// 64 bits ASCII transmit for binary dispaly.			
// *********************************************** 
void tx_buff_bin(void)
{
  char bit;
	char txd;
	char i,j;
	 
	rf_buff_ptr =0;
	rf_bit_ptr =0;
	uart_putc(0x0a);	 					// lf =start of text

	for (i =0; i <64; i++)
	{
    bit =get_buff_bit();			// get bit from rf_buff
		if (bit) txd =0x31;				// 0x31 =ascii '1'
		else txd =0x30;						// 0x30 =ascii '0'
		uart_putc(txd);						// '0' or '1' to uart
	}
	uart_putc(0x0d);	 					// cr =end of text
}
	
// *********************************************** 
// 10 digit ASCII transmit to UART for hexa dispaly.			
// *********************************************** 
void tx_buff_hex(void)
{
  char bit;
	char txd;
	char i,j;
	 
	rf_buff_ptr =1;							// skip 9 bits of header?	rf_bit_ptr =1;							
	uart_putc(0x0a);	 					// start of text =LF

	for (i =0; i <10; i++)			// 10 of nibbles ?	{
	  for (j =0; j <4; j++)			// for 4 bit?		{ 
			txd = (txd <<1); 				// shift to left for saved bit
			bit =get_buff_bit();		// get bit from rf_buff
			if (bit) txd |=0x01;		// save bit to lsb
			else txd &= 0xfe;
		}

		txd &= 0x0f;	 						// enable 4bit for nibble?		if (txd < 0x0a) txd +=0x30;
		else txd +=0x37;					// make ASCII HEX for dispaly?		
		uart_putc(txd);						// ASCII transmit to UART
		bit =get_buff_bit();			// get parity and remove?	}
	uart_putc(0x0d);	 					// end of text =CR
}

// *********************************************** 
// Main routine 
// *********************************************** 
void main(void)
{
  CLI(); 	   			   					//disable all interrupts
  MCUCR = 0x00;
  GICR  = 0x00;

  port_init();
  eeprom_init();		  				// disable eeprom interrupt
  adc_init(); 			  				// 10 bit adc #7 (free run)

  timer2_init();		  				// init 10us timer
  uart0_init();			  	 			// init serial port
  SEI();  	   			  	 			// re-enable interrupts

  uart_putc(0x0a);			 			// start of string
  uart_puts("EM4095 RFID Card Reader V2.0");
  uart_putc(0x0d);				 		// end of string	 

	em4095_init();						 	// init EM4095 RFID reader
	timer1_init(0);				 			// init timer1 from EXT-T1 (EM4095-CLK)
	fill_rf_buff(16);			  		// erase rf buffer. 

  while(1)						 
  {
		PORTD |=MOD;								// turn off indicator?		delay_ms(20);								// turn off time =20 ms,
		PORTD &= ~MOD;							// start EM4095 read mode
		fill_rf_buff(16);			  		// erase rf buffer 16 bytes. 

		// EM type (Read only) data format
		// 1111 11111 = Header = 9 bit?		// xxxxP, xxxxp= Custom #1,#2  = 10 bit
		// xxxxP,xxxxP = data #1,#2  = 10 bit
		// xxxxP,xxxxP = data #3,#4  = 10 bit
		// xxxxP,xxxxP = data #5,#6  = 10 bit
		// xxxxP,xxxxP = data #7,#8  = 10 bit
		// PPPP0 = 4 Parity + 1 stop = 5 bit
		// data 55 bits + header 9 bits =64 bits?		
		// Manchester code detecting method
		// Header (9 bits)
		// ______--__--__--__--__--__--__--__--__-- (wave)
		// 0-0 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1  (edge)
		// (x) (1) (1) (1) (1) (1) (1) (1) (1) (1)  (code)
		
		// Custom-ID (10 bits) 
		// --__--__--__--__--__--____----__--____-- (wave)
		// 1-0 1-0 1-0 1-0 1-0 1-0 0-1 1-0 1-0 0-1  (edge)
		// (0) (0) (0) (0) (0) (0) (1) (0) (0) (1)  (code)
		//  D7  D6  D5  D4  Pr  D3  D2  D1  D0  Pr  (Pr =parity)
		      
		// find manchester pattern in received bits
		// output is number of received bits =bit_trans_num
		get_bits_num(64, 0);	 			// receive 64 bits stream within 60ms 	
		PORTB &= ~LED;	 	 					// Indicator turn off?
		find_header();							// check head is 9 bit =1?
		checksum_h();								// check horizontal parity?		checksum_v();								// check vertical parity?		
		if (flag_err ==0)						// has no head error?
		{ 
			if (parity_err ==0)				// has no parity error? 
			{
//		  tx_buff_bin();					// 64 binary display code to UART.			
			  tx_buff_hex();					// 10 hexa dispaly code to UART.			
		  	PORTB |=REL;						// turn on relay.
			}
			else PORTB |=BUZ;					// if error available then turn on buzzer.		
		}												

		// Total cycle time = reste 20ms + receive 60ms + output 120ms = 200ms?		delay_ms(120);							// output time = 120ms								
		PORTB &= ~BUZ;							// turn off buzzer.
		PORTB &= ~REL;							// turn off relay.
	}	
}

// *********************************************** 
// 林 窃荐狼 场
// *********************************************** 

⌨️ 快捷键说明

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