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

📄 mifare_tx_rx_c_2.c

📁 Build your own RFID reader with the http://www.elektor.es/ schematic. It works great with tag MiFare
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <avr/io.h>
#include <avr/pgmspace.h>

#define F_CPU 13560000UL // 1 MHz
#include <util/delay.h>
#include "lcd.h"


// EXPERIMENTAL MIFARE RFID READER
// Date: 31.th July 2006
// M. Ossmann
// built using WINAVR-GCC  c-compiler under AVR-STUDIO

int uart_putc(unsigned char c)
{
    while (!(UCSRA & (1<<UDRE))); /* warten bis Senden moeglich */
    UDR = c;                      /* sende Zeichen */
    return 0;
}


/* puts ist unabhaengig vom Controllertyp */
void uart_puts (char *s)
{
    while (*s)
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
        uart_putc(*s);
        s++;
    }
}

void uart_blank(){
	 uart_putc(' ') ; }

void uart_crlf(){
	 uart_putc(13) ; uart_putc(10) ;}

void decout(int k){
 uart_putc(32) ;
  uart_putc( ((k/100) % 10)+48 ) ;
  uart_putc( ((k/10) % 10)+48 ) ;
  uart_putc( (k % 10)+48 ) ;
   uart_putc(32) ;
  }


void chr_out(uint8_t v){
   uart_putc(v) ; }


void hex_out(uint8_t v){
 v &=0b00001111 ;
 if (v<=9) { chr_out('0'+v) ; } else { chr_out(v+'A'-10) ; } ;
 }

void byte_out(uint8_t v){
  hex_out(v>>4) ; hex_out(v) ; 
  }

void word_out(uint16_t v){
  byte_out(v>>8) ; byte_out(v) ; 
  }
  
//----------------------------------------------------------------------------------------

/* Zeichen empfangen */
uint8_t uart_getc(void)
{
    while (!(UCSRA & (1<<RXC)));  // warten bis Zeichen verfuegbar
    return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
}

uint8_t uart_getc_echo(void){
char c ;
	c=uart_getc() ;
	uart_putc(c) ;
	return(c) ;
	}

uint8_t uart_chkc(void) {
	return (UCSRA & (1<<RXC)) ;  //  Zeichen verfuegbar ?
	}

uint8_t uart_geth(){
	uint8_t c ;
	uint8_t v ;
	v=0 ;
	uart_putc('>') ;
	while(1){
		c=uart_getc_echo() ;
		if ( ('0'<=c) & (c<='9') ) { v=(v<<4) + (c-'0') ; }
		else if ( ('A'<=c) & (c<='F') ) { v=(v<<4) + (c-'A'+10) ; }
		else if ( ('a'<=c) & (c<='f') ) { v=(v<<4) + (c-'a'+10) ; }
		else { return(v) ; }
	//	uart_putc(':') ; word_out(v) ;
		} ;

}


//----------------------------------------------------------------------------------------
void LCDhex_out(uint8_t v){
 v &=0b00001111 ;
 if (v<=9) { lcd_putc('0'+v) ; } else { lcd_putc(v+'A'-10) ; } ;
 }

void LCDbyte_out(uint8_t v){
  LCDhex_out(v>>4) ; LCDhex_out(v) ; 
  }

void LCDword_out(uint16_t v){
  LCDbyte_out(v>>8) ; LCDbyte_out(v) ; 
  }

//----------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------

// see iso 14443-3-fcd annex B

uint16_t CRCreg ;

void CRCinit(){ CRCreg=0x6363 ;}


void updateCRC(uint16_t ch) {
	ch=ch ^ (CRCreg ) ;
	ch	= ch ^( ch<<4 ) ;
	ch = ch & 0x00ff ;
	CRCreg=(CRCreg>>8) ^ (ch<<8) ^ (ch<<3 ) ^ (ch>>4) ;
}

//------------------------------------------------------------------------------------

#define IObytes 220 

uint8_t IObuffer[IObytes] ;

