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

📄 00em4095v2.c

📁 这个也是关于EM4095的读卡程序,通过学习可以更好的了解ID读卡器的原理.
💻 C
📖 第 1 页 / 共 2 页
字号:
// *********************************************** 
// project : RFID Reader V2.0
// Target : MEGA8-16AU
// Crystal: 14.7456 Mhz
// Input : EM4095 RFID 125KHz
// Output : RS232C 115200,N,8,1
// Compiler : ICC-AVR V6.26C
// Author : leeky@avrtools.co.kr
// *********************************************** 

// *********************************************** 
// Pin configuration for ATMEGA8-16AU TQFP32
// *********************************************** 
// #30 PD0/RXD <--- RXD (RS232C)
// #31 PD1/TXD ---> TXD (RS232C)
// # 9 PD5/T1 <--- TIMER1 EXT-T1 <--- RDY-CLK (EM4095)
// #10 PD6 ---> SHD (EM4095)
// #11 PD7 ---> MOD (EM4095)

// #12 PB0/ICAP <--- TIMER1 ICAP <--- DEMOD (EM4095)
// #13 PB1 ---> LED (Indicator)
// #14 PB2 ---> BUZZER (Warning)
// #15 PB3 ---> RELAY (Output)
// *********************************************** 
#include <iom8v.h>  // Define for Mega8 MPU																 
#include <macros.h>	// Define for macro functions

// *********************************************** 
// Variables for System 
// *********************************************** 
unsigned char time_1ms; 
unsigned int	adc_buff;
unsigned char rxd_buff;
 
// *********************************************** 
// Initialize Variables for flags
// *********************************************** 
unsigned char flag_1ms =0;    // timer 1 ms	 
unsigned char flag_adc =0;	 	// end of adc conversion
unsigned char flag_rxd =0;	 	// serial received

unsigned char flag_err =0;	 	// header error
unsigned char parity_err =0;	// parity error

// *********************************************** 
// Constant define
// *********************************************** 
#define REL 0x08		// Relay =PB3																  
#define BUZ 0x04		// Buzzer =PB2																  
#define LED 0x02		// indicator =PB1
#define DEM 0x01 		// RF Data input EXT-INT0 from PB0/ICAP

#define RXD 0x01		// PD0/RXD <--- ROUT SP232 <--- PC TXD  
#define TXD 0x02 		// PD1/TXD ---> TINP SP232 ---> PC RXD
#define CLK 0x20		// EXT-T1 input for RF read clock =PD5 																			 																	 // External interrupt used to read clock

#define SHD 0x40 		// RF shot down for RF disable =PD6
#define MOD 0x80		// RF 100% modulation =PD7

// *********************************************** 
// Global variables for buffer
// *********************************************** 
char rf_buff[16];	 		 			// rf buffer  
char rf_buff_ptr =0;				// rf buffer pointer?char rf_bit_ptr = 0;				// rf bit pointer

// *********************************************** 
// Global variables
// *********************************************** 
char bit_value =1;				  // received bit value
char bit_saved =1;					// flag of next bit will be store  
char edge_dir =1;						// Edge Direction is riging										 

char stable_width =0;	 			// RF uncertainty
char bit_trans_num =0;			// number of bit stored

int	 old_width =0;					// old width of captured timer1 value
int  timer_over =0;					// flag of time overflow 

// *********************************************** 
// Initialize Ports
// *********************************************** 
void port_init(void)
{
  PORTB = 0x01;      	 // PB3=Relay,PB2=Buzzer,PB1=LED,
 	DDRB  = 0xFE;				 // PB7~PB1 =output,PB0=DEMOD input. 
 
 	PORTC = 0x00;				 // PORTC = adc input (not used) 
 	DDRC  = 0x00;		   	 // PC7~PC0 = all input

 	PORTD = 0xCF;			 	 // PD7=MOD,PD6=SHD,PD5=RDY-CLK(input)
 	DDRD  = 0xC0;			 	 // PD7~PD6 =output
}

// eeprom_init()
// Initialize internal eeprom
void eeprom_init(void)
{
	EECR = 0x00;					// Disable interrupts
}

