📄 00em4095v2.c
字号:
// ***********************************************
// 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 + -