static inline void TX_RX (){
// TXbuffer contains duration-code list terminated by 0
// the byte behind the terminating 0 is the number of sample-bytes to be recorded after TXing


	asm volatile ("  .set 	R0,0				; get register name							" ) ; 
	asm volatile ("  .set 	temp,16				; get register name							" ) ; 
	asm volatile ("  .set 	mC1,17				; get register name							" ) ; 
	asm volatile ("  .set 	mC0,18				; get register name							" ) ; 
	asm volatile ("  .set 	YL,28				; get register name							" ) ; 
	asm volatile ("  .set 	YH,29				; get register name							" ) ; 
	asm volatile ("  .set 	PORTB,24			; get port name								" ) ; 
	asm volatile ("  .set 	PINB,22				; get register name							" ) ; 


	asm volatile ("			push YH 			; save framepointer							" ) ; 
	asm volatile ("			push YL 														" ) ; 
	asm volatile ("			push temp 			; and other used registers					" ) ; 
    asm volatile ("			push mC1 														" ) ; 
	asm volatile ("			push mC0 														" ) ; 

	asm volatile ("			ldi   YL,lo8(IObuffer) 	; Y points to next byte					" ) ; 
	asm volatile ("			ldi   YH,hi8(IObuffer) 											" ) ; 

	asm volatile ("TXlp:	ld		temp,Y+		; get duration								" ) ; 
	asm volatile ("    		tst		temp		; set flags									" ) ; 
	asm volatile ("			breq	sample		; 0 = end of list							" ) ;

	asm volatile ("			push	temp		; save duration								" ) ;
	asm volatile ("			cbi		PORTB,0		; carrier switched to 0						" ) ;
	asm volatile ("			rcall	time0		; wait pause-duration						" ) ;
	asm volatile ("			sbi		PORTB,0		; switch carrier on again					" ) ;
	asm volatile ("			pop		temp		; restore duration							" ) ;
	asm volatile ("			rcall	timer		; wait duration								" ) ;
	asm volatile ("			rjmp	TXlp		; and next slot to TX						" ) ;


// sampling PINB.4
	asm volatile ("sample:	ldi		temp,250												" ) ;
	asm volatile ("			rcall	timer													" ) ;

	asm volatile ("			cbi		PORTB,1		; falling edge trigger						" ) ;

	asm volatile ("			ld		mC1,Y+ 		; sample count								" ) ;
	asm volatile ("			tst		mC1														" ) ;
	asm volatile ("			breq	ENDsample												" ) ;
	asm volatile ("			ldi		YL,lo8(IObuffer)										" ) ;
	asm volatile ("			ldi		YH,hi8(IObuffer)										" ) ;

	asm volatile ("BITlp2:	ldi		mC0,8													" ) ;

// shift bits into emp MSB first !!															" ) ;
	asm volatile ("BITlp1:	clc					; get new slot at tmp.0						" ) ;
	asm volatile ("			rol		temp		; by rotating a zero int this position		" ) ;
	asm volatile ("			sbi		PORTB,3		; signalize sampling						" ) ;
	asm volatile ("			sbic	PINB,4													" ) ;
	asm volatile ("			ori		temp,1		; conditionally set this bit				" ) ;
	asm volatile ("			cbi		PORTB,3		; stop sampling signal						" ) ;

	asm volatile ("			dec		mC0			; SAMPLE counter							" ) ;
	asm volatile ("			brne	go1			; equalize									" ) ;
	asm volatile ("			st		Y+,temp		; save complete BYTE = 8 samples			" ) ;
	asm volatile ("			dec		mC1			; BYTE counter								" ) ;
	asm volatile ("			brne	BITlp2		; restart with new BYTE						" ) ;
	asm volatile ("			rjmp	ENDsample												" ) ;
// equalize jump delay
	asm volatile ("	go1:	nop																" ) ;
	asm volatile ("			nop																" ) ;
	asm volatile ("			nop																" ) ;
	asm volatile ("			nop																" ) ;
	asm volatile ("			rjmp	BITlp1													" ) ;

    asm volatile ("time0:	ldi		temp,9 		; general timing routines					" ) ;
	asm volatile ("timer:	dec		temp													" ) ;
	asm volatile ("			brne	timer	  												" ) ;
	asm volatile ("			ret			  													" ) ;

	asm volatile ("ENDsample:   pop   mC0 		; restore registers							" ) ; 
	asm volatile ("			pop   mC1 														" ) ;
	asm volatile ("			pop   temp 														" ) ; 
	asm volatile ("			pop   YL 														" ) ; 
	asm volatile ("     	pop   YH 														" ) ; 
 }