// *********************************************** 
// ADC initialisation
// Conversion time: 104uS
// *********************************************** 
void adc_init(void)
{
  ADCSR = 0x00; 	   //disable adc
  ADMUX = 0x07; 	   //select adc input 7 only
  ACSR  = 0x80;
  ADCSR = 0xEF;
}

// *********************************************** 
// Interrupt handler for ADC
// conversion complete, read value (int) using...
// value=ADCL; Read 8 low bits first (important)
// value|=(int)ADCH << 8; 
// read 2 high bits and shift into top byte
// *********************************************** 
#pragma interrupt_handler adc_isr:15
void adc_isr(void)
{
  adc_buff =ADCL;	 	  	  			// get low byte only
  adc_buff |=(int)ADCH << 8;  	// get high byte and amke int
  flag_adc =1;	   	  	  			// end of adc convert
}

// *********************************************** 
// TIMER2 initialisation - prescale:128
// WGM: Normal
// desired value: 1mSec
// actual value:  0.998mSec (0.2%)
// *********************************************** 
void timer2_init(void)
{
 	TCCR2 = 0x00; 			//stop
 	ASSR  = 0x00; 			//set async mode
 	TCNT2 = 0x8D; 			//setup
 	TCCR2 = 0x05; 			//start
	TIMSK |= 0x40; 			// timer2 interrupt sources
}

// *********************************************** 
// Interrupt handler for TIMER2 1ms overflow
// *********************************************** 
#pragma interrupt_handler timer2_ovf_isr:5
void timer2_ovf_isr(void)
{
  TCNT2 = 0x8D; 			// reload counter value
  flag_1ms =1;	   		// flag_1ms =1
	timer_over++;				// 1ms timer +1
}

// *********************************************** 
// Delay for ms
// *********************************************** 
void delay_ms(int dly)
{
 	 unsigned int i;
	 for (i=0; i <dly; i++)		// 1ms *N =N [ms]	
	 {
		 while (flag_1ms ==0)		// Stand by 1ms
		 {
		 }
		 flag_1ms =0; 	 				// reset 1 ms timer		  
	 } 
}
 
// *********************************************** 
// UART initialize for 115200,N,8,1
// char size: 8 bit, parity: Disabled
// *********************************************** 
#define F_OSC 14745600	// oscillator-frequency in Hz
#define BAUD_RATE 57600	// x2 =115,200 bps
#define BAUD_CALC ((F_OSC)/((BAUD_RATE)*16l)-1)

void uart0_init(void)
{
  UCSRB = 0x00; //disable while setting baud rate
  UCSRA = 0x02; //double baud rate
  // 0x86 = asynchronous 8N1
  UCSRC = (1<<URSEL)|(3<<UCSZ0);
  // set baud rate
  UBRRH =BAUD_CALC >>8;
  UBRRL =BAUD_CALC;
  // 0x90 = Enable receiver and transmitter
	// enable RX interrupt
  UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
}

// *********************************************** 
// Interrupt handler for UART0 receiver
// *********************************************** 
#pragma interrupt_handler uart0_rx_isr:12
void uart0_rx_isr(void)
{
 //uart has received a character in UDR
  rxd_buff =UDR;
  flag_rxd =1;
}

// *********************************************** 
// String send to UART
// wait until UDR ready
// *********************************************** 
void uart_putc(unsigned char tx_byte)
{
  while(!(UCSRA & (1 << UDRE)));
  UDR = tx_byte;    // send character
}

// *********************************************** 
// loop until *s != NULL
// *********************************************** 
void uart_puts (char *str)
{
  while (*str)
  {
    uart_putc(*str);
    str++;
  }
}

// *********************************************** 
// TIMER1 initialze for ICP cature 
// timer1 clock is EXT_T1 from RDY-CLK of EM4095
// PB0/ICP capture input is DEMOD sinal from EM4095
// *********************************************** 
void timer1_init(char edge)
{
  TCCR1B = 0x00; 			// stop timer1 
	TCNT1H = 0x00;
	TCNT1L = 0x00;			// start from 0000

	ICR1H  = 0x00;
	ICR1L  = 0x00;			// using timer1 capture

	TCCR1A = 0x00;
	TCCR1B = 0x00;			// stop timer1, 

	if (edge ==1) TCCR1B = 0x40;  // ICAP capture from T1 riging.
	else TCCR1B = 0x20;	// ICAP capture from T1 falling. 
	TIMSK |= 0x24; 			// timer1 capture, overflow interrupt sources
}

