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

📄 level4.c

📁 此程序为利用mage8 AVR 和EM4094实现读取TYPE B类型卡的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 tx_number;           //received data byte number of raw data from PC;
uint8_t rx_number;

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 SendByte( uint8_t byte );
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( 1000 );
    cbi( PORTC , TEN_485 );     
}

//weigan26
//E CCCC CCCC CCCC                    CCCC CCCC CCCC O

//weigan34 
//E CCCC CCCC CCCC CCCC          CCCC CCCC CCCC CCCC O

//weigan36
//O CCCC CCCC CCCC CCCC C       CCC CCCC CCCC CCCC IIE
//I is '0';

//weigan44
//CCCC CCCC CCCC CCCC CCCC
//CCCC CCCC CCCC CCCC CCCC XXXX
//XXXX is the value of XOR of first 10 CCCC;


// ********************************************************************************************
// 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( );
	  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( );
	  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( );	  
	  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( );	    
	  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( );	  
	  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( );	  
	  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 ;
	  }
*/	
    for ( i = 0 ; i < 5 ; i++ )
        weigan44_low_byte ^= weigan_data[ i ];
    weigan44_low_byte = ( weigan44_low_byte >> 4 ) ^ ( weigan44_low_byte & 0x0F );  
	  wdt_reset( );	  
	  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 > 0 ; i-- )          //Send XXXX ;
	  {	      
	      if ( ( weigan44_low_byte >> ( i - 1 ) ) & 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;
    SendByte( 0x7E );        //SOF;
    SendByte( 0x30 );        //address always is 0x01;
    SendByte( 0x30 );
    SendByte( 0x30 );
    SendByte( 0x30 );
    
    for ( i = 0 ; i < 5 ; 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 );    	  	  
    } 
    SendByte( 0x0D );        //EOF;
    SendByte( 0x0A );        //EOF;
}

⌨️ 快捷键说明

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