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

📄 level4.c

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


#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 declarations

uint8_t uart_out_buffer[ 4 ] = { 0x55 , 0xAA , 0x01 , 0x02 };
uint8_t uart_in_buffer[ UART_IN_BUFFER_SIZE ];    //receive buffer,receive data from UART of PC;
//uint8_t uart_in_error;       //uart receive error;
//uint8_t uart_in_write;       //received value numbers;
//uint8_t uart_in_read;        //
//uint8_t uart_in_overflow;
uint8_t tx_number;           //received data byte number of raw data from PC;
uint8_t rx_number;

//uint8_t uart_valid_data_num; //recieved valid data number,one command and one parameter counted as one ;
//uint8_t uart_command;
//uint8_t uart_param;
uint8_t uart_in_command;
uint8_t uart_in_param;
uint8_t valid_data_flag ;

// ==================================================================
void Send_Weigan0( void );
void Send_Weigan1( void );
void Send_Weigan26( uint8_t * data );
void Send_Weigan34( uint8_t * data );
void Send_Weigan36( uint8_t * data );
void Send_Weigan44( uint8_t * data );
void Send_9600( uint8_t * data );

// ==================================================================
// uart byte receive interrupt

SIGNAL ( SIG_UART_RECV )
{
	  uint8_t temp;
	  uint8_t error;
	  error = UCSRA & ( ( 1 << FE ) | ( 1 << DOR ) | ( 1 << PE ) ); 
    temp = UDR;               //store byte into cyclic buffer
    if ( error != 0 )
    {
        rx_number = 0 ;    
        return;
    }
    if ( valid_data_flag != 0 )
    	  return;
    switch( rx_number )
    {
        case 0 :
        	  if ( temp == 0x55 )
        	      rx_number = 1 ;
        	  else
        	      rx_number = 0 ;
            break;
            
        case 1 :
        	  if ( temp == 0xAA )
        	      rx_number = 2 ;
        	  else
        	      rx_number = 0 ;
        	  break;	
        	  
        case 2 :
        	  if ( temp == 0x01 )
        	      rx_number = 3 ;
        	  else 
        	      rx_number = 0 ;
        	  break;	
        	  
        case 3 :
        	  if ( error != 0 )
        	  	  rx_number = 0 ;
        	  else
        	  {
        	      uart_in_command = temp;
        	      rx_number = 4 ;
        	  }
        	  break;	
        	          	  
        case 4 :
        	  if ( error != 0 )
        	  	  rx_number = 0 ;
        	  else
        	  {
        	      uart_in_param = temp;
        	      rx_number = 5 ;
        	  }
        	  break;	 
        	         	  
        case 5 :
        	  if ( temp == 0x55 )
        	      rx_number = 6 ;
        	  else
        	  {
        	  	  rx_number = 0 ;
        	  }
        	  break;	
        	          	  
        case 6 :
        	  rx_number = 0 ;
        	  if ( temp == 0xAA )
        	  {
                valid_data_flag = 0x55;
        	  }
        	  break;
        default :
        	  rx_number = 0 ;
        	  break;	        	          	  
    }
}


// ********************************************************************************************
// Description : Send one byte through UART.
// Return value: None.   
// parameter   : byte -- the byte to be sent.
// ********************************************************************************************
 
void SendByte( uint8_t byte ) 
{
	  sbi( PORTC , TEN_485 );
	  UDR = byte;
    while ( !( UCSRA & ( 1 << UDRE ) ) )
    { }
    Delayus( 900 );
    cbi( PORTC , TEN_485 );     
}



// ********************************************************************************************
// Description : Send weigan26 model and encode according to weigan26 protocol.
// Return value: None.   
// parameter   : * data -- the point of the data to be encoded.
// ********************************************************************************************