// *********************************************** 
// TIMER1 overflow interrupt
// *********************************************** 
#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{
  //TIMER1 has overflowed
 	TCNT1H = 0x00;				 	// reload counter high value
 	TCNT1L = 0x00;				 	// reload counter low value
}

// *********************************************** 
// Received bit store by buffer pointer in rf buffer
// *********************************************** 
void rf_bit_store(char bit_value)
{
  char byte;

	if(!(rf_buff_ptr ==sizeof(rf_buff)))	// not end of buffer?
  {
	  byte =rf_buff[rf_buff_ptr];	// get saved byte by pointer
		byte =(byte << 1);					// shift left
		
		if (bit_value) byte |=0x01;	// received bit =1					 
		else byte &=0xfe;						// received bit =0?		rf_buff[rf_buff_ptr] =byte; // store received bit?
 		if(++rf_bit_ptr == 8)			// end of bit pointer? ? 		{
   	  rf_bit_ptr = 0;	 	 			// bit pointer =0?   		++rf_buff_ptr;					// increament byte poiinter 
 		}
	}
}

// *********************************************** 
// PB0/ICP cature interrupt 
// captured 16 bit ICR1 register read 1st low byte
// current edge direction chage to reverse edge direction
// *********************************************** 
#pragma interrupt_handler timer1_capt_isr:6
void timer1_capt_isr(void)
{
 	int value;							// temporary of catured value
	int width;							// temporary of width calc. 
	
	value =ICR1L;						 // Read low byte first (important)
	value |=(int)ICR1H << 8; // Read high byte and shift into top byte

  if (edge_dir)	 			 		 // change ICP capture direction of edge. 
  {
	  TCCR1B &= ~0x40;
		TCCR1B |= 0x20;				 // ICP capture direction edge to riging 
    edge_dir =0;		 		 	 // for next cature direction is falling.    
  }
  else
  {
	  TCCR1B &= ~0x20;
		TCCR1B |= 0x40;				 // ICP capture direction edge to falling 
    edge_dir =1;		 		 	 // for next capture direction is riging
  }

	width =value -old_width; // width = new captured width - old captured width
	old_width =value;     	 // updata old captured width for next width calc.
	
  // receiving manchester code from RFID card. 
	// 1st received bit is must be 1 for 1st bit is header after reset, 
	// if pulse width is more than 40 then received bit to invert.
  if(width > 40)							// narrow pulse width is under 32,
	{
	  if (bit_value) PORTB |=LED;	// debug indictor for input bits
		else PORTB &= ~LED;

    bit_value = ~bit_value; 	// received bit is inverting
	  rf_bit_store(bit_value);	// save inverted bit
	 	++bit_trans_num;					// increament number of saved bits
  	bit_saved = 0;  					// skip bit store when bit inverted?  }
		
  if(bit_saved)        				// will be bit store?
  {
	  if (bit_value) PORTB |=LED;	// debug indictor for input bits 
		else PORTB &= ~LED;
				
	  rf_bit_store(bit_value);	// bit store in rf buffer
	 	++bit_trans_num;					// number of stored bits +1
	}
	bit_saved = ~bit_saved;  		// skip next store for next bit 
}

// *********************************************** 
// RFID Card Reader EM4095 initialize
// EM4095 output ---> PD5/T1 =RDY-CLK, PB0/ICP =DEMOD
// EM4095 input <--- PD7 =MOD, PD6 =SHD.
// *********************************************** 
void em4095_init()
{
	 PORTB |= BUZ;					// Buzzer =on 	 
	 PORTB |= LED;					// LED =on
	 delay_ms(100);					// delay 100ms

	 PORTB &= ~BUZ;					// Buzzer =off 	 

⌨️ 快捷键说明

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