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

📄 level3.c

📁 此程序为利用mage8 AVR 和EM4094实现读取TYPE A类型卡的C程序、读卡稳定、这个项目我们做了好久、非常不错的程序、很适合做这方面产品的朋友们参考
💻 C
📖 第 1 页 / 共 2 页
字号:



#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/wdt.h>
#include "level4.h"
#include "level3.h"
#include "level2.h"
#include "level1.h"

//--------------------------------------------------------------
//global variables
uint8_t volatile sof;                   //sof and eof indication
uint8_t maxCaptureTime;                 //current maximum capture time (used to initialise TCNT2)
uint8_t maxCaptureTimeScale;            //scale of current maximum capture time (expected value 3 - 7 only)
uint8_t cmd_message[ UART_IN_BUFFER_SIZE ];  // maximum

uint8_t debug_mode;
uint8_t expectedResponseLen;            // expected number of response bits
uint8_t clean_data_cnt;                 //clean response data length
uint16_t maxTGeneral;                   //current datarate maximum response capture time
uint8_t em4094_data_valid;              //EM4094读到了有效数据,即读到了卡号;
//--------------------------------------------------------------
//Local function declarations

void Capture( void );
void Compute_Timeouts( void );
uint16_t ScaleOnce( uint16_t period );
uint8_t ScaleTime( uint16_t period );
void Send( uint8_t len , uint16_t wait_time );
void store_bit( uint8_t b , uint8_t v );
void store_pulse( uint8_t b );
void type_A_polling( void );
void TypeA_GetUID( void );
void Wait( uint16_t period ); 


// ==================================================================
// Down Link setup function
// Requires: maxCaptureTime and maxCaptureTimeScale
//   (located here instead of level2 because of register variables)

void Capture( void ) 
{
    TCCR0 = 0;                                //disable Counter0
    TCCR1B = 0;                               //disable Counter1
    TCNT1 = 0;
    if ( !bufferClean ) 
    	  ClearCaptureBuffers( );
    bufferClean = 0;
    captured_bit_count = 0;                   //reset some values
    capture_cnt = 0;
    raw_cnt = 0;
    bit_pos = 1;
    sof = 0;
    //set hi byte of maximum capture timer2 timeout
    TCNT2 = ~maxCaptureTime;                  //set timer2 timeout
    TCNT0 = 0;                                //clear timer0
    TIFR = TIFR | ( 1 << ICF1 ) | ( 1 << TOV1 ) | ( 1 << OCF2 ) | ( 1 << TOV2 );      //clear pending interrupts
    sbi( TIMSK , TOIE2 );                      //enable timer2 overflow
    sbi( SFIOR , PSR2 );                       //clear timer2 prescaler
    //  enable_capture = style;                   //set capture style
    TCCR2 = maxCaptureTimeScale;              //run T2
    if( forward_link_type == 2 ) 
    {                //type A
        TCCR0 = 6;                                //external clock source, falling edge
        TCCR1B = counter1set;                     //run! at clk
        type_A_polling( );                         //do polling until done for Manchester
        
        wdt_reset( );
        
#ifdef WDT
        WatchDog_Feed( );
#endif
        TCCR0 = 0;                                //stop all
        TCCR1B = 0;
    } 
    
    TCCR2 = 0;
    cbi( TIMSK , TOIE2 );                        //disable timer2 overflow
    sbi( TIFR , TOV2 );                          //clear pending interrupt

    if ( ( debug_mode != 1 ) && ( forward_link_type != 3 ) ) 
    {
        while ( captured_bit_count != 0 )           //flush captured bits
        store_bit( 0 , 1 );
    }
}

// ********************************************************************************************
// Description : Wait period/16 us , and use Prescaler to realize period cycles large than 256
//               instead of times of T2 overflow.
// Return value: None.   
// parameter   : period -- the number of cycles of OSC.
// ********************************************************************************************


void Wait( uint16_t period ) 
{
    uint8_t time = ScaleTime( period );
    TCCR2 = 0;                                //disable Counter2
    TCNT2 = -time;                            //set timer with initial time
    TIFR = TIFR | ( 1 << OCF2 ) | ( 1 << TOV2 );      //clear pending interrupts
    sbi( SFIOR , PSR2  );                       //clear T2 prescaler
    sbi( TIMSK , TOIE2 );                      //enable overflow
    TCCR2 = maxCaptureTimeScale;              //run! at clkio/scale
    while ( TIMSK & ( 1 << TOIE2 ) )              //wait until done
    { }
    TCCR2 = 0;                                //stop
}


// ********************************************************************************************
// Description : Compute the timeout of polling data from antenna.
// Return value: None.   
// parameter   : None.
// ********************************************************************************************

