this is modified example.
/*
* Project name
RFiD (Displaying CRC check of RFid card via Usart)
* Copyright
(c) mikroElektronika, 2010.
* Revision History
20091220:
- initial release;
20101021:
- added active comments, sbit approach, code reorganized...
* Description
The code demonstrates using two external interrupts to read data sent
by EM4095 chip (clock - RDY/CLK; data - OUT).
Upon correct identification of the card, results are displayed via USART
along with the card specific number.
* Test configuration:
MCU: PIC18F4520
http://ww1.microchip.com/downloads/en/D ... 39631E.pdf
Dev.Board: EasyPIC6
http://www.mikroe.com/eng/products/view ... nt-system/
Oscillator: HS-PLL, 32.0000 MHz
Ext. Modules: mE RFid Reader Board
ac:RFid_reader
http://www.mikroe.com/eng/products/view ... der-board/
SW: mikroC PRO for PIC
http://www.mikroe.com/eng/products/view ... o-for-pic/
* NOTES:
- mE RFid Reader Board should be connected to PORTB
- Make sure you turn on the apropriate switches to enable USART communication (board specific)
- Upon correct CRC check program will send "CRC CHECK OK!" via USART
- Usage of P18 family of MCUs and clock setting >= 32 MHz is recommended when working with RFid Reader Board
*/
// Lcd module connections
sbit LCD_RS at LATD4_bit;
sbit LCD_EN at LATD5_bit;
sbit LCD_D4 at LATD0_bit;
sbit LCD_D5 at LATD1_bit;
sbit LCD_D6 at LATD2_bit;
sbit LCD_D7 at LATD3_bit;
sbit LCD_RS_Direction at TRISD4_bit;
sbit LCD_EN_Direction at TRISD5_bit;
sbit LCD_D4_Direction at TRISD0_bit;
sbit LCD_D5_Direction at TRISD1_bit;
sbit LCD_D6_Direction at TRISD2_bit;
sbit LCD_D7_Direction at TRISD3_bit;
// End Lcd module connections
sbit OUT at RB0_bit;
sbit RDY_CLK at RB1_bit;
sbit SHD at RB2_bit;
sbit MOD at RB3_bit;
sbit OUT_Direction at TRISB0_bit;
sbit RDY_CLK_Direction at TRISB1_bit;
sbit SHD_Direction at TRISB2_bit;
sbit MOD_Direction at TRISB3_bit;
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
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 Interrupt() {
// This is external INT1 interrupt (for sync and sample)
// it is enabled until we get 128 data bits
if (INT1IF_bit && INT1IE_bit) {
cnt++; // count interrupts on INT1 pin (RB1)
INT1IF_bit = 0;
}
// This is external INT0 interrupt (for sync start)
// - once we get falling edge on RB0 we are disabling INT0 interrupt
else if (INT0IF_bit && INT0IE_bit) {
cnt = 0;
sync_flag = 1;
INT0IF_bit = 0;
INT0IE_bit = 0;
INT1IF_bit = 0;
INT1IE_bit = 1;
}
}
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.B0 != row_check[4].B0) {
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.B0 != column_check[10].B0) {
return 0;
}
column_count++;
}
// end column parity check
if (bit_array[63] == 1) {
return 0;
}
return 1;
}
// main program
void main() {
ANSELB = 0; // Configure AN pins as digital I/O
ANSELD = 0;
C1ON_bit = 0; // Disable comparators
C2ON_bit = 0;
OUT_Direction = 1;
RDY_CLK_Direction = 1;
SHD_Direction = 0;
MOD_Direction = 0;
SHD = 0;
MOD = 0;
UART1_Init(19200); // Initialise USART communication
Delay_ms(100);
sync_flag = 0; // sync_flag is set when falling edge on RB0 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
// setup interrupts
INTEDG0_bit = 0; // Interrupt on falling edge on RB0
INTEDG1_bit = 1; // Interrupt on rising edge on RB1
INT0IF_bit = 0; // Clear INT0IF
INT1IF_bit = 0; // Clear INT1IF
INT0IE_bit = 0; // turn OFF interrupt on INT0
INT1IE_bit = 0; // turn OFF interrupt on INT1
GIE_bit = 1; // enable GIE
while (1) {
bad_synch = 0; // set bad synchronization variable to zero
cnt = 0; // reseting interrupt counter
sync_flag = 0; // reseting sync flag
INT1IF_bit = 0;
INT1IE_bit = 0; // disable external interrupt on RB1 (for sync and sample)
INT0IF_bit = 0;
INT0IE_bit = 1; // enable external interrupt on RB0 (start sync procedure)
while (sync_flag == 0) { // waiting for falling edge on RB0
asm nop
}
while (cnt != 16) { // waiting 16 clocks on RB1 (positioning for sampling)
asm nop
}
cnt = 0;
_data[0] = OUT & 1;
for (data_index = 1; data_index != 0; data_index++) { // getting 128 bits of data from RB0
while (cnt != 32) { // getting bit from RB0 every 32 clocks on RB1
asm nop
}
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
}
}
INT1IE_bit = 0; // disable external interrupt on RB1 (for sync and sample)
if (bad_synch)
continue; // try again
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
UART1_Write_Text("CRC CHECK OK!"); // Writing of the CRC Check confirmation through USART communication
UART1_Write(13); // Cariage return (view ASCII chart)
UART1_Write(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
== 0) {
Uart1_Write('0');
}
else {
Uart1_Write('1'); // at the end of this for loop you will get a string of "0" and "1"
}
} // specific to a single RfID CARD
Lcd_Chr(1, 10, data_valid); // this is the value(card ID) i wanted to display on the lcd
UART1_Write(13); // Cariage return (view ASCII chart)
UART1_Write(10); // Line Feed (view ASCII chart)
Delay_ms(500);
}
}
}
}