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