Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

How to read RFID tag by ATmega32 using Codevision ?

Status
Not open for further replies.
should I put the first part of the code in interrupt routine?
sth like the following code?
// USART0 Receiver interrupt service routine
interrupt [USART0_RXC] void usart0_rx_isr(void)
{
char status,data;
status=UCSR0A;
data=UDR0;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer0[rx_wr_index0]=data;
if (++rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;
if (++rx_counter0 == RX_BUFFER_SIZE0)
{
rx_counter0=0;
rx_buffer_overflow0=1;
};
};
//This is the complete String readout for the reader
void makestring(void)
{
datax[datapoint]=getchar(); //Get the next character
datapoint++;
if ((datax[datapoint-2] == 0x13) && (datax[datapoint-1] == 0x10)) //End of string is reached?
{
datax[datapoint] = 0x00; //Insert the "C" String end
lcd_puts(*datax); //Any output routine could be insert here LCD, USART or something else.
datapoint = 0; //Set Pointer to 0 for next card
}
}
 
Last edited:
The first part ( Interrupt Routine ) would be generated by the Automatic Programm Generator.
Let it like it is.

Your parameter is the rx_counter.
You should test this variable in main while(1) loop.
When > 0 a new Byte arrived and You have to do some action -> Readout and process.

E.G. When put in an LCD Output routine into Interrupt, the whole controller is blocked until the output is done.

I'm not shure that You know how it works.

The RX Interrupt get any Byte that was received via USART and save it in a Ring Buffer.

Your Job ist to readout this Buffer, evaluate the data and generate "C" compatible strings.
There are many possible way's to do this.
 
Try this out.
/*******************************************************
This program was created by the CodeWizardAVR V3.26
Automatic Program Generator
© Copyright 1998-2016 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : USART MEGA 16
Version : 0.0
Date : 07.11.2017
Author : Krug
Company :
Comments:
Test for RF01D


Chip type : ATmega16
Program type : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*******************************************************/

#include <io.h>

// Declare your global variables here

// Standard Input/Output functions
#include <stdio.h>
volatile unsigned char uc_timeout=0;
unsigned char datax[15];
unsigned char datapoint=0;

#define OVERFLOWTIME 15 //15 is about 0,5s

#define OVR 3

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART Receiver buffer
#define RX_BUFFER_SIZE 32
char rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE<256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif

// This flag is set on USART0 Receiver buffer overflow
bit rx_buffer_overflow;

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
uc_timeout++;

}

// USART0 Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer[rx_wr_index]=data;
if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
if (++rx_counter == RX_BUFFER_SIZE)
{
rx_counter=0;
rx_buffer_overflow=1;
};
};
}

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART0 Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index];
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif

//This is the complete String readout for the reader
void makestring(void)
{
datax[datapoint]=getchar(); //Get the next character
datapoint++;
if ((datax[datapoint-2] == 0x13) && (datax[datapoint-1] == 0x10)) //End of string is reached?
{
datax[datapoint] = 0x00; //Insert the "C" String end
puts(datax); //Any output routine could be insert here LCD, USART or something else.
datapoint = 0; //Set Pointer to 0 for next card
}
}


void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Port C initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRC=(0<<DDC7) | (0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTC=(0<<PORTC7) | (0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);

// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
// Mode: Normal top=0xFF
// OC0 output: Disconnected
// Timer Period: 32,768 ms
TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (1<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0<<AS2;
TCCR2=(0<<PWM2) | (0<<COM21) | (0<<COM20) | (0<<CTC2) | (0<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (1<<TOIE0);

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
MCUCSR=(0<<ISC2);

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
UCSRB=(1<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (1<<RXEN) | (1<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
UCSRC=(1<<URSEL) | (0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
UBRRH=0x00;
UBRRL=0x33;

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
SFIOR=(0<<ACME);

// ADC initialization
// ADC disabled
ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);

// SPI initialization
// SPI disabled
SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);

// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);

// Globally enable interrupts
#asm("sei")

while (1)
{
while(rx_counter>0)
{
uc_timeout=0; //Reset Timeout
makestring();
//Receive Data and generate a string
}
if(datapoint>0) //Transmission in progress ?
{
if(uc_timeout>OVERFLOWTIME) //Timeout overflown ?
{
uc_timeout=0; //Yes! Reset Timeout
datapoint=0; //Reset data pointer
}
}
else //Else waiting for new tag
{
uc_timeout=0; //Reset Timeout
}
// Place your code here

}
}
 
Every Timer0 Overflow would called the
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
routine.
In this routine the uc_timeout variable would be incremented by 1.

In this section
if(uc_timeout>OVERFLOWTIME) //Timeout overflown ?
{
uc_timeout=0; //Yes! Reset Timeout
datapoint=0; //Reset data pointer
}
}
else //Else waiting for new tag
{
uc_timeout=0; //Reset Timeout
}

the uc_timeout variable would be testet with an overflow value - In this case 15, that give You ~0,5s timeout at 8MHz clock and the current setting of timer0.
If the variable is bigger than this, the datapointer will be set to 0 and so all the saved Bytes will be thrown away.

In the other case a new byte was received, the overflow since the last byte was not achieved and the timeout variable would be set to 0 until the next byte arrives.

You could check this out with the simulator of AVR Studio 7.

Codevision has no integrated simulator.
The exchange File between this 2 solutions is the .cof File.
 
I got the tag number by gets(code,11) and when i'm trying to show it on LCD one extra character appears on (0,0) on the LCD, how can cut the desired number (just the digits written on the tag?
 
Hello, I'm here again..finally I made the code for showing rfid tag's number on lcd but I don't know how to compare it with a given number
I would suggest You to insert a learn routine into the Controller.
You'll bring the controller into a "learn mode" by pressing a Button or else method.
Then hold the new card on the reader.
The Controller read the string and store it into an EEPROM place, to make it save at power down.

In normal Mode the entire card code will be compared with the stored one's.

Old Cards can be removed manually, when defect manually by an own routine.
The Codes behind this card should be sortet new, to use the EEPROM space effective.
 
I would suggest You to insert a learn routine into the Controller.
You'll bring the controller into a "learn mode" by pressing a Button or else method.
Then hold the new card on the reader.
The Controller read the string and store it into an EEPROM place, to make it save at power down.

In normal Mode the entire card code will be compared with the stored one's.

Old Cards can be removed manually, when defect manually by an own routine.
The Codes behind this card should be sortet new, to use the EEPROM space effective.
let me explain my problem clearly
 
the 10 digits are my numbers but the first character is extra and I don't know what it is, tried to delete it but didn't work
upload_2017-12-25_20-32-8.png
upload_2017-12-25_20-32-8.png
 
the 10 digits are my numbers but the first character is extra and I don't know what it is, tried to delete it but didn't work
I think the fail ist a wrong setting of the Jumper 2 and 3 of the RF01D.
When SW 3 set to 1 the RF01D send a start Byte ( 0x02 ).
The Display interpret's that as character and display this.
Set this pin to 0 should solve that problem.

You also can eliminate that by change the first character into an other byte of ASCII code e.g. 0x20 for a space.

Or copy the String into an other without the first byte.
The length of a string You can get with the command strlen.
So copy the String from byte 1 to the end to byte 0 to an another string.

You see many way's to solve that.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top