void Send_Weigan26( uint8_t * data )
{
	  uint8_t i , weigan26_even_data , weigan26_odd_data , parity_bit , bit_cnt;
	  parity_bit = 0;               //If use even parity check , this bit must be 0;
	  for ( i = 8 ; i < 20 ; i++ )
	  {
	  	  bit_cnt = i % 8 ;
	  	  parity_bit ^= ( data[ i / 8 ] >> ( 7 - bit_cnt ) ) & 0x01; 
	  }
	  wdt_reset( );
#ifdef WDT
    WatchDog_Feed( );
#endif
	  weigan26_even_data = parity_bit ;
	  parity_bit = 1;               //If use odd parity check , this bit must be 1 ;
	  for ( i = 20 ; i < 32 ; i++ )
	  {
	      bit_cnt = i % 8;
	      parity_bit ^= ( data[ i / 8 ]	>> ( 7 - bit_cnt ) ) & 0x01;
	  }
	  wdt_reset( );
#ifdef WDT
    WatchDog_Feed( );
#endif
	  weigan26_odd_data = parity_bit;
	  if ( weigan26_even_data )                   //Send E bit;                     
	  	  Send_Weigan1();
	  else
	  	  Send_Weigan0();
	  for ( i = 8 ; i < 32 ; i++ )                //Send CCCC CCCC CCCC CCCC CCCC CCCC;
	  {
	      bit_cnt = i % 8 ;
	      if ( ( data[ i / 8 ] >> ( 7 - bit_cnt ) ) & 0x01 )     //MSBit is sent first;
	      	  Send_Weigan1();
	      else
	      	  Send_Weigan0();	
	  }
	  if ( weigan26_odd_data )                    //Send O bit;
	  	  Send_Weigan1();
	  else
	  	  Send_Weigan0();		  	  
}

// ********************************************************************************************
// Description : Send weigan34 model and encode according to weigan34 protocol.
// Return value: None.   
// parameter   : * data -- the point of the data to be encoded.
// ********************************************************************************************

void Send_Weigan34( uint8_t * data )
{
    uint8_t i , weigan34_even_data , weigan34_odd_data , parity_bit , bit_cnt;
	  parity_bit = 0;               //If use even parity check , this bit must be 0;
	  for ( i = 0 ; i < 16 ; i++ )
	  {
	  	  bit_cnt = i % 8 ;
	  	  parity_bit ^= ( data[ i / 8 ] >> ( 7 - bit_cnt ) ) & 0x01; 
	  }
	  weigan34_even_data = parity_bit ;
	  wdt_reset( );
#ifdef WDT
    WatchDog_Feed( );
#endif  
	  parity_bit = 1;               //If use odd parity check , this bit must be 1 ;
	  for ( i = 16 ; i < 32 ; i++ )
	  {
	      bit_cnt = i % 8;
	      parity_bit ^= ( data[ i / 8 ]	>> ( 7 - bit_cnt ) ) & 0x01;
	  }
	  weigan34_odd_data = parity_bit;   
	  wdt_reset( );
#ifdef WDT
    WatchDog_Feed( );
#endif      
	  if ( weigan34_even_data )                   //Send E bit;
	  	  Send_Weigan1();
	  else
	  	  Send_Weigan0();
	  for ( i = 0 ; i < 32 ; i++ )                //Send CCCC CCCC CCCC CCCC CCCC CCCC CCCC CCCC;
	  {
	      bit_cnt = i % 8 ;
	      if ( ( data[ i / 8 ] >> ( 7 - bit_cnt ) ) & 0x01 )    //MSBit is send first;
	      	  Send_Weigan1();
	      else
	      	  Send_Weigan0();	
	  }
	  if ( weigan34_odd_data )                    //Send O bit;
	  	  Send_Weigan1();
	  else
	  	  Send_Weigan0();	  	   
}

// ********************************************************************************************
// Description : Send weigan36 model and encode according to weigan36 protocol.
// Return value: None.   
// parameter   : * data -- the point of the data to be encoded.
// ********************************************************************************************

void Send_Weigan36( uint8_t * data )
{
	  uint8_t i , weigan36_even_data , weigan36_odd_data , parity_bit , bit_cnt;
	  parity_bit = 1;               //If use odd parity check , this bit must be 1 ;
	  for ( i = 0 ; i < 17 ; i++ )
	  {
	  	  bit_cnt = i % 8 ;
	  	  parity_bit ^= ( data[ i / 8 ] >> ( 7 - bit_cnt ) ) & 0x01; 
	  }	  
	  weigan36_odd_data = parity_bit ;
	  wdt_reset( );
#ifdef WDT
    WatchDog_Feed( );
#endif  
	  parity_bit = 0;               //If use even parity check , this bit must be 0;
	  for ( i = 17 ; i < 32 ; i++ )
	  {
	      bit_cnt = i % 8;
	      parity_bit ^= ( data[ i / 8 ]	>> ( 7 - bit_cnt ) ) & 0x01;
	  }
	  weigan36_even_data = parity_bit;
	  wdt_reset( );
#ifdef WDT
    WatchDog_Feed( );
#endif	  
	  if ( weigan36_odd_data )                    //Send O bit;
	  	  Send_Weigan1();
	  else
	  	  Send_Weigan0();
	  for ( i = 0 ; i < 32 ; i++ )                //Send CCCC CCCC CCCC CCCC CCCC CCCC CCCC CCCC;
	  {
	      bit_cnt = i % 8 ;
	      if ( ( data[ i / 8 ] >> ( 7 - bit_cnt ) ) & 0x01 )   // MSBit is sent first;
	      	  Send_Weigan1();
	      else
	      	  Send_Weigan0();	
	  }
	  Send_Weigan0();                             //Send I bit;           
	  Send_Weigan0();                             //Send I bit;
	  if ( weigan36_even_data )                   //Send E bit;
	  	  Send_Weigan1();
	  else
	  	  Send_Weigan0();   
}