void Compute_Timeouts( void ) 
{
    uint16_t pom = 0;
    pom = ( uint16_t )expectedResponseLen * 20 + 1;
    pom = ( 19 * ( uint32_t )pom ) / 16 + 1;   //13.56 to 16 correction
    maxTGeneral = pom;
}


//--------------------------------------------------------------
//send command and wait
//
void Send( uint8_t len , uint16_t wait_time ) 
{
    uint8_t fwd_bit_count;
    uint8_t i;
    fwd_bit_count = Prepare_SOF( );

    for ( i = 0 ; i < len ; i++ ) 
        fwd_bit_count += Prepare_Data( cmd_message[ i ] , len );

    fwd_bit_count += Prepare_EOF( len );

    Compute_Timeouts( );
    
    ClearCaptureBuffers( );
    
    maxCaptureTime = ScaleTime( maxTGeneral );
    
    SendForward( fwd_bit_count );
    
    if ( wait_time != 0 ) 
    	  Wait( wait_time );
}

//--------------------------------------------------------------
// general read function
//


typedef struct {
    uint16_t atqa;
    uint8_t uid[ 3 * 5 ];
    uint8_t sak[ 3 ];
} TA_UID;

void TypeA_GetUID( void ) 
{
    uint8_t i , j , cascade;
    TA_UID ta_uid;
    
//    cbi( PORTD , DBG_FORWARD );  

    forward_link_type   = 0x02; 
    cmd_message[ 0 ]    = 0x26; //REQA
    expectedResponseLen = 0x10;
    
    Send( 1 , 30 );
     
    wdt_reset( );
#ifdef WDT
        WatchDog_Feed( );
#endif
       
    Capture( );
    

    wdt_reset( );
#ifdef WDT
        WatchDog_Feed( );
#endif    
    clean_data_cnt = ExtractTypeAData( 248 );

    if ( clean_data_cnt == expectedResponseLen ) 
    {
        ta_uid.atqa = ( data_buffer[ 1 ] << 8 ) | ( data_buffer[ 0 ] );
    } 
    else 
    {    	  
        em4094_data_valid = 0x00 ;
        return;
    }
    i = data_buffer[ 0 ];
    j = i & 0x1F;
    if ( ( data_buffer[ 1 ] & 0x0F ) || ( ( i & 0xC0 ) == 0xC0 ) ||
      ( !( ( j == 0x01 ) || ( j == 0x02 ) || ( j == 0x04 ) || ( j == 0x08 ) || ( j == 0x10 ) ) ) ) 
    {
    	  em4094_data_valid = 0x00 ;
     	  return;
    }  
//    Beep( 2 );       
    cascade = 0;        //cascade loop

    i = 0x04;

    while ( i != 0 ) 
    {

        expectedResponseLen = 0x28;
        cmd_message[0] = cascade * 2 + 0x93;
        cmd_message[1] = 0x20;     //SEL (NVB = 0x20)
       
        Send( 2 , 30 );

        Capture( );

        clean_data_cnt = ExtractTypeAData( 248 );

        if ( clean_data_cnt == expectedResponseLen ) 
        {
            for ( i = 0 ; i < 5 ; i++ ) 
            {
                ta_uid.uid[ cascade * 5 + i ] = data_buffer[ i ];    //store this uid part
//                SendByte( data_buffer[ i ] );
//                weigan_data[ i ] = data_buffer[ i ] ;
//                Beep( 3 );
                cmd_message[ 2 + i ] = data_buffer[ i ];                      //copy uid part to cmd for full selection
            }
            weigan_data[ 0 ] = data_buffer[ 3 ]; 
            weigan_data[ 1 ] = data_buffer[ 2 ];
            weigan_data[ 2 ] = data_buffer[ 1 ];
            weigan_data[ 3 ] = data_buffer[ 0 ];
            weigan_data[ 4 ] = data_buffer[ 4 ];
            em4094_data_valid = 0x55 ;
//            SendByte(  0xC0 + cascade );
//            Beep(2);
            return;
        } 
        else 
        {
            em4094_data_valid = 0x00 ;
//            SendByte( 0xD0 + cascade );
            return;
        }
        
        expectedResponseLen = 0x18;
        cmd_message[ 0 ]    = cascade * 2 + 0x93;
        cmd_message[ 1 ]    = 0x70;              //SELECT (NVB = 0x70)

        uint16_t crc = ISOCRCA( cmd_message , 7 );
        cmd_message[ 7 ] = crc & 0xFF;
        cmd_message[ 8 ] = crc >> 8;
        
        Send( 9 , 30 );  

        Capture( );
       
        clean_data_cnt = ExtractTypeAData( 248 );

        if ( clean_data_cnt == expectedResponseLen ) 
        {
            crc = ISOCRCA( data_buffer , 1 );

⌨️ 快捷键说明

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