Считыватель EM4095 RFID считывает плохую синхронизацию - PullRequest
0 голосов
/ 10 июля 2019

Я хочу связать EM4095 с микроконтроллером.Я пробовал это с arduino, оно всегда выдает ошибку bad_synch, что, по моему мнению, связано с неправильной синхронизацией синхронизации.

Подобная проблема с микроконтроллером stm32 была обнаружена и была заявлена ​​как специфическая проблема микроконтроллера.

Я пробовал подобный код на Arduino UNO (atmega328), stm32 и esp32, поэтому я не думаю, что это аппаратная проблема.Также я не могу связаться с предыдущим спрашивающим, поэтому я не смог связаться с человеком.

Как я могу отладить, чтобы найти проблему для того же самого?

Ниже приведен код для того же самого.

const int OUT = 2;
const int RDY_CLK = 3;
const int SHD = 4;

unsigned short sync_flag,       // in the sync routine if this flag is set
               one_seq,         // counts the number of 'logic one' in series
               data_in,         // gets data bit depending on data_in_1st and data_in_2nd
               cnt,             // interrupt counter
               cnt1, cnt2,      // auxiliary counters
               INTF1_bit, INTF0_bit;
unsigned short data_index;      // marks position in data arrey
char i;
char _data[256];
char data_valid[64];
char bad_synch;                 // variable for detecting bad synchronization

void counter_intr()   // INT1
{
  cnt++;                        // count interrupts on INT1 pin (RD3)
  INTF1_bit   = 0;
  // Serial.println(cnt);
}


// This is external INT0 interrupt (for sync start)
//   - once we get falling edge on RD2 we are disabling INT0 interrupt
void sync_intr()  // INT0
{
 // Serial.println("i");
 cnt = 0;
 sync_flag = 1;
 INTF0_bit = 0;
// INT0_bit = 0;
 detachInterrupt(digitalPinToInterrupt(OUT));   
 INTF1_bit = 0;
   //  INT1_bit = 1;
   attachInterrupt(digitalPinToInterrupt(RDY_CLK), counter_intr, RISING);   
}

    char CRC_Check(char *bit_array) {

char row_count, row_bit, column_count;
char row_sum, column_sum;
char row_check[5];
char column_check[11];

   // row parity check:
   row_count = 9;               // count rows
   while (row_count < 59) {
     column_count = 0;          // count columns
     while (column_count < 5) {
       row_check[column_count] = bit_array[row_count+column_count];
       column_count++;
     }
     row_bit = 0;               // count row bits
     row_sum = 0;
     while (row_bit < 4) {
       row_sum = row_sum + row_check[row_bit];
       row_bit++;
     }

     if ((row_sum&0x01) != (row_check[4]&0x01)) {
       return 0;
     }
     row_count = row_count + 5;
   }
   // end row parity check

   // column parity check
   column_count = 9;            // count columns
   while (column_count < 13) {
     row_bit = 0;               // count column bits
     row_count = 0;             // count rows
     while (row_bit < 11) {
       column_check[row_bit] = bit_array[column_count+row_count];
       row_bit++;
       row_count = row_count + 5;
     }

     row_bit = 0;               // count column bits
     column_sum = 0;
     while (row_bit < 10) {
       column_sum = column_sum + column_check[row_bit];
       row_bit++;
     }

     if (column_sum&0x01 != column_check[10]&0x01) {
       return 0;
     }
     column_count++;
   }
   // end column parity check
   if (bit_array[63] == 1) {
     return 0;
   }
   return  1;
}


void setup()
{

  pinMode(SHD,OUTPUT);
  digitalWrite(SHD,LOW);

  Serial.begin(9600);             // Initialise USART communication
  Serial.println("start");
  delay(100);

  sync_flag = 0;                // sync_flag is set when falling edge on RD2 is detected
  one_seq = 0;                  // counts the number of 'logic one' in series
  data_in = 0;                  // gets data bit
  data_index = 0;               // marks position in data arrey
  cnt = 0;                      // interrupt counter
  cnt1 = 0;                     // auxiliary counter
  cnt2 = 0;                     // auxiliary counter

  attachInterrupt(digitalPinToInterrupt(RDY_CLK), counter_intr, RISING);  // int 1
  attachInterrupt(digitalPinToInterrupt(OUT), sync_intr, FALLING);    // int 0

  INTF0_bit = 0;
  INTF1_bit = 0;

  detachInterrupt(digitalPinToInterrupt(RDY_CLK)) ;
}