//---------------------------------------------------------------------------------------------------------
// Receiver (RX) functions


uint16_t RXerror ;
// 1 ; half-but to bit conversion error (collision ?)
// 2 : too many ones befoer first bit
//    4 : too long string of zeroes
//    8 : too long string of zeroes
// 0x10 : parity error
// 0x20 : crc error

int SAMPLEbytePTR ;
int SAMPLEbitMASK ;

void sampleINIT(){
  SAMPLEbitMASK=0b10000000 ;
  SAMPLEbytePTR=0 ;
  }

int GETsample(){
  int bit ;
  if (SAMPLEbytePTR>=IObytes) { return (1) ; } ;					// append 1 at end of buffer	
  bit=0 ;
  if ( IObuffer[SAMPLEbytePTR] &SAMPLEbitMASK )	 { bit=1 ; } ;		// get bit from buffer
  SAMPLEbitMASK=SAMPLEbitMASK>>1 ;									// and update BitMASK
  if (SAMPLEbitMASK==0) { SAMPLEbitMASK=0b10000000 ; SAMPLEbytePTR++ ; } ;
  return(bit) ;
  } 

//---------------------------------------------------------------------------------------------------------
// half-bits to bits conversion

uint8_t RXbitBUFFER[200] ;
int BITSinBUFFER ;
int isFIRST ;

void half_bit(int b){
	if (isFIRST) { RXbitBUFFER[BITSinBUFFER]=b ; isFIRST=0 ; }
	else { if (b==RXbitBUFFER[BITSinBUFFER]) { RXerror |= 1 ; } ; 
				// uart_putc(',') ; 
				BITSinBUFFER++ ; 
				// decout(BITSinBUFFER) ; 
				isFIRST=1 ; } ;
	}

//---------------------------------------------------------------------------------------------------------
// RX samples to bits conversion

void RXsamplesTObits(int BYTESrequested){
	sampleINIT() ;
	RXerror=0 ;
	int kk ;
	for ( kk=0 ; kk<100 ; kk++) { RXbitBUFFER[kk]=0 ; } ; // erase old contents

	BITSinBUFFER=0 ;
	isFIRST=1 ;

	// skip over leading ones
	kk=0 ;
	while ( GETsample()==1 ) { 
		kk++ ; if (kk>50 ) { RXerror |= 2 ; return ; } ;
		} ;

	int BITSrequested=9*BYTESrequested+1 ;
	// first 0 found , thi is first half-bit of first bit ;
	while (BITSinBUFFER<BITSrequested) {
		kk=1 ;
  		while ( GETsample()==0 ) { 
  			kk++ ;
			if (kk>16) { RXerror |=4 ; return ; } ;
			} ;
		// decout(kk) ;
  		while(kk>2) {
			// uart_putc('b') ; 
			half_bit(1) ;  
			kk -= 4 ; }
  		kk=1 ;
  		while ( GETsample()==1 ) { 
  			kk++ ;
			if (kk>16) { 
				// uart_putc('A') ;
				half_bit(0) ;  
				if (BITSinBUFFER<BITSrequested) { RXerror |= 8 ;	return ; } ;
				if (BITSinBUFFER==BITSrequested) { return ; } ;
				}
			} ;
     	// decout(kk) ;
  		while(kk>2) {
			// uart_putc('a') ; 
			half_bit(0) ; 
			kk -= 4 ; }
 		} ;
	// uart_putc('!') ; 
	}


//---------------------------------------------------------------------------------------------------------
// bits to bytes conversion

uint8_t RXbyteBUFFER[30] ;

int BYTEerror ;

uint8_t RXbyteBUFFER[30] ;

void GETbytes(int n ){
BYTEerror=0 ;
if (RXbitBUFFER[0] !=1) { BYTEerror=1 ; return ; } ;

int theBYTE ;
int BITptr ;
int k,j ;
uint8_t b,parity ;

CRCinit() ;

BITptr=1 ;
for (j=0 ; j<n ; j++){
	theBYTE=0 ;
	parity=1 ;
	for ( k=0 ; k<8 ; k++) { 
		b=RXbitBUFFER[BITptr++] ;
		if (b) parity=1-parity ;
		theBYTE+= b<<k  ; 
		} ;
	b=RXbitBUFFER[BITptr++] ;
	if (b) parity=1-parity ;
  	// byte_out(theBYTE) ;
	RXbyteBUFFER[j]=theBYTE ;
	updateCRC(theBYTE) ;
	if ( parity ) {	
	//	uart_putc('-') ; 
		RXerror |= 0x10 ; } 
	  else { 
	//  	uart_putc('+') ; 
			}
	} ;
} 

