USART interrupt using in a dynamic way (UQEnd,UQFront)

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am using these library files on my project using ATMEGA32. Its working fine.

When I am trying to understand the following lines of code:

-------------------------------------------

if(((UQEnd==RECEIVE_BUFF_SIZE-1) && UQFront==0) || ((UQEnd+1)==UQFront))
	{
		//Q Full
		UQFront++;
		if(UQFront==RECEIVE_BUFF_SIZE) UQFront=0;
	}
	

	if(UQEnd==RECEIVE_BUFF_SIZE-1)
		UQEnd=0;
	else
		UQEnd++;


	URBuff[UQEnd]=data;

	if(UQFront==-1) UQFront=0;

-------------------------------------------------

I didn't recognize clearly.

In searching GOOGLE I have found the following answer:
-------------------
it's clear that there's a receive array URBuff[] with a size of RECEIVE_BUFF_SIZE and it appears to have read and write pointers called UQFront and UQEnd. New characters are written to the circular buffer at UQEnd (the write pointer) and when it wraps off the end of the array it is set back to the start (hence circular). It moves the read pointer on by one if the write pointer catches the read pointer (losing one buffered character).
----------------------------------------

If anyone help me to understand then it will be a great pleasure for me.

Here is the full USART.h and USART.c file:
---------------USART.h file----------------------

#include 

#ifndef USART_H
#define USART_H


//Macros
#define RECEIVE_BUFF_SIZE 64
#define USART_RXC_VECT USART_RXC_vect	//This change from mcu to mcu. This is for mega8, mega16, mega32

//#define F_CPU 12000000UL

//#define UBRR_VALUE(baud) ((F_CPU/(baud<<4))-1)

////////////////////////////
#define FOSC 16000000                       // Clock Speed
#define BAUD 19200
#define UBRR_VALUE FOSC/16/BAUD -1

///////////////////////////

//Varriables
volatile char URBuff[RECEIVE_BUFF_SIZE];	//USART Receive Buffer
volatile int8_t UQFront;
volatile int8_t UQEnd;

//Functions
void USARTInit(uint16_t ubrrvalue);

uint8_t UDataAvailable();

char UReadData();
void UWriteData(char data);

void UWriteString(char *str);

void UReadBuffer(void *buff,uint16_t len);
void UFlushBuffer();



#endif

----------------------------------

------------USART.c file-------------------

#include 
#include 
#include 

#include "usart.h"

void USARTInit(uint16_t ubrrvalue)
{
	//Setup q
	UQFront=UQEnd=-1;

	//Set Baud rate
	UBRRH=(unsigned char)(ubrrvalue>>8);
	UBRRL=(unsigned char)ubrrvalue;

	/*Set Frame Format
	
	Asynchronous mode
	No Parity
	1 StopBit
	char size 8

	*/

	UCSRC=(1<<URSEL)|(3<<UCSZ0);//32
	
	
	//UCSR0C |= (1 << UCSZ01) | (1 << UCSZ00);    // Set frame: 8data, 1 stp
	
	
	//UCSR0C = (3<<UCSZ00);//328p
	//UCSR0C |= (1 << UCSZ01) | (1 << UCSZ00);    // Set frame: 8data, 
	
	//UCSR0C =(1<< URS)
	/*Enable Interrupts
	RXCIE- Receive complete
	UDRIE- Data register empty

	Enable The recevier and transmitter

	*/

	UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN);//32
	
	
	//UCSR0B |= (1 << RXEN0) | (1 << TXEN0);      // Enable receiver and transmitter
	//UCSR0B |= (1 << RXCIE0);                    // Enable reciever int
	
	sei();

}

//The USART ISR
ISR(USART_RXC_VECT)
{
	//Read the data
	char data=UDR;

	//Now add it to q

	if(((UQEnd==RECEIVE_BUFF_SIZE-1) && UQFront==0) || ((UQEnd+1)==UQFront))
	{
		//Q Full
		UQFront++;
		if(UQFront==RECEIVE_BUFF_SIZE) UQFront=0;
	}
	

	if(UQEnd==RECEIVE_BUFF_SIZE-1)
		UQEnd=0;
	else
		UQEnd++;


	URBuff[UQEnd]=data;

	if(UQFront==-1) UQFront=0;

}

char UReadData()
{
	char data;
	
	//Check if q is empty
	if(UQFront==-1)
		return 0;
	
	data=URBuff[UQFront];
	
	if(UQFront==UQEnd)
	{
	//If single data is left
	//So empty q
	UQFront=UQEnd=-1;
	}
	else
	{
		UQFront++;

		if(UQFront==RECEIVE_BUFF_SIZE)
		UQFront=0;
	}

	return data;
}

void UWriteData(char data)
{
	//Wait For Transmitter to become ready
	//while(!(UCSR0A & (1<<UDRE0)));//328p
	while(!(UCSRA & (1<<UDRE)));//32
	//Now write
	UDR=data;
}

uint8_t UDataAvailable()
{
	if(UQFront==-1) return 0;
	if(UQFrontUQEnd)
		return (RECEIVE_BUFF_SIZE-UQFront+UQEnd+1);
	else
		return 1;
}

void UWriteString(char *str)
{
	while((*str)!='\0')
	{
		UWriteData(*str);
		str++;
	}
}

void UReadBuffer(void *buff,uint16_t len)
{
	uint16_t i;
	for(i=0;i0)
	{
		UReadData();
	}
}

------------------------------------

Attachment(s): 

Last Edited: Thu. Apr 10, 2014 - 09:02 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In the past 3 years since you have been a member did you ever read this? :wink:
https://www.avrfreaks.net/index.p...

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's a classic circular buffer or queue. Easy to simulate using a pencil and paper. Draw ten boxes on a horizontal line. You have two pointers - the head and tail. The head is used to determine where to put the next char in, the tail points to the next char to pull out. If you go past the end of the table, you go vack to the start - thus 'circular'.

Net result is the rx interrupt puts the chars in and your code can remove chars at it's leisure so long as you dint receive more than you remove. Also known as an elastic buffer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

js wrote:
In the past 3 years since you have been a member did you ever read this? :wink:
https://www.avrfreaks.net/index.p...

Thanks a lot. Now code is formatted.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0