[TUT] [SOFT] Using the USART - Interrupt driven serial comms

Go To Last Post
341 posts / 0 new

Pages

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
uint8_t data; 

The variable "data" is shared between the ISR and the code in main(), it must be declared volatile.

volatile uint8_t data; 

Also Bold characters

 test 

do not work in code blocks.

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

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

great.. thank you very much...
"volatile"......

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

Hi,

Great tutorial Dean!!!

But here is my problem. I'm using Peter's Fluery lib. And after compilation it returns very known warning: uart.c:322: multiple definition of `__vector_11'. I checked (in case) list of vectors in iom16.h (for my MEGA16), and they are correct but conflict is in file uart.c where there is a function:

ISR(UART0_RECEIVE_INTERRUPT)
/*************************************************************************
Function: UART Receive Complete interrupt
Purpose:  called when the UART has received a character
**************************************************************************/
{
    unsigned char tmphead;
    unsigned char data;
    unsigned char usr;
    unsigned char lastRxError;
 
 
    /* read UART status register and UART data register */ 
    usr  = UART0_STATUS;
    data = UART0_DATA;
    
    /* */
#if defined( AT90_UART )
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
#elif defined( ATMEGA_USART )
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
#elif defined( ATMEGA_USART0 )
    lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
#elif defined ( ATMEGA_UART )
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
#endif
        
    /* calculate buffer index */ 
    tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
    
    if ( tmphead == UART_RxTail ) {
        /* error: receive buffer overflow */
        lastRxError = UART_BUFFER_OVERFLOW >> 8;
    }else{
        /* store new index */
        UART_RxHead = tmphead;
        /* store received data in buffer */
        UART_RxBuf[tmphead] = data;
    }
    UART_LastRxError = lastRxError;   
}

which is collides with ISR(USART_RXC_vect) in my code. Is there way to accord this problematic dependence?

Thanks in advance for your help.
Daniel

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

Quote:

which is collides with ISR(USART_RXC_vect) in my code. Is there way to accord this problematic depen

Well you can't have two handlers for the same vector so you have to decide if you are going to handle it or are you going to let Fleury handle it - it cannot be both. The fact that you are using Fleury rather suggests that it's your own code that is pointless.

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

Quote:

The fact that you are using Fleury rather suggests that it's your own code that is pointless.

That's so true. This is my first steps in uC's programming so I'm still learning and searching for answers and confirmations of my uncertainty in writing. It's actually not writing yet. It's boils down to googling and searching parts of code and trying it and that from where my problems comes. Sorry if that question was frustrating for You, but it will helps me choose what solution should I seek to.

Greetings
Daniel

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

Quote:

Sorry if that question was frustrating for You

Most noob questions are frustrating for us :wink:, but we try to answer (perhaps with a twist) each time after grinding our teeth for a few minutes.

Welcome to AVRfreaks Daniel!

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

Quote:
grinding our teeth for a few minutes

What can I say? You should have a good dentist :P.
Ok, seriously thank You guys for Your patient, selflessness and so kind welcome in forum :). Big Bravo for AVRfreaks Team for the great job They are doing for us to make our lives easier :D!!!

Greetings
Daniel

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

Quote:
Big Bravo for AVRfreaks Team for the great job They are doing

Stay around for a possible re-evaluation, or the final crash of the site. (Not that the guys behind the site aren't ambitious. Just no money.)

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

Discussion about implementing CTS/CTS split from this thread to AVR Forum here:

https://www.avrfreaks.net/index.p...

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

The answer for this might be in here but I figured I'd bump it up because this was driving me crazy for hours. Like this tutorial, the datasheet for the 8515 says that the USART RX complete handler is named "USART_RXC" however in "iom8515.h" it's actually defined as "USART_RX"

So if your following the tutorial from page one and you are ripping your hair out because it compiles but the interrupts never work make sure you change your ISR to be

ISR(USART_RX_vect){
//interrupt stuff
}

as a side note for any other beginners using the vector address number in the datasheet will work as well like this:

ISR(_VECTOR(9)){

}

while the second method isn't as nice it gets the job done

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

You would've torn out less hair if you'd paid attention to the warning about a misspelled (ISR ) handler . :wink:

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

Hey! :)

I'm reading through the previous thread (half done), and I'll read this through too. Now I have to leave my computer, and have a problem what for I didnt find the solution yet.

I can send data from my avr to the PC, but I cant send data from my PC to the avr via USART.

I have a flashing led driven by an overflow interrupt, and if I type something to hyperterminal the flashing stops, and the character not returned to the screen either, so nothing happens, and looks like the program on the avr stoped?

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

Sounds like you might have a blocking poll loop in an ISR. Of course we can only guess without seeing code. BTW this thread isn't really for diagnosing implementation issues - only for discussing improvements to the tutorial in the first post. You are better off with a separate thread in AVR Forum.

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

Alright, thanks for the answer! :)

(I posted my issue here)

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

Hello
I wont to use interrupt to manage rs232 connection for receive 8 byte frames. I intend to use the counters inside ISR(USART_RXC_vect) but I don't know whether counters are clered each time a byte has been received ? How to save state of the counter increased inside ISR(USART_RXC_vect) ?
Are the variables defined in the ISR(USART_RXC_vect){} are global ?

ISR(USART_RXC_vect)
{
  uint8_t i=0; //counter for 8 bytes, how to declare and initialize in other way, because whenever a byte is received i will be 0 and this can't work
  char received_tab[8];  // table of received 8 bytes
  received_tab[i]=UDR;
  i++;  
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Use:

ISR(USART_RXC_vect)
{
  static uint8_t i=0;

the "static" means "remember the value of this variable from one call of the function to the next". In effect it makes it a global (in .bss) but continues to limit its name scope to within the function.

To be honest there's more to what you are suggesting here anyway. What happens when 'i' gets bigger than received_tab[] has been defined? What you really want is what's known as a circular buffer (also known as a ring buffer, also known as a FIFO). I was going to point you to a tutorial thread that would explain about this but I realise it is THIS thread which suggests you have not yet read all of the preceding 14 pages. Do so now.

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

You also have a problem there with received_tab being a local var. You could also make it static, but then you could not access it from outside the ISR.

Regards,
Steve A.

The Board helps those that help themselves.

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

Dear all,

When I program my ATmega328 with the code below it seems there is no echo response after I type something in putty. In putty I put the flow control of and use 8bits data and 1 stop bit. Strangely my old program worked when no interrupts were used (previous tutorial). I really don't have a clue of what I'm doing wrong... So thanks for any help!

#include               // Most basic include files
#include        // Add the necessary ones here
#include  


#define FOSC 8000000//1843200// 2000000//1843200 // clock speed
#define BAUD 9600 // baud rate
#define MYUBRR FOSC/16/BAUD-1


void USART_Init( unsigned int ubrr)
{
/*Set baud rate */
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;
/*Enable receiver and transmitter */
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
/* Set frame format: 8data, 1stop bit */
UCSR0C = (1<<USBS0)|(3<<UCSZ00);


// interrupts
UCSR0B |= (1 << RXCIE0); // Enable the USART Recieve Complete interrupt (USART_RXC)
//UCSR0B |= (1 << TXCIE0); // Enable the USART Transmit Complete interrupt (USART_TXC)

sei();
//USART_Transmit('b');

}
 

void USART_Transmit( unsigned char data )
{
/* Wait for empty transmit buffer */
while ( !( UCSR0A & (1<<UDRE0)) )
;
/* Put data into buffer, sends the data */
UDR0 = data;
}


unsigned char USART_Receive( void )
{
/* Wait for data to be received */
while ( (UCSR0A & (1<<RXC0))==0 )
;
/* Get and return received data from buffer */
return UDR0;
}

ISR(USART0_RX_vect) //trigger interrupt when uart receives data 
	{ 
	// Code to be executed when the USART receives a byte here
	char ReceivedByte; 
	ReceivedByte = UDR0; // Fetch the recieved byte value into the variable "ByteReceived" 
	USART_Transmit(ReceivedByte);
	
	UDR0 = ReceivedByte; // Echo back the received byte back to the computer 
	
	}

int main(void){
	
	USART_Init(MYUBRR);
	while (1)
	{
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
/* Set frame format: 8data, 1stop bit */
UCSR0C = (1<<USBS0)|(3<<UCSZ00); 

The comment does not match the code.

Quote:
When I program my ATmega328

ISR(USART0_RX_vect) 

Why do you ignore the warnings of the compiler? Don't do it!

And last but not least:
Don't post "my code does not work" questions in the tutorial forum, and use the code tags.

Stefan Ernst

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

Quote:
And last but not least:
Don't post "my code does not work" questions in the tutorial forum
Read the "posting guidelines" in the sticky section of the forum's main page . EVERY forum has one .

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

Hy I have a problem with intrerupt when reception is complete.This is the code:

#include "avr/io.h"
#include "avr/interrupt.h"




#define FOSC 8000000// Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1

unsigned char c;
int contor = 0;
char jumper[]="clock";
int CLOCK = 0;
int ALARM = 0;
int STOP_WATCH =0;


void USART_Init( unsigned int ubrr );
unsigned char USART_Receive();
void USART_Transmit(unsigned char data);

void Timer_Init();

void clock();


ISR(USART1_RX_vect)
{
	
USART_Transmit( 58 );
}


ISR(TIMER0_COMP_vect)
{
	contor++;
	if(contor >= 100)
	{
		CLOCK++;
		contor =0;
		
		if(strcmp(jumper,"clock")==0)
		clock();
		else
		alarm();
	}
	
}




int main( void )
{
	sei();
	USART_Init ( MYUBRR );
	Timer_Init();
	while(1)
	;

}

void clock()
{
	strcpy(jumper,"clock");
	int CHour = CLOCK / 3600;
	int CMin = CLOCK%3600/60;
	int CSec = CLOCK%3600%60;
	
	USART_Transmit(12);
	USART_Transmit((unsigned char)(CHour/10 + 48 ));
	USART_Transmit((unsigned char)(CHour%10 + 48 ));
	USART_Transmit(58 );
	USART_Transmit((unsigned char)(CMin/10 + 48 ));
	USART_Transmit((unsigned char)(CMin%10 + 48 ));
	USART_Transmit(58 );
	USART_Transmit((unsigned char)(CSec/10 + 48 ));
	USART_Transmit((unsigned char)(CSec%10 + 48 ));
}

void alarm()
{
	strcpy(jumper,"alarm");
	int AHour = ALARM / 3600;
	int AMin = ALARM%3600/60;
	int ASec = ALARM%3600%60;
	
	USART_Transmit(12);
	USART_Transmit((unsigned char)(AHour/10 + 48 ));
	USART_Transmit((unsigned char)(AHour%10 + 48 ));
	USART_Transmit(58 );
	USART_Transmit((unsigned char)(AMin/10 + 48 ));
	USART_Transmit((unsigned char)(AMin%10 + 48 ));
	USART_Transmit(58 );
	USART_Transmit((unsigned char)(ASec/10 + 48 ));
	USART_Transmit((unsigned char)(ASec%10 + 48 ));
}


void USART_Init( unsigned int ubrr )
{
UCSR1B = 0b10011000;
UCSR1C = 0b00001110;
UBRR1H = 0;
UBRR1L = ubrr;
sei();
}



void Timer_Init()
{
	TCCR0 = 0b00011111;
	OCR0 = 77;
	TIMSK = 0b00000010;
}



void USART_Transmit( unsigned char data )
{
while ( !( UCSR1A & (1<<UDRE1)) ) // asteapta pana transmisia este completa
;
UDR1 = data;  // trimite caracterul spre terminal
}


unsigned char USART_Receive( void )
{
while ( !(UCSR1A & (1<<RXC1)) )  // asteapta pana receptia este completa
;
return UDR1;	//returneaza caracterul primit de la terminal
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I have a problem

(a) this thread exists simply to improve the article in the first post - not to diagnose every last UART problem people have

(b) how on God's green earth do you expect anyone to be able to help when you don't say what the "problem" actually is

(c) BTW system header includes should be <> not ""

(d) this is almost totally meaningless:

UCSR1B = 0b10011000;
UCSR1C = 0b00001110; 

Why don't you use symbolic names?

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

Quote:
Quote:

I have a problem

(a) this thread exists simply to improve the article in the first post - not to diagnose every last UART problem people have

(b) how on God's green earth do you expect anyone to be able to help when you don't say what the "problem" actually is

(c) BTW system header includes should be <> not ""

(d) this is almost totally meaningless:
Code:
UCSR1B = 0b10011000;
UCSR1C = 0b00001110;

Why don't you use symbolic names?

1. I am so sorry that I have posted here but I am so angry that this (code) is not working.

2.If I said that I have a problem when reception is complete that means that's the problem.That reception doesn't work which means that everytime when I press a key nothing happens.(I wrote that "USART_Trasmit(58)" in Interrupt Service Routine to see on the screen ":" when I press any key - to check if it work,if it entry in that ISR).

3.doesn't matter if you put <> or "" for headers.

4.UCSR1B = 0b10011000;
UCSR1C = 0b00001110;
Let me eplain this:
UCSR1B = (1 << RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
*Enable the USART Recieve Complete ,Enable receiver and transmitter

UCSR1C = (1 << USBS)|(1<<UCSZ11)|(1<<UCSZ10);
*2 stop bits ,frame dimension 8 bits

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

Quote:

3.doesn't matter if you put <> or "" for headers.

Try not to be an idiot.

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

Quote:
Let me eplain this:
UCSR1B = (1 << RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
*Enable the USART Recieve Complete ,Enable receiver and transmitter

UCSR1C = (1 << USBS)|(1<<UCSZ11)|(1<<UCSZ10);
*2 stop bits ,frame dimension 8 bits

If you had written that in your original code, then you wouldn't have had to "explain" it.

Regards,
Steve A.

The Board helps those that help themselves.

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

im kinda doing a small project- Chat hosting using UART0 and UART1 for chatting between two PC's.
I have got the duplex communication working..that is transmitting and receiving at the same time from both the Pc's. I have used interrupts for it.But i want to make it look like a proper chat like

Comp1 Comp2

User1:hi! User1:hi!
User2:hey! User2:hey!

can anyone give me some ideas on how to modify this code please.

Attachment(s): 

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

#include
#include
#include "uart.h"

volatile unsigned char read;

ISR(UART0_RX_vect)
{
read=UDR0;
uart1_tx_char(read);
}

ISR(UART1_TX_vect)
{
read=UDR1;
uart1_tx_char(read);
uart0_tx_char(read);
}

int main()
{
sei();
uart1_init();
uart0_init();
uart1_tx_string("\t\t\tCHAT\n\n");
while(1);
return 0;
}

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

When I try to compile your code, AVRStudio tells me that all the USART variables are undeclared.
I'm using the newest version of WinAVR and AVRStudio 4.19 with the latest tool chain. Any ideas?

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

The above code needs #include in the 1st line at least or the compiler doesn't know what you are talking about.

It may be best to start another thread rather than posting here.

A moderator who has access to this forum may be able to split your post.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

I figured it out, since my uC has two USART's, I had to change the definitions to UCSR0L and so on.

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

@AutoItKing: If this is about the code in the original post, i.e. the tutorial proper, then please understand that different AVR models have different names for e.g. the UART registers. You will need to correct the code to use the names that is in the data sheet for your AVR model.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

Note I've added the following paragraph to the end of the first post:

Quote:
Please note that the names of the registers and bits for the UART(s) in the AVR you are using may be different from those shown above. In place of UDR, UBRRH, UCSRA etc. you may find they are called UDR0 (or UDR1), UBRR0H, UCSR0A and so on.

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

hello and tanks for your helpful posts

i use atmega32 for my project
and paste your code in atmel studio 6 to use Usart interrupt.

but interrupt dose not working.
is three any part of the code that must change in atmega32?

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

I believe it should just work on the MEGA32. What are your connections (include a schematic if possible) and did you use the very last code sample in the tutorial?

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

thanks for your help
i think the problem can be from clock,
how can i can config fuze bit in atmel studio?

in bascom we have "$crystal= 8000000" for declare clock frequency
how can do this in atmel studio?

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

There are two things you must do:

1. Make sure the clock selection fuses are programmed correctly - you do this in the programming dialogue in Atmel Studio. And of-course you actually attach the external clock if that is what you've programmed the fuses to. CAUTION: Mis-programming the fuses might render your AVR seemingly dead - in reality it is not, but the actions to resurrect it from it's non-responsiveness might require extra hardware that you might not have.

2. Tell the compiler what speed the AVR is running at by defining the macro F_CPU.

If your AVR is running off the default internal RC oscillator at nominally 1 MHz then you'd define F_CPU to 1000000UL. You can do this directly in the source code, but as sopn as you have more than one source file it makes sense to rather do this in the project settings in Atmel Studio.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

I check the Interrupt by bascom and its working

i use this code in atmel studio and its not working:

#include 
#include 
#include 


#define F_CPU 8000000
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)


int main (void)
{
	DDRA=255;
	//UCSRB |= (1 << RXEN) | (1 << TXEN);   // Turn on the transmission and reception circuitry
	UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes

	UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
	UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
	UCSRB |= (1 << RXCIE); 
	//UDR=255;
	

	for (;;) // Loop forever
	{
		delay_ms(1000);
		PORTA+=1;
		delay_ms(1000);
		PORTA+=1;
		// Do nothing - echoing is handled by the ISR instead of in the main loop
	}
}

ISR(USART_RXC_vect)
{
	char ReceivedByte;
	ReceivedByte = UDR; // Fetch the received byte value into the variable "ByteReceived"
	UDR = ReceivedByte; // Echo back the received byte back to the computer
	PORTA=0;
}

[/code]

Last Edited: Mon. Dec 17, 2012 - 06:31 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Aha, you used the code from earlier in the tutorial, which is intentionally broken (the text explains why). You need to use the last code sample from the tutorial for it to work, which enables global interrupts.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

thanks

there are many codes in this topic
would you submit the right code again?

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

It's the final version in Chapter 5 here:

http://deans-avr-tutorials.googl...

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

tanks for you help

its working now

tanks a lot

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

hello again

1.is there any include file which has entire functions of usart ?(like read line, write line, handshaking , parity,...)

2.i want to interrupt occur when 8 byte received. is this possible?

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

Quote:

i want to interrupt occur when 8 byte received. is this possible?

If you're saying that you want the USART to receive characters and store them internally until it has 8 ones, and only then generate an interupt: No. The USART has a buffer for one character. Time to re-read the USART section of your data sheet.

You will need to get every character, one by one, and store them yourself. You get an interrupt for each received character, and in the ISR you get the one character out of the USART and store it in some buffer you have created.

I know this thread is long, but if you browse though all 25 pages of it you will find that most questions has already been ased and answered.

Quote:
.is there any include file which has entire functions of usart ?(like read line, write line [...]

"Read line" and "write line" are not functions of a USART. They might be functions of a standard programming language and it's run time library - and then often generic, so you need to "attach" some character I/O peripheral to them in some way. In C those functions are called gets() and puts(), they work on the streams stdin and stdout, and those streams needs to be "attached" to the USART. Not a trivial thing, but not overly complicated either. You need to read the documentation here: http://www.nongnu.org/avr-libc/u... . (All this assumes you are using the AVR-GCC/AVRLIBC tool chain that comes with Atmel Studio 6.)

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

hello

in the serial interrupt sub how can catch more than one byte, like 4 bytes?

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

You can't - you get one byte per interrupt raised. Instead you need to buffer the bytes you receive and process them once you have a "sufficient" amount.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

I am trying to figure out how to use various ISR. In my code, i'm transmitting a sentence repeatedly over UART, and on every transmission complete, the USART_TXC interrupt will toggle PINC0 on atmega16. my transmission is successful, however the pin is not toggled. Whats have I done wrong. Below is my code. Thanks in advance.


#define F_CPU 1000000

#define BAUD 4800
#define MYUBRR (F_CPU/16/BAUD)-1


#include 
#include 
#include 
#include 


void USART_Init( unsigned int ubrr);
void USART_Transmit(char data );






int main(void)
{
	
	DDRC |= (1<<PINC0);
	sei();
	USART_Init (MYUBRR);

	char mystring[] = "sample string";
	int i;
	while(1)
	{
		for(i=0;i>8);
	UBRRL = (unsigned char)ubrr;
	
	UCSRB |= (1<<TXEN)|(1<<TXCIE);
	
	
	UCSRC |= (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0); 
}



void USART_Transmit(char data )
{
	while ( !( UCSRA & (1<<UDRE)) );
	UDR = data;
	
}

ISR (USART_TXC_vect)
{
	PORTC ^= (1<<PINC0);
}

Last Edited: Wed. Jun 19, 2013 - 09:49 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Since your application is always loading data into the UDR register, the transmission never completes from the USART's perspective.

The USART has a hardware double buffer, so you can load in the next character before the last one has completed. This gives you the UDR flag. Once all data has been transmitted and the hardware double buffer is empty, you get the TXC flag. Since your application never allows all the data to completely shift out before loading in the sentence the next time, the TXC interrupt never fires.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

noob need help :
what the different using this and using

printf

any disadvantage? because that code is so simple

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

printf do not automagically send its output to the serial port / UART.

You will have to write code that does that, and plug it into the back of the stdout file handle.

The code you write can either be interrupt driven or not.

Depending on how you configure it, printf can be more or less hungry for code memory and CPU cycles. In general, convenience in application code often comes with a cost in memory and/or run time.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

JohanEkdahl wrote:
printf do not automagically send its output to the serial port / UART.

You will have to write code that does that, and plug it into the back of the stdout file handle.

The code you write can either be interrupt driven or not.

Depending on how you configure it, printf can be more or less hungry for code memory and CPU cycles. In general, convenience in application code often comes with a cost in memory and/or run time.

thank you, if less code memory, at least that code need a cycle to call the code that plug in the back of the stdout file, right?

Pages