void CRCchk(){
	if ( CRCreg !=0 ) { RXerror |=0x20 ; } ;
}

//----------------------------------------------------------------------------------------
// transmitter (TX) routines


uint8_t TXbyteBUFFER[20] ;

int TXbits ;  //Number of PAYLOAD bits
int TXzeroes ;
int TXtime ;
int TXptr ; // points to time buffer !!

//---------------------------------------------------------------------------------------------------------
// time-gap to time-element in TXbuffer conversion

#define t3 24
#define t5 46
#define t7 68


void PUTtime(){
	 // uart_putc('(') ; decout(TXtime) ;uart_putc(')') ; 
	if (TXtime<5) { 
		// uart_putc('a') ; 
		IObuffer[TXptr++]=t3 ;
		} 
	else if (TXtime>5) { 
		// uart_putc('c') ; 
		IObuffer[TXptr++]=t7 ;
		} 
	else { 
		// uart_putc('b') ; 
		IObuffer[TXptr++]=t5 ;
		} ;
	}

//---------------------------------------------------------------------------------------------------------
// x,y,z to time-gap conversion

void appendX(){
//	uart_putc('x') ;
	TXtime += 2 ;
	PUTtime() ;
	TXtime = 1 ;
	}
 
void appendY(){
//	uart_putc('y') ;
	TXtime += 4 ;
	}

void appendZ(){
//	uart_putc('z') ;
	PUTtime() ;
	TXtime = 3 ;
	}

//---------------------------------------------------------------------------------------------------------
// bit to x,y,z conversion

void TXemit(uint8_t b){
	 // uart_putc(48+b) ;
	if (b==0) { TXzeroes++ ; } else { TXzeroes=0 ; }
	if ( b==1 ) {
		appendX()  ;} 
	else {
		if (TXzeroes>1) { appendZ() ; } else { appendY() ; }
		} ;
	}

//---------------------------------------------------------------------------------------------------------
// TXbyteBuffer to times conversion


void TXconvert(uint8_t Nbytes) {
	TXptr=0 ;
	uint8_t mask=1 ;
	uint8_t parity=1 ;
//	uart_putc('T') ;
//	uart_putc('X') ;

//	uart_putc('z') ; 
	TXzeroes=2 ; // force Z-generation at start
	TXtime=3 ;

	int TXbytePTR=0 ;
	while (TXbits>0) { 
		TXbits-- ;
		if ( TXbyteBUFFER[TXbytePTR]&mask ) { 
				TXemit(1) ; parity=1-parity ; } 
			else { 
				TXemit(0) ; } ;
		mask = mask << 1;
		if (mask==0 ) { 
			mask=1 ; 
			TXbytePTR++ ; 	
			// uart_putc('p') ; 
			TXemit(parity) ; 
			// uart_putc(' ') ; 
			parity=1 ;
			} ;
		} ;
   // uart_putc('e') ; 
  TXemit(0) ;
  appendZ() ; 
  IObuffer[TXptr++]=0 ; // end of list
  IObuffer[TXptr++]=Nbytes ;
}



void appendCRC(){
	int k ;
	k=TXbits ;
	CRCinit() ;
	TXptr=0 ;
	while(k>0){
		updateCRC(TXbyteBUFFER[TXptr++]) ; 
		k -= 8 ; 
		} ;
 // uart_putc('c') ;
 // word_out(CRCreg) ;
  	TXbyteBUFFER[TXptr++]= CRCreg     & 0x00ff ;
	TXbyteBUFFER[TXptr++]=(CRCreg>>8) & 0x00ff ;
	TXbits += 16 ;
	}

//----------------------------------------------------------------------------------------

#define TRIGGER 3

void longDELAY(int d){
int k ;
	for ( k=0 ; k<d ; k++ ) {
		_delay_loop_2(6000) ;
		}
	}

void MIFAREpauseANDcharge(){

⌨️ 快捷键说明

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