我想将EM4095与微控制器接口。我用arduino尝试过,它总是会由于错误的同步时间而产生bad_synch错误,我认为这是错误的。
Similar problem被发现带有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);
}
}
}