📄 mifare_tx_rx_c_2.c
字号:
#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 + -