void loop() 
{
//  continue:
  label:
  Serial.println("loop");

  bad_synch = 0;              // set bad synchronization variable to zero
  cnt = 0;                    // reseting interrupt counter
  sync_flag = 0;              // reseting sync flag
  INTF1_bit = 0;
  detachInterrupt(digitalPinToInterrupt(RDY_CLK))   ;           // disable external interrupt on RD3 (for sync and sample)
  INTF0_bit = 0;
  attachInterrupt(digitalPinToInterrupt(OUT), sync_intr, FALLING);              // enable external interrupt on RD2 (start sync procedure)

  while (sync_flag == 0) {    // waiting for falling edge on RD2
    // asm nop
         __asm__ __volatile__ ("nop\n\t")  ; 
   // Serial.println("a");
  }

  // while (cnt != 16) {         // waiting 16 clocks on RD3 (positioning for sampling)
  while (cnt <= 16){
    // asm nop
    __asm__ __volatile__ ("nop\n\t"); 
   // Serial.println("b");
  }

  Serial.println("cnt 16");

  cnt = 0;
  _data[0] = OUT & 1;

  for (data_index = 1; data_index != 0; data_index++) {   // getting 128 bits of data from RD2
   //  while (cnt != 32) {                                   // getting bit from RD2 every 32 clocks on RD3
      while (cnt <= 32) {
       // asm nop
      __asm__ __volatile__ ("nop\n\t"); 
      // Serial.println("c");
      }
      cnt = 0;                                              // reseting interrupt counter
      _data[data_index] = OUT & 1;                          // geting bit
      if(data_index & 1)
      if (!(_data[data_index] ^ _data[data_index-1]))
         {
            bad_synch = 1;

            break;                                          // bad synchronisation
         }
  }

  detachInterrupt(digitalPinToInterrupt(RDY_CLK));                                          // disable external interrupt on RD3 (for sync and sample)
  if (bad_synch)
  {
    Serial.println("bad_synch");
//     goto continue;                                              // try again
    goto label;
  }

  cnt1 = 0;
  one_seq = 0;
  for(cnt1 = 0; cnt1 <= 127; cnt1++) {                    // we are counting 'logic one' in the data array
    if (_data[cnt1 << 1] == 1) {
        one_seq++;
    }
    else {
        one_seq = 0;
    }

    if (one_seq == 9) {                                   // if we get 9 'logic one' we break from the loop
        break;
    }
  }                                                       //   (the position of the last  'logic one' is in the cnt1)
  if ((one_seq == 9) && (cnt1 < 73)) {                    //   if we got 9 'logic one' before cnt1 position 73
                                                            //   we write that data into data_valid array
       data_valid[0] = 1;                                   //   (it has to be before cnt1 position 73 in order
       data_valid[1] = 1;                                   //   to have all 64 bits available in data array)
       data_valid[2] = 1;
       data_valid[3] = 1;
       data_valid[4] = 1;
       data_valid[5] = 1;
       data_valid[6] = 1;
       data_valid[7] = 1;
       data_valid[8] = 1;
       for(cnt2 = 9; cnt2 <= 63; cnt2++) {                  // copying the rest of data from the data array into data_valid array
          cnt1++;
          data_valid[cnt2] = _data[cnt1 << 1];
        }
       if (CRC_Check(data_valid) == 1) {                    // if data in data_valid array pass the CRC check

           Serial.println("CRC CHECK OK!");              // Writing of the CRC Check confirmation through USART communication
            Serial.println(13);                                // Cariage return (view ASCII chart)
            Serial.println(10);                                // Line Feed (view ASCII chart)


            for (i = 0; i <= 64; i++){                      // This part of the code
                                                            //  dislays the number of the specific RfID CARD
                if (data_valid[i] == 0) {
                  Serial.print('0');
                  }
                else {
                  Serial.print('1');                         // at the end of this for loop you will get a string of "0" and "1"
                  }
            }                                               // specific to a single RfID CARD
            Serial.println(13);                                // Cariage return (view ASCII chart)
            Serial.println(10);                                // Line Feed (view ASCII chart)
            delay(500);

       }
  }
}
...