// ********************************************************************************************
// Description : Send weigan44 model and encode according to weigan44 protocol.
// Return value: None.   
// parameter   : * data -- the point of the data to be encoded.
// ********************************************************************************************

void Send_Weigan44( uint8_t * data )
{
	  uint8_t i , bit_cnt , weigan44_low_byte = 0;
	  for ( i = 0 ; i < 40 ; i += 4 )
	  {
	  	  bit_cnt = i % 8;
	  	  weigan44_low_byte ^= ( data[ i / 8 ] >> ( 4 - bit_cnt ) ) & 0x0F ;
	  }
	  wdt_reset( );
#ifdef WDT
    WatchDog_Feed( );
#endif  
	  for( i = 0 ; i < 40 ; i++ )         //Send CCCC CCCC CCCC CCCC CCCC CCCC CCCC CCCC CCCC CCCC;                        
	  {
	      bit_cnt = i % 8;
	      if ( ( data[ i / 8 ] >> ( 7 - bit_cnt ) ) & 0x01 )
	      	  Send_Weigan1();
	      else
	      	  Send_Weigan0(); 	
	  }
	  for( i = 4 ; i < 8 ; i++ )          //Send XXXX ;
	  {
	      bit_cnt = i % 8;
	      if( ( weigan44_low_byte >> ( 7 - bit_cnt ) ) & 0x01 )    
	      	  Send_Weigan1();
	      else
	      	  Send_Weigan0();	
	  }
}




void Send_Weigan1( void )
{
	  sbi( PORTB , WEIGAN_1 );
	  Delayus( 100 );
	  cbi( PORTB , WEIGAN_1 );
	  Delayus( 1500 );
    wdt_reset( );
#ifdef WDT
    WatchDog_Feed( );
#endif	  
}

void Send_Weigan0( void )
{
	  sbi( PORTB , WEIGAN_0 );
	  Delayus( 100 );
	  cbi( PORTB , WEIGAN_0 );
	  Delayus( 1500 );
	  wdt_reset( );
#ifdef WDT
    WatchDog_Feed( );
#endif	  
}

void Send_9600( uint8_t * data )
{
    uint8_t i , temp , check_data;
    SendByte( 0x7E );        //SOF;
//    SendByte( 0x30 );        //address always is 0x01;
//    SendByte( 0x31 );
    SendByte( 0x30 );        //address always is 0x01;
    SendByte( 0x30 );
    SendByte( 0x30 );        //address always is 0x01;
    SendByte( 0x30 );        
//    check_data = 0x01;
    for ( i = 0 ; i < 5 ; i++ )
    {
//    	  check_data ^= weigan_data[ i ];
    	  temp = weigan_data[ i ] >> 4 ;
    	  if ( temp <= 0x09  )
    	  	  SendByte( 0x30 + temp );
    	  else if ( temp <= 0x0F )
    	  	  SendByte( 0x37 + temp );
    	  temp = weigan_data[ i ] & 0x0F ;
    	  if (  ( temp <= 0x09 ) )
    	  	  SendByte( 0x30 + temp );
    	  else if ( temp <= 0x0F )
    	  	  SendByte( 0x37 + temp );    	  	  
    }    
/*    temp = check_data >> 4 ;            //Send check_data,this value is former 6 byte XOR value;
    if ( ( temp <= 0x09 ) )
    	  SendByte( 0x30 + temp );
    else if ( temp <= 0x0F )
    	  SendByte( 0x37 + temp );
    temp = check_data & 0x0F ;
    if ( ( temp <= 0x09 ) )
    	  SendByte( 0x30 + temp );
    else if ( temp <= 0x0F )
    	  SendByte( 0x37 + temp );     
*/
    SendByte( 0x0D );        //EOF;
    SendByte( 0x0A );        //EOF;
    
//    for ( i = 0 ; i < 5 ; i++ )
//        SendByte( data[ i ] );	
}

⌨️ 快捷键说明

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