assi…  · web viewpost subject: i wouldn't have thought you'd have time to wait for...

286
AVR Freaks AVR Tutorials - [TUT] [SOFT] Using the USART - Interrupt driven serial comms abcminiuser - Mar 30, 2007 - 09:37 AM Post subject: [TUT] [SOFT] Using the USART - Interrupt driven serial comms For an updated version of this tutorial in PDF format, please see this page of my website. Interrupt driven USARTs The following is a short extension of my previous tutorial, Using the USART - Serial communications. This tutorial will teach the basics for creating interrupt-driven USART communications. It assumes that the reader has both read and fully understood my previous tutorial on basic serial communications. Interrupts? AVRs - and almost all microcontrollers - contain a feature known as interrupts. Interrupts, as their name implies, allows for external events (such as inputs from the user or AVR peripheral) to momentarily pause the main microcontroller program and execute an "Interrupt Service Routine" (shorthand "ISR") before resuming the main program where it left off. Interrupts are extremely useful for dealing with irregular input (such as pin changes or the arrival of a serial byte), as well as for processing "background tasks" like togling a LED each time a timer overflows.

Upload: phamtram

Post on 31-Jan-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

AVR Freaks

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

abcminiuser - Mar 30, 2007 - 09:37 AM

Post subject: [TUT] [SOFT] Using the USART - Interrupt driven serial comms For an updated version of this tutorial in PDF format, please see this page of my website.

Interrupt driven USARTs

The following is a short extension of my previous tutorial, Using the USART - Serial communications. This tutorial will teach the basics for creating interrupt-driven USART communications. It assumes that the reader has both read and fully understood my previous tutorial on basic serial communications.

Interrupts?

AVRs - and almost all microcontrollers - contain a feature known as interrupts. Interrupts, as their name implies, allows for external events (such as inputs from the user or AVR peripheral) to momentarily pause the main microcontroller program and execute an "Interrupt Service Routine" (shorthand "ISR") before resuming the main program where it left off. Interrupts are extremely useful for dealing with irregular input (such as pin changes or the arrival of a serial byte), as well as for processing "background tasks" like togling a LED each time a timer overflows.

In this tutorial, we are going to make use of the AVR's USART peripheral interrupts.

A recap, our echo program

Page 2: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

From the last serial tutorial, we have created a simple program from scratch which will echo bytes received on the AVR's USART interface. The full program listing is as follows:

Code:

#include <avr/io.h>

#define USART_BAUDRATE 9600

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

int main (void)

{

char ReceivedByte;

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

for (;;) // Loop forever

{

while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR

ReceivedByte = UDR; // Fetch the received byte value into the variable "ByteReceived"

while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it

Page 3: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

UDR = ReceivedByte; // Echo back the received byte back to the computer

}

}

Readers should be able to fully understand this code - if you cannot please re-read the previous tutorial on basic serial communication.

Now, we want to extend this code so that the serial data is echoed back when received in an interrupt, rather than our main program loop. To do this, first we need to include the AVRLIBC standard library header, "avr/interrupt.h". This file contains library functions and macros which relate to the interrupt functionality of the AVR. We'll add this to the top of our code, below the "avr/io.h" header include:

Code:

#include <avr/io.h>

#include <avr/interrupt.h>

Once included, we now have a way to make our ISR to deal with the serial reception. To make an ISR, we use the syntax:

Code:

ISR({Vector Name})

{

// Code to be executed when ISR fires

}

Page 4: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

And place it in our program as if it was a normal function. To add one to deal with the reception of a byte via the USART, we need to look for the appropriate name in our AVR's datasheet. In the datasheet for our example AVR, the MEGA16, we see that the name of the interrupt for when a byte is received is "USART_RXC". The standard AVRLIBC library file "avr/io.h" - included in our program as well as any other AVR-GCC program involving the AVR's IO functionality - defines the vector names for us.

AVRLIBC's symbolic names for each of the interrupt vectors is identical to the datasheet, with the addition of a "_vect" suffix to denote that it is a vector name. So, as our datasheet listed "USART_RXC" as the vector name, the syntax for our program is:

Code:

ISR(USART_RXC_vect)

{

// Code to be executed when the USART receives a byte here

}

Which we'll place at the end of our program, after our main function. The new program looks like this:

Code:

#include <avr/io.h>

#include <avr/interrupt.h>

#define USART_BAUDRATE 9600

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

int main (void)

{

char ReceivedByte;

Page 5: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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

for (;;) // Loop forever

{

while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR

ReceivedByte = UDR; // Fetch the received byte value into the variable "ByteReceived"

while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it

UDR = ReceivedByte; // Echo back the received byte back to the computer

}

}

ISR(USART_RXC_vect)

{

// Code to be executed when the USART receives a byte here

}

Page 6: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Populating the ISR

At the moment our new USART reception ISR doesn't actually do anything - we've just defined it. We want it to echo back the byte that is sent, so we'll move our main loop code:

Code:

while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR

ReceivedByte = UDR; // Fetch the received byte value into the variable "ByteReceived"

while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it

UDR = ReceivedByte; // Echo back the received byte back to the computer

Over to it. However, we can now remove the two while loops - since the ISR only fires when a byte is received, and only one byte is sent after each reception we can guarantee that both checks are now redundant. When the ISR fires we know that there is both a byte received in the USART input buffer, as well as nothing in the output buffer. Using this knowledge, we can simplify our ISR code to the following:

Code:

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

}

Page 7: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Note that I've also moved the variable declaration of "ReceivedByte" over to the ISR, as that is now where it is actually used.

It's worth mentioning at this point a small section on the datasheet about the RXC interrupt:

Quote:

When interrupt-driven data reception is used, the receive complete routine must read the received data from UDR in order to clear the RXC Flag, otherwise a new interrupt will occur once the interrupt routine terminates.

That's important to remember - if you are using the RXC interrupt, you must read a byte from the UDR register to clear the interrupt flag. We do that in our above code, but keep it in mind for your future projects!

Enabling the USART receive interrupt

Let's take a look at the latest incarnation of our test code:

Code:

#include <avr/io.h>

#include <avr/interrupt.h>

#define USART_BAUDRATE 9600

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

int main (void)

{

Page 8: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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

for (;;) // Loop forever

{

// 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

}

If you compile and run this, you'll notice that nothing happens - no characters are echoed back to the PC. This is because although we've defined and populated the ISR, we haven't enabled it. To do so, we need to do two things:

1) Turn on global interrupts

2) Enable the USART Byte Received interrupt

Page 9: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Item one is simple, so we'll do that first. The AVR microcontrollers contain a global flag which can be set or cleared to enable or disable the handling of interrupts. Note that setting this flag doesn't enable all interrupts, it only allows for the possibility of running them. If the Global Interrupt Enable flag is disabled, all interrupts will be ignored, even if they are enabled (more on that later).

To turn on the Global Interrupt Enable flag, we can use the macro "sei()" which the "avr/interrupt.h" library helpfully defines for us. This is so named as it generates a "SEI" assembly instruction in the final code listing, which the AVR interprets as an order to set the Global Interrupt Enable flag. The compliment of "sei()" is "cli()" (to turn off the handling of interrupts) however we will not be using that macro in this tutorial.

We'll add our "sei();" instruction to our main routine, after configuring the USART registers:

Code:

// ...

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

sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed

for (;;) // Loop forever

// ...

Page 10: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Now for item 2 on our list, which needs to be performed before the interrupt will be enabled. We need to specifically enable the USART Receive Complete interrupt, which we can do by setting the appropriate flag in the USART control register.

In the MEGA16, this bit is called RXCIE (Recieve Complete Interrupt Enable) and is part of UCSRB. Setting this bit enables the handling of the USART_RXC event vector:

Code:

UCSRB |= (1 << RXCIE);

We'll add this to our main routine, before our new "sei();" command.

Putting it all together

Now we have a working interrupt driven serial example:

Code:

#include <avr/io.h>

#include <avr/interrupt.h>

#define USART_BAUDRATE 9600

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

int main (void)

{

UCSRB |= (1 << RXEN) | (1 << TXEN); // Turn on the transmission and reception circuitry

Page 11: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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 << RCXIE); // Enable the USART Recieve Complete interrupt (USART_RXC)

sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed

for (;;) // Loop forever

{

// 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

}

Which, like out original program, will echo characters received via the USART. However, because our program is now interrupt driven, we can add in code into the main loop which will be executed when data is not received - such as flashing a LED.

Page 12: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Interrupts allow for infrequent "background" tasks to be executed when they occur, without posing a run-time penalty of having to poll the hardware until the even occurs. This frees up our main loop to take care of the critical code, with the interrupt code pausing the main code to execute when the event of interest ocurs.

Interrupts should be made to be as short as possible in execution time. This is because while one ISR is executing, others are blocked and thus if another ISR condition occurs while one ISR is executing, that ISR event will be missed or delayed.

Because of this, communication ISRs are generally made short by receiving in characters via an ISR, and placing them into a buffer which the main code may read at its leisure. This ensures that received data will not be missed, while giving the main program time to complete what it is currently doing before having to process the input. Similarly, long transmissions may be made by placing the data to be sent into a buffer, and have an interrupt send the data as the hardware is ready while the main program performs other tasks.

I hope this tutorial is informative - if not please post your suggestions! I'm open to feedback, and please feel free to post your own examples, code, etc. below.

For an updated version of this tutorial in PDF format, please see this page of my website.

- Dean Twisted Evil Bitshuffler - Mar 30, 2007 - 03:45 PM

Post subject: RE: [TUT] [SOFT] Using the USART - Interrupt driven serial c Hi Dean, thanks for the great tutorial. One thing - I think the line:

Code:

Page 13: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

UCSRB |= (1 << RCXIE); // Enable the USART Recieve Complete interrupt (USART_RXC)

actually needs to use RXCIE rather than RCXIE. I have this running and it's working great in hyperterminal.

A quick question: Do you know a way to do a 'full speed' loopback test in windows? Typing isn't really stressing it at all. I'm using Artur Lipowski's USART library in a motor controller project and I'm losing the occasional character (with a 0% error clock frequency). I'd like to blast a large text file through the loopback, capture it when it gets back to the pc and then do a file compare to test for differences. ie if the avr is doing nothing but passing the character back and there are still errors I can narrow it down to some problems on my board.

Thanks again for the tutorial, it's very timely. I've been fighting with the usart for a couple of days now. much appreciated.

Update: I went away and checked and hyperterminal has a "paste to host" option that allows you to paste in a large block of text. I turned off local echo and posted in a large source file. Although this method doesn't allow an actual file compare, inspection showed that the AVR returned the text file completely intact. I guess this means there is some problem with my motor control code fighting with the code to handle the USART, although I'm not sure how.

Anyway, thanks once again for your great tutorial. I'll look at implementing a simple circular buffer based off your code and swapping my existing handler out.

Cheers

Andrew smileymicros - Mar 30, 2007 - 04:01 PM

Post subject: RE: [TUT] [SOFT] Using the USART - Interrupt driven serial c Connect your TxD pin to your RxD pin.

Smiley Bitshuffler - Mar 30, 2007 - 06:42 PM

Page 14: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Post subject: Thanks for the thought, Smiley. But I don't think that's what I need - I was sorta using the avr for the loopback, just sending stuff to the chip and trying to measure if I got exactly the same stuff back.

Actually I think I understand what's happening now.

The UART code works fine in a project that does nothing but send/recieve characters, but if I include it in the motor controller (with 5 servo motors) it drops characters.

BUT (and here's the n00b thing to watch) if the motors are disconnected there's no problem and no dropped characters. So it appears to be the motors drawing current that are causing the problems. (Typical - I'm a software guy so I think in terms of software problems. I'll just go and beat myself with a stick now. :-/ )

I've seen many schematics that put a capacitor between Supply and ground probably for this very reason. Please pardon my ignorance. Perhaps if someone could confirm I'm guessing right, and verify what to do about it it'd be great, and thanks again.

Andrew bloody-orc - Mar 30, 2007 - 07:17 PM

Post subject: "reverse" diodes on the motor lines (4 in total per motor), a 0.1uF ceramic cap as close as possible to the AVR power pins. this should minimize the motors effect on the circuit. power isolation would be the best (with optical isolation on the control signal) but i doubt you need that much of "protection".

You could also add a capacitor triangle on the motor leads (if using DC motor): cap between leads, lead1 to case, lead2 to case. also ceramic.

very OT although Wink maybe could be moved to another thread in OT or something... Bitshuffler - Mar 31, 2007 - 01:37 AM

Post subject: Thank you very much for your help (although I profess to not completely understanding what you said i can research it and work it out now you have given me a direction.) Smile

Apologies if this is off topic. I considered before posting here, but thought - if the beginner is trying to use the USART and it's dropping characters then it'd be worth highlighting this as possible cause

Page 15: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

to consider. Once again, apologies and let me know if I should delete my posts here, and thanks again. abcminiuser - Mar 31, 2007 - 04:40 AM

Post subject:

Quote:

actually needs to use RXCIE rather than RCXIE. I have this running and it's working great in hyperterminal.

Whoops! I wrote the above in response to your post, since you were having trouble (and I thought I could help others at the same time). Should have checked the datasheet more thoroughly. I'll fix that ASAP.

Sorry about the lack of polish on this one - I only had an hour in which to write it. So long as I get my main point across I suppose it's a passable tutorial Wink.

- Dean Twisted Evil Tobbe - Apr 03, 2007 - 06:53 PM

Post subject: Great tutorial. It will definitely come in handy. Thanks! I have a question though I am not entirely sure I should post it here, but I'll do so anyway. (If you want me to delete it and repost somewhere else, just ask!)

Your code works wonders if I only recieve one byte (one character) of data. But what happens if I want to recieve, let's say, 5 consecutive bytes? This probably just requires some smart C-code, but it I believe it is somewhat connected to how the AVR works too. Remember that I am a novice, but I still hope my question makes sense. Let me explain.

Let's say I want to send 5 bytes of data. Now as I see it, if I have multiple interrupts enabled in my program, they will stack them and do them one after another in the order they happened? Is that correct? So let's say that I send a byte but I am currently in another interrupt, that is when a character is sent I will not directly go to ISR(USART_RXC_vect) since another interrupt is currently beeing processed. Let's say this interrupt also takes some time. What will happen then? Will the sender just write 5 characters really fast and thus not let the AVR get a chance to read the bytes one by one. ie will only the last byte sent be read when the AVR finally goes into the ISR(USART_RXC_vect) interrupt function? Will only the last byte be in the UDR?

Page 16: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

What I am basically asking is will the AVR somehow recieve bytes into a certain buffer and not send them out to the UDR register until it has been read when receiving data? Or do I have somehow have to use the RTS/CTS flags in the RS232 protocol? (even though I have no clue how that would work anyway with this particual problem)

Thanks for any answers I might get.

Edit:

I also found a very nonsignificant error heh.

Code:

char ReceivedByte;

ReceivedByte = UDR; // Fetch the recieved byte value into the variable "ByteReceived"

should probably be:

Code:

char ReceivedByte;

ReceivedByte = UDR; // Fetch the recieved byte value into the variable "ReceivedByte"

bloody-orc - Apr 03, 2007 - 07:40 PM

Post subject: No they will not be stacked like you said. when you are in a interrupt routine all other interrupts are disabled. so you should get out if it as fast as possible.

I'll see if I can find my code on receiving more than one byte... abcminiuser - Apr 04, 2007 - 03:27 AM

Post subject: The UDR register is double buffered, I think, so you have have two pending characters in it at a time (reading one then frees up that place for the next character).

If one interrupt is executing, other interrupts that are pending will have have to wait until the current interrupt is complete. It's possible to make interrupts that are themselves interruptible, but that's an advanced topic and certain to cause problems if you don't know what you are doing.

To receive blocks of characters, you need to stuff them into a buffer inside the interrupt (to keep it short), then read those characters out later in your main routine to process them. This is commonly

Page 17: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

done in the form of a "Ring Buffer", a special type of circular buffer. You might want to Google that to find some example code (or I could PM some to you).

- Dean Twisted Evil Tobbe - Apr 04, 2007 - 11:08 PM

Post subject: Thanks for the informative answer Dean. I just have one followupquestion. bloody-orc said all other interrupts are disabled. I read that as they won't happen at all if I'm currently in another interrupt. When I read your post I read it as they will indeed stack and happen one after another, in the order they happened? Which one of thoose two statements are correct?

Also, I'd love some example code! Thanks in advance. abcminiuser - Apr 04, 2007 - 11:40 PM

Post subject: The interrupts semi-stack. What happens when an interrupt is entered, is that the global interrupt flag (allowing for the processing of pending interrupts) is disabled. Interrupt conditions can still cause other interrupt's flags to be set, however the ISRs won't fire until the currently executing ISR ends (and re-enables the global interrupt enable flag). The order of which the pending interrupts are processed once the ISR exits is dependent on the Interrupt's priority - its order in the vector table.

Each interrupt can only have its flag set once, so if two Pin Change interrupts occur (for example) while you are processing the LCD interrupt, the Pin Change ISR will only fire once when the LCD ISR completes.

Make sense?

- Dean Twisted Evil Siebesiech - Apr 05, 2007 - 10:55 AM

Post subject: Hi together

I have a similar problem but in the opposite way.

I have to dend data with a baudrate of 38400 over the rs232 to an other software.

I tried to make an interrupt on the "USART_TXC_vect" that looks like this.

Code:

(main)

sei();

Page 18: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

UCSRB |= (1 << RXEN) | (1 << TXEN) ; // Turn on the transmission and reception circuitry

(Timerroutine)

ISR(SIG_OVERFLOW1)

{

...

program

...

after initialisation the software

UCSRB |= (1 << TXCIE); // Enable the USART Transmit Complete interrupt (USART_TXC)

...

(end timerroutine)

//Interruptroutine

ISR(USART_TXC_vect)

{

sensor= ((ADCH << 8 ) | ADCL);//read value out of ADC

UDR = ((sensor<< 6)>>4)| 0x01; //send value to software

}

I tried this but it doesn't work.

Is this generally posible like this?

(I have to send with this baudrate, but parallel to sending data I've to controll the display and keys of my device(this works) in my program.)

Thanks for some help.

Stefan

Page 19: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

(I've an atmega32) abcminiuser - Apr 05, 2007 - 12:33 PM

Post subject: Please use the forum [code ] [ /code] tags (without the spaces) when posting code - it keeps the formatting and makes it easier to read. I've fixed your above post, but the indentation was eaten by the board.

You don't seem to have set up the ADC in your code. You need to do that before the ADCH/ADCL register values become valid.

Also, "sensor" isn't defined in your code. Where is it defined and what is it defined as?

The shifting and ORing of the two ADC registers creates a 16-bit value (of which only 10 bits are used), which is placed in your "Sensor" variable. However, the UDR register is only 8-bit, so you'll be loosing bits when you send them. You seem to have some weird shifting going on:

Code:

UDR = ((sensor<< 6)>>4)| 0x01; //send value to software

Equates to:

Code:

UDR = ((sensor << 2)| 0x01); //send value to software

Which means you're shifting the 10 bits to the left twice, then ORing with 0x01. That will cause bit 0 to always be one, and bit 1 to always be read as 0. Is this what you want? Also, since UDR is only 8 bit as mentioned, that value will be cast down and the upper 8 bits thrown away. So what you're actually sending is the lower 6 bits of the ADC register pair shifted left twice, and the LSB set.

- Dean Twisted Evil lfmorrison - Apr 05, 2007 - 01:07 PM

Page 20: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Post subject: One other thing to keep in mind is that there are actually two different interrupt vectors associated with the USART transmitter:

1) A "UART Data Register Empty" (UDRE) interrupt will fire continually as long as there's space in the double-buffered UDR for additional characters to be added to the hardware queue.

2) A "UART Transmit Complete" (TXC) interrupt will fire once following the completion of the final queued character.

If you design an application based solely on the TXC interrupt -- as you've done above -- you must "prime the pump" by sending the first character of a multi-byte transaction manually, and then the TXC interrupt will eventually fire when that byte is totally finished and the UART is sitting idle waiting for some more data.

I think it's easier to write software based on the UDRE interrupt instead. All you need to do in that case is populate a software buffer, then enable the UDRE interrupt source -- the hardware will take care of the rest.

In some circumstances it is appropriate to use both forms of transmitter interrupts in tandem -- for example when you don't want to have to bother with "priming the pump" so the UDRE interrupt is more convenient, but you also need to take a special action (such as switching the data direction of an RS485 transceiver) after you're certain that the final byte of a transaction has cleared the UART. Siebesiech - Apr 05, 2007 - 01:08 PM

Post subject: Sorry, perhaps i was a bit imprecise.

It works with the ADC, i didn't wrote de code above to save time and don't confuse you Wink...

I "only" have problems to get the baudrate, so that every circle has a new "Sensor"-value.

So I tried to make an interrupt with the TXCIE-Bit to know when it's ok to fill in the data to UDR (when the UDR is empty).

Or to say it in another way: when TXE-Interrupt comes, i use to write the sensor-data to UDR.

I hope you got what i mean. it's a little bit complicated to explain. Tobbe - Apr 05, 2007 - 03:31 PM

Post subject: Thanks Dean. It makes perfect sense. It stacks the interrupts by priority. So if a priority interrupt flag of priority 1 is set, it goes is put at the top of the stack and fires as soon as the current ISR is finished.

Page 21: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Also, I am fairly certain I could create the "ring buffer" code myself, but I'd be more than happy if you could provide me with an example through a PM. It'd save me time. Thanks again for the wonderful and detailed explanations. anilsoni85 - Apr 18, 2007 - 12:21 PM

Post subject: hey this code not working when i tried to complie this code i got an warning that

../SMS_Controller.c:135: warning: 'USART_RXC_vect' appears to be a misspelled signal handler abcminiuser - Apr 18, 2007 - 12:26 PM

Post subject: You may be using an old version of WinAVR (actually, an old version of avrlib-c which is included in the package). The "*_vect" names were added in a recent release and the old "SIG_*" names deprecated - an up-to-date version is in the current WinAVR 20070122.

If you don't want to upgrade, try the old name "SIG_USART_RECV" (or "SIG_UART_RECV" depending on your chosen AVR model).

- Dean Twisted Evil anilsoni85 - Apr 18, 2007 - 08:44 PM

Post subject: I am using the latest verion of WinAVR 20070122 and my avr is atmega8535 still i m getting this warining what could be reason behind this?? abcminiuser - Apr 19, 2007 - 05:48 AM

Post subject: For the MEGA8515, the datasheet says that the vector is named "USART_RX_vect". "SIG_UART_RECV" should have also worked (despite being deprecated) - what error did you get when you used that?

- Dean Twisted Evil coolleo - Jun 10, 2007 - 11:34 AM

Post subject: I'm also having the same "warning: 'USART_RXC_vect' appears to be a misspelled signal handler" messages, however after I replace it to SIG_USART_RECV the warning message disappear, 0 warning message Very Happy

but nothing is echoed back, nothing is shown in my hyperterminal windows, I used the same circuitry from 1st usart tutorial.

while the result from 1st tutorial are somewhat ok, this times it's far from ok Sad Crying or Very sad clawson - Jun 10, 2007 - 01:41 PM

Post subject: coolleo,

Sounds like your avr-gcc and avr-libc is out of date then. As you are using Windows I guess you are also using WinAVR - the latest is WinAVR20070525 harish.ravishankar - Jun 25, 2007 - 11:42 AM

Page 22: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Post subject: Hi. I tried using the code posted in the tutorial. However, the microcontroller seems to be hanging once the interrupt occurs. I dont get back the sent data. Also, the background programme(a blinking LED) also stops the moment I transmit a byte from the computer.

I am using atmega16 with 1.8432 Mhz crystal. Normal usart works fine.Could you tell me what was going wrong? futrtrubl - Jul 07, 2007 - 01:53 AM

Post subject: Hey Dean,

Any plans to expand this to include interrupt driven transmition?

After reading lfmorisson's post in this thread I was thinking that the best way to do buffered transmition would be to have a function to queue data like

Code:

if (buffer empty interrupt off)

{

enable buffer empty interrupt

place first byte in buffer to send

place the rest in the queue

}

else

{

place everything in the queue

}

and then have the following in my buffer empty interrupt...

Code:

if (more stuff queued)

{

place next byte in buffer

Page 23: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

}

else

{

disable buffer empty interrupt

}

This would allow my main code to actually go to sleep for periods at a time instead of constantly being awake if I just enabled the buffer empty interrupt and let it go all the time. Sound good?

I'm just worried that an interrupt may fire after doing the check in the queuing function, and turns off the interrupt if the queue is empty. Should I do a cli() just before the check and sei() after the end of the else statement?

Edward santafree - Jul 09, 2007 - 05:29 AM

Post subject: I have the same query as above, by Edward (futrtrubl). The USARTs on my mega164p have a similar issue while receiving constant data at 4800 baud. I have ended up polling for flags ("loop_until_bit _is_set") on both Tx and Rx ends and miss a fair bit of characters (I still do that on the transmission end as you can see in the code). For starters, I'd atleast like an interrupt driven procedure for the incoming data on the reception end; but so far the service routine seems to miss out when it comes to execution.

Code:

static int uart_putchar( unsigned char cg , FILE *stream);

static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);

static int uart_putchar(unsigned char cg, FILE *stream)

{

if (cg == '\n')

uart_putchar('\r', stream);

Page 24: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

loop_until_bit_is_set(UCSR0A, UDRE0);

UDR0 = cg; // to terminal window at 1200baud.

return 0;

}

void main(void)

{

init_devices(); // call to various initializing function.

PORTA = 0x01;

for(;;)

{

if (newintFlag)

{

stdout = &mystdout;

printf("%c\n",uart_rxData);

// printf("HelloWorld\n");

}

}

}

ISR(USART1_RX_vect)

{

uart_rxData=UDR1; // this variable is a volatile unsigned char

newintFlag = 1; // volatile static int

}

Page 25: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

santafree - Jul 09, 2007 - 05:33 AM

Post subject: sorry , I missed a line while cleaning up the code.

I set the volatile variable newintFlag =0; in the if statement of my main(). abcminiuser - Jul 09, 2007 - 06:25 AM

Post subject: I could expand it to include buffered transmission - it's very simple. The algorithm would be:

Code:

FUNCTION Main

Enable TX Interrupt

Enable Global Interrupts

LOOP FOREVER

{Do Stuff}

Transmit_Data(Data)

Sleep

END LOOP

END FUNCTION

FUNCTION Transmit_Data(Data)

IF (UDR NOT FULL)

Store Data into RingBuffer

ELSE

UDR = Data

END IF

END FUNCTION

ISR TX_ISR

Page 26: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

IF RingBuffer NOT EMPTY

UDR = RingBuffer.Next

END IF

END ISR

Fairly simple - you just need a buffer to hold the data before transmission. I've written just such a library - check out the "Advanced Configurable RingBuffer Library" entry on my Website here.

- Dean Twisted Evil lfmorrison - Jul 09, 2007 - 01:59 PM

Post subject: The AVR actually has two different transmission-related interrupt mechanisms. The TX Complete inteerrupt fires after the last bit data has been clocked out of the UART and it is now sitting idle.

Alternatively, the TX Buffer Empty interrupt fires after the byte currently sitting in UDR as been moved into the shift register and it's safe to write a new byte to UDR for future transmission. This mechanism is possible because the UART't transmission system is actually buffered -- there are physically two separate registers, one of them is the shift register which holds the byte currently being clocked out, and the other is a holding register which can be filled ahead of time to ensure that there's always a byte queued up ready to automatically start transmission as soon as the transmitter is ready for it. This eliminates the idle period between the end of one byte and the start of the next.

Using the TX Buffer Empty interrupt can shave a few microseconds of idle time off of the transaction, potentially speeding up large bulk transmissions.

If Dean's algorithm doesn't meet your fancy, an alternative implementation would be:

Code:

FUNCTION Main

Enable Global Interrupts

LOOP FOREVER

Page 27: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

{Do Stuff}

Transmit_Data(Data)

Sleep

END LOOP

END FUNCTION

FUNCTION Transmit_Data(Data)

Store Data into RingBuffer

Enable TX Buffer Empty Interrupt (instead of Dean's TX Complete Interrupt)

END FUNCTION

ISR TX_BUFFER_EMPTY_ISR

IF RingBuffer NOT EMPTY

UDR = RingBuffer.Next

ELSE

Disable TX Buffer Empty Interrupt

END IF

END ISR

futrtrubl - Jul 09, 2007 - 11:52 PM

Post subject: Thanks Dean and lfmorrison. I think I will stick with the buffer empty interrupt route, as it simplifies my send function if I send more than one byte at a time, and shaving of idle time is always nice.

Edward

PS Dean, I think there could be a problem if the interrupt fires after you check that UDR is empty in Transmit_data() and there is no more data in the ring buffer. Data will be stuffed into the ring buffer but the tx interrupt will not fire again until another call to Transmit_data, at which point the data will be sent in the wrong order. santafree - Jul 11, 2007 - 01:55 AM

Page 28: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Post subject: Dean:

I get the following error when attempting to implement the Ring Buffer Library:

../RingBuff.c:12: error: 'for' loop initial declaration used outside C99 mode

would you know what could cause that. I am actually trying to loop my transmitted data from one UART to the other via the ring buffer. However, I run into another problem when I initialize with both the RXC (rx_complete interrupt) and UDRE ( tx_buffer_empty interrupt) I fail to read anything ( on the output terminal). here is what I am trying to do:

Code:

RingBuff_t* DataBuff;

void main(void)

{

init_devices(); // Buffer_Initialize(DataBuff);

for(;;)

{

}

}

//========= Rx Receive Flag Service Routine==================

ISR(_VECTOR(28)) //USART1_RX_vect

{

Buffer_StoreElement(DataBuff, UDR1);

Page 29: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

UCSR0B |= (1 << UDRIE0) ; // enable output buff empty interrupt

// uart_rxData = UDR1;

// newintFlag = 1;

}

ISR(_VECTOR(21)) //USART0_UDRE_vect

{

if (!(Buffer_GetElement(DataBuff)))

{

// If Buffer Empty

UCSR0B |= (0 << UDRIE0) ; // disable output buff empty interrupt

}

else

{

UDR0 = Buffer_GetElement(DataBuff);

}

}

abcminiuser - Jul 11, 2007 - 01:58 AM

Post subject: You need to configure your GCC installation to use the C99 standard. If you're using a makefile, change your -std line to:

Code:

CSTANDARD = -std=gnu99

Page 30: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

If using AVRStudio as your frontend, change the standard via the project options screen.

- Dean Twisted Evil santafree - Jul 11, 2007 - 02:09 AM

Post subject: thanks mate. got it working. santafree - Jul 11, 2007 - 04:03 AM

Post subject: Dean:

actually I have been unable to store the "unsigned char" datatype in the ring buffer. i set the BUFF_DATATYPE configuration variable (default: uint8_t) to unsigned char with no luck. could you point me in the right direction here. abcminiuser - Jul 11, 2007 - 05:06 AM

Post subject: Hi santafree,

Sorry! I just went over my code and it took me quite a long time to realize I made a silly boo-boo. Your buffers should not be pointers to a RingBuff_t and should be passed by address. I've updated the zip on my site - download that and check out the corrected example (also made a few minor code changes).

- Dean Twisted Evil zeugnim - Jul 18, 2007 - 10:56 AM

Post subject:

abcminiuser wrote:

You need to configure your GCC installation to use the C99 standard. If you're using a makefile, change your -std line to:

Code:

CSTANDARD = -std=gnu99

If using AVRStudio as your frontend, change the standard via the project options screen.

- Dean Twisted Evil

Page 31: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

I have the same problem with the GCC config, I'm usign AVRStudio and I cannot see how to change the standard in the project options screen.. would it be beacuse of my version? I'm using ver 4.13.524... or how can I change to the C99 standard?? clawson - Jul 18, 2007 - 11:25 AM

Post subject: Project-configuration options-custom options

If a -std=???? already exists then select it and use [edit], pressing [add] when finished. Otherwise just type "-std=gnu99" into the box to the left of [add] and then press that same add button. abcminiuser - Jul 18, 2007 - 11:29 AM

Post subject: In AVRStudio:

Project Menu -> Configuration Options. Select the "Custom Options" tab, in the text box type "-std=gnu99" and press the "Add" button. Click "Ok" to close the window and it should work fine.

Also check out my other tutorial on configuring AVRStudio for optimal GCC projects, as there's a few other pointers in there.

- Dean Twisted Evil LixxxX - Jul 30, 2007 - 06:59 PM

Post subject: My program is not working, Help me please!!!

Code:

#include <avr/io.h>

#include <avr/interrupt.h>

#include <avr/signal.h>

#include <inttypes.h>

#include <avr/iom16.h>

//Variables

#define Frec_Osc_Cristal 16934400

Page 32: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

#define Baud_Rate 250

#define _U2X 1 //1 � 0

//Definicion del UBRR para el Baud rate

#define _UBRRL ((Frec_Osc_Cristal/(Baud_Rate*(8*(2-_U2X))))-1)

int n;

void inicio(void)

{

//Definicion del baud rate

UBRRH = (_UBRRL>>8);

UBRRL = _UBRRL;

//8 bits|8 bits|2 stop bits|lecturaUCSRC pag 167

UCSRC =(1 << UCSZ0 | 1 << UCSZ1 | 1<<USBS | 1<<URSEL);

//habilit de interrup de Tx completada | habilit de interrup reg vacio|habilit tx

UCSRB =(1 << TXCIE | 1 << UDRIE | 1<<TXEN);

//si es uno doble el baud rate

if (_U2X) UCSRA |= (1 << U2X);

sei(); //Habilito las interrup globales

}

Page 33: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

SIGNAL (SIG_UART_DATA)

{

n=0;

while(n<=20)

{

n++;

UDR = 0x01;

PORTC =0xFF;

}

}

SIGNAL (SIG_UART_TRANS)

{

PORTC =0x02;

}

void USART_Transmit( unsigned char data )

{

while ( !( UCSRA & (1<<UDRE)) )

UDR = data;

}

Page 34: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

int main(void)

{

inicio();

//pin 0 y 1 de portc como salida

DDRC=0xFF;

while(1)

{

while(!(UCSRA & (1 << UDRE)))

USART_Transmit(43);

//PORTC =0x02;

USART_Transmit(0xAA);

PORTC =~ PORTC;

n=0;

while(n <= 0xFFF)

n++;

}

}

I don�t know that is my error clawson - Jul 30, 2007 - 09:53 PM

Post subject: "not working" ???

Page 35: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

(BTW SIGNAL() is deprecated - use ISR() these days) LixxxX - Jul 30, 2007 - 10:51 PM

Post subject: Thanks, is working, but no enter at USART_TXC_vect interrupt

clawson wrote:

"not working" ???

(BTW SIGNAL() is deprecated - use ISR() these days)

The led in portc no turn on, because USART_TXC_vect interrupt no working

Code:

#include <avr/io.h>

#include <avr/interrupt.h>

#include <avr/signal.h>

#include <inttypes.h>

#include <avr/iom16.h>

//Variables

#define Frec_Osc_Cristal 16934400

#define Baud_Rate 250

#define _U2X 1 //1 � 0

//Definicion del UBRR para el Baud rate

#define _UBRRL ((Frec_Osc_Cristal/(Baud_Rate*(8*(2-_U2X))))-1)

volatile int m=0;

int n;

Page 36: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

void inicio(void)

{

cli();

//pin 0 y 1 de portc como salida

DDRC=0xFF;

//Definicion del baud rate

UBRRH = (_UBRRL>>8);

UBRRL = _UBRRL;

//8 bits|8 bits|2 stop bits|lecturaUCSRC pag 167

UCSRC =(1 << UCSZ0 | 1 << UCSZ1 | 1<<USBS | 1<<URSEL);

//habilit de interrup de Tx completada | habilit de interrup reg vacio|habilit tx

UCSRB =(1 << TXCIE | 1 << UDRIE | 1<<TXEN);

//si es uno doble el baud rate

if (_U2X) UCSRA |= (1 << U2X);

sei(); //Habilito las interrup globales

}

ISR(USART_UDRE_vect)

Page 37: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

{

m++;

if (m < 20)

{

UDR = 0x01;

}

else

{

m=0;

PORTC=0x00;

}

}

ISR(USART_TXC_vect)

{

PORTC =0xFF;

}

void USART_Transmit( unsigned char data )

{

while ( !( UCSRA & (1<<UDRE)))

UDR = data;

}

Page 38: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

int main(void)

{

inicio();

while(!(UCSRA & (1 << UDRE)));

USART_Transmit(43);

while(1)

{

}

}

lfmorrison - Jul 31, 2007 - 03:06 PM

Post subject: RE: Thanks, is working, but no enter at USART_TXC_vect inter The TXC interrupt vector will only fire once after the final bit of a frame has been clocked out and there's nothing else buffered in UDR waiting for transmission.

Because of the way that your UDRE interrupt service routine is structured, there will *always* be something waiting in the UDR buffer. (Remember, the UDRE interrupt fires continually as long as there is space left in the UDR buffer.) Therefore, the TXC interrupt will *never* have a chance to fire. LixxxX - Jul 31, 2007 - 11:46 PM

Post subject: With respect, as you would modify the program so that each 20 data (UDRE interrupt�s) the interruption TXC fire? lfmorrison - Aug 01, 2007 - 03:39 AM

Post subject: Well, that sort of depends, because I'm not convinced of exactly what you actually want that software to do.

You've got a call to UART_Transmit() in the mainline which will be competing with the constantly-firing UDRE interrupts for writing to UDR.

Page 39: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

It's impossible for me to judge exactly what you actually intended to accomplish with the mainline's UART_Transmit() call, because the UDRE interrupts will already have started start firing, stuffing 0x01's through the UART, as soon as the last line of code in inicio() finishes executing.

I'd prefer to see a more complete process specification before I commented on how to structre any changes. Taipan - Aug 15, 2007 - 05:48 AM

Post subject: Just wondering if I can expect to be able to reliably test a Max232 chip on a breadboard? I have a VB6 program that is polling an AVR regularly and displaying the results on screen. Through the spare RS232 on the STK500 it works very well. But when I try to use a max232 chip I have set up on a breadboard using the circuit here the communications is not so good. It keeps losing connection as I am not getting a return from every request for data. I just want to make sure my circuit is OK before I make a pcb. clawson - Aug 15, 2007 - 10:26 AM

Post subject: Taipan,

But you don't show the clock source to the AVR on your own circuit. Reliable comms generally means reliable clock source (and vice versa). Also do you have a scope and can look at the TX/RX signals for timing and any noise etc. Taipan - Aug 15, 2007 - 11:25 AM

Post subject:

clawson wrote:

Taipan,

But you don't show the clock source to the AVR on your own circuit. Reliable comms generally means reliable clock source (and vice versa). Also do you have a scope and can look at the TX/RX signals for timing and any noise etc.

I have tried it 2 different ways, firstly with an Atmega16 along with a 7.3728 crystal and the Max232 on the breadboard, and secondly using the AVR on the STK500 and just routing the TXD/RXD to the Max232 on the breadboard. Both ways give about the same result.

Using Bray's Terminal I just have to send a single ascii character to get a return from the AVR. If I use the Spare RS232 on the STK500 I can hold down the key sending a continual stream of characters and get 100% return from the AVR. When I use the Max232 on the breadboard I am getting about an 80% return.

Page 40: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

I do have a scope, but I don't know a lot about using it. I'll get it out tomorrow and give it a try. Thanks for the help. Taipan - Aug 16, 2007 - 03:57 AM

Post subject: I found my circuit worked OK at 9600 baud but I was initially trying to use 115200. At that speed some of the sent characters were arriving corrupted.

I forgot to say thanks for the great tutorial. It certainly made things easy for a beginner like myself. zhongc1 - Aug 27, 2007 - 06:37 PM

Post subject: By looking at iom8535.h, the recognized vector is USART_RX_vect. This is inconsistent with the datasheet, but USART_RX_vect (without the 'C') is copied from AVR Studio's partdescriptionfiles. I ran into the same problem with atmega8515, where the vectors are defined to be UART instead of USART. We maybe in a situation where GCC would say it is a problem originated from Atmel, and Atmel would say the partdescriptionfiles are only meant for AVR studio.

#define USART_RX_vect _VECTOR(11)

anilsoni85 wrote:

I am using the latest verion of WinAVR 20070122 and my avr is atmega8535 still i m getting this warining what could be reason behind this??

reg2117 - Aug 30, 2007 - 03:08 PM

Post subject: Dean,

Thanks for posting such a clear tutorial! It is immensely useful in getting started with the USART.

One suggestion to clarify the ISR use: Please include a line mentioning how the Recieve Complete Interrupt flag clears (from the ATmega16 datasheet):

Quote:

When interrupt-driven data reception is used, the receive complete routine must read the received data from UDR in order to clear the RXC Flag, otherwise a new interrupt will occur once the interrupt routine terminates.

This is similar to the explanation you gave in your timers tutorial for the OCF1A flag:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=50106

Page 41: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

In fact, had I not read that very useful tutorial, I wouldn't have known where to look in the datasheet to understand how the interrupt flag clears.

Again, thanks for adding such useful content to the forum. Keep 'em coming!! abcminiuser - Aug 30, 2007 - 03:14 PM

Post subject: Hi reg2117,

Thanks for the praise and comment. That's a good idea - I've added the datasheet quote to the tutorial. Thanks for the feedback!

- Dean Twisted Evil hyam005 - Sep 11, 2007 - 10:07 AM

Post subject: Hi everyone. I encounter some problems when using USART. This is the senario: I need to transmit a string of characters through USART to a PC. Hyperterminal is the terminal emulator that I use at the PC end. I know this terminal is not good. But I have to use it. I tried to run the code posted over here and it worked perfectly. I can see every characters that I pressed. But when I change

Code:

UDR = ReceivedByte;

to

Code:

UDR = 'J';

or some other characters, something else will turn up on the terminal window. I don't have any idea how that happen. Do I need to set anything other than the baud rate and flow control? I normally use 2400, 8-N-1, Auto detect emulation.

Also, I am using ATmega8, at 8Mhz using calibrated internal RC oscillator. clawson - Sep 11, 2007 - 10:43 AM

Post subject: Calibrated against what? hyam005 - Sep 11, 2007 - 10:51 AM

Post subject:

clawson wrote:

Page 42: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Calibrated against what?

I am not quite sure. I just load the calibration bytes into OSCCAL register clawson - Sep 11, 2007 - 11:31 AM

Post subject: Well as long as you operate at normal room temperature and from a 5V supply the Atmel factory profiled valued should be OK and the 207 you load into UBRRL should be giving you just 0.2% error but to check maybe use a scope to measure the bit widths on transmitted characters (repeatedly sending 'U' is good for this!). For 2400 baud you are looking for 416.6us

Cliff hyam005 - Sep 11, 2007 - 12:19 PM

Post subject:

clawson wrote:

Well as long as you operate at normal room temperature and from a 5V supply the Atmel factory profiled valued should be OK and the 207 you load into UBRRL should be giving you just 0.2% error but to check maybe use a scope to measure the bit widths on transmitted characters (repeatedly sending 'U' is good for this!). For 2400 baud you are looking for 416.6us

Cliff

I know what you mean. I am aware of the 0.2% error too. I just don't understand why the Hyperterminal can recognize the echoed characters, but not the characters that are coded in the program. I am suspecting that Hyperterminal is not configure properly to recognize char that is sent by USART. harald85 - Sep 13, 2007 - 01:12 AM

Post subject: hello everyone, i am facing some problem when using the code below

ISR(USART_RXC_vect)

{ // USART RX interrupt

unsigned char c;

c = UDR;

}

the compile result get this

Page 43: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

warning: 'USART_RXC_vect' appears to be a misspelled signal handler

i have no idea wat happening, Confused Taipan - Sep 13, 2007 - 02:31 AM

Post subject: what AVR are you using, maybe it has more than one USART and needs to be USART0 or USART1? harald85 - Sep 13, 2007 - 04:31 PM

Post subject: i am using ATmega8535

because this interrupt is very simple to use..

1 more problem dunno anyone can help..

i am trying to set the

F_CPU = 11059200

baudrate = 2400

MYUBRR = 287

using the pony prog, and set the CKOPT at the configuration and security bit

the programmer circuit also putting 12MHz oscillator + 22pf capacitor..

and trying with hyperterminal, using IR communication

but unlucky that cant show the result when transmit from AVR to the hyperterminal..

can anyone help?

thanks Sad Sad clawson - Sep 13, 2007 - 04:33 PM

Post subject: From iom8535.h:

Code:

/* USART, RX Complete */

#define USART_RX_vect _VECTOR(11)

So try making it:

Code:

ISR(USART_RX_vect) {

...

Page 44: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

mpukki - Oct 10, 2007 - 11:05 AM

Post subject: Hi,

I seemed to have a problem with interrupt driven Usart so I tried to follow the example given in this tutorial. I have a AtMega128 at 16 MHz and I'm using USART1 on the device. Usart communication with polling is working on the same exact cirtuitry but interrupt based communication isn't.

My source code is as follows:

Code:

#include <avr/io.h>

#include <avr/interrupt.h>

#include <avr/iom128.h>

#define F_CPU 16000000UL

#define USART_BAUDRATE 9600

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

#include <util/delay.h>

void delay(uint8_t);

int main (void)

{

//char ReceivedByte;

UCSR1B |= (1 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1); // 10011000 UCSRnB

Page 45: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

UCSR1C |= (1 << UCSZ0) | (1 << UCSZ1); // 00000110 UCSRnC

UBRR1L = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register

UBRR1H = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register

DDRA |= 1<<PA6; // Port A pin 6 as output

sei(); // enable interrupts

for (;;)

{

delay(250);

PORTA ^= 1<<PA6; // Toggle led on and off

}

}

int SRI(USART1_RX_vect){

char ReceivedByte;

ReceivedByte = UDR1; // Fetch the recieved byte value into the variable "ByteReceived"

UDR1 = ReceivedByte; // Echo back the received byte to the computer

return 0; back

}

When I run the code, led toggles happily. The time when I try to connect Usart with MiniCom it seems that the program hangs inside of the interrupt handler. I am using Linux and as there where proposals earlier in this thread that older versions of AVRLibC and AVR-GCC might be the problem, I compiled version 4.2.2 GCC as target AVR and I also compiled AVRLibC 1.4.6. Oh and of course binutils 2.18.

Page 46: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Any idea what might be wrong? Am I forgetting something or is my AVR broken or Is the fault in my toolchain?

I configured the source for toolchain like this:

binutils 2.18

Code:

configure --target=avr --program-prefix="avr-"

(avr-)gcc 4.2.2

Code:

configure --target=avr --program-prefix="avr-" --enable-languages=c --disable-libssp

AVRLibC 1.4.6

Code:

configure --host=avr

When I compile the code I showed earlier it compiles without warnings (with -Wall). Should I use some other flags when compiling the gcc? Or any other idea what might be wrong? I would need help with this problem urgently. I really hope that someone could help.

thanks

Page 47: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Mikko

"I have made this letter longer than usual, because I lack the time to make it short." - Blaise Pascal abcminiuser - Oct 10, 2007 - 02:04 PM

Post subject: Obvious things first. Have you disabled the M103 compatibility fuse? That'll certainly cause the interrupt vectors to mis-behave if it's still set.

- Dean Twisted Evil mpukki - Oct 10, 2007 - 03:34 PM

Post subject:

abcminiuser wrote:

Obvious things first. Have you disabled the M103 compatibility fuse? That'll certainly cause the interrupt vectors to mis-behave if it's still set.

- Dean Twisted Evil

After reading your reply I thought that it must be that fuse.. But output from avrdude is:

Code:

&>avrdude -c stk200 -p m128 -P /dev/parport0 -v

***clip***

avrdude: Device signature = 0x1e9702

avrdude: safemode: lfuse reads as CF

avrdude: safemode: hfuse reads as 9

avrdude: safemode: efuse reads as FF

Page 48: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

***clip***

Regarding that efuse seems to be 11111111.

In M103 compatibility mode it should be 11111101, right?

-Mikko Lajon - Oct 10, 2007 - 05:53 PM

Post subject:

Code:

int SRI(USART1_RX_vect){

Is this a typo (but I guess you did not type all that in)?

Code:

ISR(USART1_RX_vect){

would be correct.

/Lars mpukki - Oct 10, 2007 - 10:02 PM

Post subject:

Lajon wrote:

Code:

int SRI(USART1_RX_vect){

Is this a typo (but I guess you did not type all that in)?

Code:

ISR(USART1_RX_vect){

would be correct.

/Lars

Page 49: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Yes, I would think so too but my compiler doesn't:

Code:

../uart.c:39: warning: return type defaults to �int�

../uart.c: In function �SRI�:

../uart.c:44: warning: control reaches end of non-void function

No idea where that comes from but changing that wont do any good either. I tried also to echo a single character by typing "echo "U" > /dev/ttyS0". It also hangs the whole avr. I also tried compiling (WinAVR 2007-05-25) in windows and avrdude did a good job with messing LFUSE bits even if I did not ask it to do so... For example a few second delay that I use in main changed to maybe 200 milliseconds etc.. I didn't bother to find out what caused it but I changed fuse bits to original and went back to Linux later on. Compiled with WinAVR's avr-gcc sending a char for usart still hung the AVR.

thanks anyway

Mikko

edit: And yes, I had misspelled ISR to SRI at some point... but still no go. Could it be that USART1_RX_vect is wrong interrupt vector afterall? abcminiuser - Oct 10, 2007 - 11:33 PM

Post subject: If you're getting those warnings, it means that you *are* trying to make the ISR with the code:

Code:

int SRI(...)

Your ISRs should be defined verbatim as:

Page 50: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Code:

ISR(...)

As the "ISR" is a macro which is defined in avr/interrupt.h and expanded out at compile time to all the right compiler hints. Try changing your code's "int SRI" to plain "ISR" and see if it will recompile. Remember to do a "make clean" between builds to ensure a fresh compile!

- Dean Twisted Evil mpukki - Oct 11, 2007 - 12:39 AM

Post subject: ok, now code looks like this:

Code:

int main (void)

{

UCSR1B |= (1 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1);

UCSR1C |= (1 << UCSZ0) | (1 << UCSZ1);

UBRR1L = BAUD_PRESCALE;

UBRR1H = (BAUD_PRESCALE >> 8);

DDRA |= 1<<PA6;

sei();

for (;;) // Loop forever

{

delay(100);

PORTA ^= 1<<PA6;

}

Page 51: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

return 0;

}

ISR(USART1_RX_vect){

char ReceivedByte;

ReceivedByte = UDR1;

UDR1 = ReceivedByte;

}

Compiles without warnings. But it is not still working. There should not be bits and pieces of old code since using make clean.

- Mikko davef - Oct 11, 2007 - 02:15 AM

Post subject: So, it works if you do not enable the interrupts?

Does it work OK if you leave out the ISR()?

Can we see your delay()? mpukki - Oct 11, 2007 - 06:49 AM

Post subject:

davef wrote:

So, it works if you do not enable the interrupts?

It wont of course echo back anything then. If I poll RXC bit in UCSR1A I can read from USART and send characters back.

davef wrote:

Does it work OK if you leave out the ISR()?

Page 52: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Does the same

davef wrote:

Can we see your delay()?

Code:

void delay(uint8_t t){

uint8_t foo;

for (foo = 0; foo < t; foo++) _delay_ms(20);

}

This should not be causing it because even if there is an empty for loop in the main (without delay or led blinking), there is still no echo.

-Mikko davef - Oct 11, 2007 - 11:13 AM

Post subject: Sorry, by "not working" I thought you meant the LEDs didn't blink anymore!

Moving right along . . . mpukki - Oct 11, 2007 - 01:20 PM

Post subject:

davef wrote:

Sorry, by "not working" I thought you meant the LEDs didn't blink anymore!

Moving right along . . .

Page 53: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Well actually I said before that led stops blinking at the moment I send the byte to the Usart (when interrupt is enabled). I just tried with another mega128 but same problem exists, so I quess that I have to try some other compiler/version.

- Mikko mpukki - Oct 11, 2007 - 02:20 PM

Post subject: Hi,

Got it working in WinAVR without changing the source code. But I have still check into what the toolchain does wrong in Linux by disassembling the object files. Just in case someone else runs into same problem. Maybe I'll just change back to older versions on Linux.

Thanks for help

- Mikko djeezus - Oct 27, 2007 - 02:22 PM

Post subject: usart parse `cat file > /dev/modem` line by line Hy all,

let me start by thanking everyone for the great tutorials and comments ! I'm a newbie to avr and this is the motherload for me Smile

I'm trying to parse files line by line via USART, I've managed to get a CRLF terminated textfile bounce line by line in minicom when catting to /dev/modem... But I want to parse file line by line. I think I should parse 'm inside ISR(USART_RX_vect) but how to fill UDR line by line in stead of filling SRAM/FLASH (file sizes unknown)

I've also tried the "static FILE mystdio = FDEV_SETUP_STREAM(usart_putchar,usart_getchar,_FDEV_SETUP_RW);"

routines, but I'm not sure how to implement them with interrupt driven UART and I also loose chars when catting a file to /dev/modem ...

I hope this makes some sense Smile

Page 54: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

bye,

gert

Code:

#include <avr/io.h>

#include <avr/interrupt.h>

#include <util/delay.h>

#define USART_BAUDRATE 9600

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

// Global variables

unsigned short int ports, leds ;

// A delay routine

void delay(uint8_t t){

uint8_t foo;

for (foo = 0; foo < t; foo++) _delay_ms(10);

}

int main (void)

{

UCSRB |= (1 << RXEN) | (1 << TXEN);

UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);

Page 55: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

UBRRL = BAUD_PRESCALE;

UBRRH = (BAUD_PRESCALE >> 8);

UCSRB |= (1 << RXCIE);

sei();

for (ports=0;ports<=7;ports++)

{

DDRD&=~_BV(ports);//set PORTD (button) pin{ports} to zero as input

PORTD|=_BV(ports);//Enable pull up

PORTB|=_BV(ports);//led {ports} OFF

DDRB|=_BV(ports);//set PORTB (leds) led to zero as output

}

for (;;) // Loop forever

{

// RS232 communication is now handled by the ISR instead of in the main loop

// This frees up MCU to do other stuff in stead of waiting around for RX

if (bit_is_clear(PIND, 0))//if button is pressed

{

PORTB&=~_BV(0);//led 0 ON

loop_until_bit_is_set(PIND, 0);//LED ON while Button is pressd

PORTB|=_BV(0);//led 0 OFF

} else if (bit_is_clear(PIND, 7))

{ PORTB&=~_BV(7);//led 7 ON

loop_until_bit_is_set(PIND, 7);//LED ON while Button is pressd

PORTB|=_BV(7);//led 7 OFF

Page 56: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

}

else {

// blink blink

for (leds=0;leds<=7;leds++)

{ delay(2) ;

PORTB&=~_BV(leds) ;

delay(2) ;

PORTB|=_BV(leds) ;

}

}

}

return 0 ;

}

ISR(USART_RX_vect)

{

char DaTa;

DaTa = UDR;

// Must find way to read line by line ...

// pseudo code

if (DaTa=='\0') { myline = DaTa_from_ringBufffer? ;

parse_myline();

}

UDR = DaTa;

}

Page 57: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

abcminiuser - Oct 28, 2007 - 11:35 AM

Post subject: RE: usart parse `cat file > /dev/modem` line by line What you need to do, is set up some buffers that are larger than the longest line you want to read in. You'd probably need two of them, one for reading in from the USART and one for processing (you'd "ping-pong" between them, to ensure you never lose bytes).

Your ISR would read in the UDR bytes and stuff them into the current write buffer, until a \n is reached. When the newline character is sent, you need to set a flag to indicate to the main program that the buffer is ready to be parsed, and start writing to the other buffer.

Your main program then has to wait for the "ready to be parsed" flag to be set on each buffer, whereupon it clears the flag and does the parsing.

- Dean Twisted Evil infibit - Oct 29, 2007 - 06:15 AM

Post subject: i am working with atmega 8..what i have seen is the registers are the same as in case of atmega 16 djeezus - Oct 29, 2007 - 08:01 PM

Post subject: Re: RE: usart parse `cat file > /dev/modem` line by line Hey Dean,

thnx for the reply, I think I worked something out ...

abcminiuser wrote:

What you need to do, is set up some buffers that are larger than the longest line you want to read in. You'd probably need two of them, one for reading in from the USART and one for processing (you'd "ping-pong" between them, to ensure you never lose bytes).

Indeed, I think I'm not losing any ...

Quote:

Page 58: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Your ISR would read in the UDR bytes and stuff them into the current write buffer, until a \n is reached. When the newline character is sent, you need to set a flag to indicate to the main program that the buffer is ready to be parsed, and start writing to the other buffer.

Here's the ISR part now ...

Code:

// Read in USART and place in buffer for later usage ...

ISR(USART_RX_vect)

{

uint8_t c ;

c = UDR ;

if (bit_is_clear(UCSRA, RXC))

{

rxbuff = c ;

intflags.rx_int = 1 ;

}

}

Quote:

Your main program then has to wait for the "ready to be parsed" flag to be set on each buffer, whereupon it clears the flag and does the parsing.

and here's the part that parses untill "\n" ... catting works fine

Page 59: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Code:

for (;;) // Loop forever

{

if (intflags.rx_int)

{

intflags.rx_int = 0;

p=string_buffer ;

if (rxbuff == '\r')

{

*p=0; // terminate string

}

else {

if (i<10) // charbuffer size

{ *p++=rxbuff ;

i+=1 ;

}

UDR = rxbuff ; // bounce

}

}

}

Page 60: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Now I can read in line by line (if file is CRLF terminated at least); that leaves me with the part of parsing the strings, but while this parsing is going on, won't I risk loosing input from USART this way ? I'll figure this out when my parsing code is there I guess ...

bye,

Gert abcminiuser - Oct 29, 2007 - 11:08 PM

Post subject: RE: Re: RE: usart parse `cat file > /dev/modem` line by l

Quote:

but while this parsing is going on, won't I risk loosing input from USART this way ?

Which is why I suggested two large buffers. You fill one in the ISR, then null-terminate it when you receive the newline character, and set a flag. Your main code then parses the line while the ISR switches to filling the other buffer while the parser runs on the first buffer. When the next line is ready you set another flag to tell the parser to work on the second buffer while you start filling the first again.

- Dean Twisted Evil djeezus - Nov 02, 2007 - 02:45 PM

Post subject: Hya Dean,

I understood what you meant the first time, but I don't to see how 2 buffers (or even 3 of 4 for what that matters) will be sufficient for ISR RX throttling.

The usart will receive approx. 200Kb (or more) data, which needs to be parsed and will trigger delays and high/low on several pins - if I use interrupts for these, will this temporarly block ISR UART, and will a "cat file > /dev/ttyS0" be able to handle this ? -

Won't a 2nd (or 3d, 4th etc.) buffer also loose chars if the parsing and following delays() & pin changes take quite long to finish ? Maybe I should call cli() when parsing a string ? Or use uart polling ?

Page 61: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

I've also thought about storing entire usart input in PROGMEM and read from there, but that means restriction on file size. I've read many excellent docs about U(S)ART but implementation in these docs are focused on bouncing, uart<->uart or cmdline-interface... These I've got sorted Cool

However, I've only been doin' C and AVR for 1 month, so maybe I'm missing the point entirely Embarassed

Thnx for yer time Smile clawson - Nov 02, 2007 - 03:13 PM

Post subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway. Wouldn't it be easier to add some buffer RAM to the AVR - maybe an SPI or I2C/TWI connected SRAM devices or, if it needs to be non-volatil, FRAM abcminiuser - Nov 03, 2007 - 11:37 AM

Post subject: Well, as long as your operations on a single line (buffer) are shorter than the time it takes to read in another line, you won't loose any characters - the ISR fills the opposite line buffer to the one being operated on.

A better way to do this would be to use a large ringbuffer (see the "AVR Experiments" page of my site for a code example) to store the characters. You'd also keep a counter for the number of *complete* lines stored in the buffer. The system would work like this:

Code:

volatile uint8_t TotalRecLines;

volatile RingBuffer_t RingBuff;

ISR(Byte Recieved)

{

uint8_t RecByte = UDR;

if (RecByte == '\n')

{

TotalRecLines++;

Page 62: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

RecByte = '\0';

}

StoreByte(&RingBuff, RecByte);

}

int main (void)

{

// Usual setup code

for (;;)

{

if (TotalRecLines) // Line waiting to be processed

{

// Process line, read in bytes from ringbuffer until \0 is reached

TotalRecLines--;

}

}

}

That way, the ISR just has to keep feeding in bytes into the ringbuffer. When a complete line is read it increments the counter to tell the main program to start reading it back out of the buffer again and process it. While the processing is being done, the ISR can still add bytes to the ringbuffer, so no information is lost as long as the buffer is large enough.

- Dean Twisted Evil djeezus - Nov 05, 2007 - 10:16 PM

Post subject: Hy,

Page 63: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

I'm not sure I quite understand how to use AdvRingBuffer, I understand what it does, but I struggle to get the data back out of the buffer. Should I read chars until '\0' and then strcpy to a string ?

Code:

// RingBuffer stuff

#include "RingBuff.h"

volatile uint8_t TotalRecLines;

volatile RingBuff_t RingBuff;

ISR(USART_RX_vect)

{

uint8_t c ;

c = UDR;

if (c == '\r') {

TotalRecLines++ ;

c = '\0'; // Null terminate

}

Buffer_StoreElement(&RingBuff, c); // store in RingBuffer

}

void check_RS232(void)

{

if (TotalRecLines) {

uart_rxbuf[uart_rx_pos] = Buffer_GetElement(&RingBuff); // read chars from ringbuffer

if (Buffer_GetElement(&RingBuff) == '\0' ) { // till '\0' encountered

Page 64: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

strcpy(buffer, uart_rxbuf);

uart_rx_pos=0;

} else {

uart_rx_pos++;

}

TotalRecLines-- ;

}

}

bye

djeez abcminiuser - Nov 05, 2007 - 11:19 PM

Post subject: Here's a quick example of what I was getting at:

Code:

// RingBuffer stuff

#include "RingBuff.h"

volatile uint8_t TotalRecLines;

volatile RingBuff_t RingBuff;

ISR(USART_RX_vect)

{

char c = UDR;

if (c != '\r') // Ignore the \r in the standard \r\n sequence

return;

Page 65: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

if (c == '\n') // Reached the \n in the \r\n sequence

{

TotalRecLines++; // Indicate that an entire line is ready

c = '\0'; // Null terminate

}

Buffer_StoreElement(&RingBuff, c); // Store next byte in RingBuffer

}

void check_RS232(void)

{

char LineBuffer[100]; // Max line length is 100 bytes

if (TotalRecLines) // Wait for a whole line to be buffered before reading it out

{

char c;

uint8_t LineSize = 0;

do

LineBuffer[LineSize++] = Buffer_GetElement(&RingBuff);

while ((c != '\0') && (LineSize != sizeof(LineBuffer)))

if (LineSize == LineBuffer) // Line too long for buffer

LineBuffer[sizeof(LineBuffer) - 1] = '\0'; // Terminate string

TotalRecLines--;

Page 66: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

// LineBuffer now contains the next line from the USART - process it here

}

}

Haven't even tried to compile it, but you should get the basic idea of what it's trying to do.

- Dean Twisted Evil JimmyD - Nov 13, 2007 - 08:39 AM

Post subject: Hello, i was trying this Tutorial-code with ATmega32 and it wont work. I tried the code suggested in the datasheet and got some strange results:

if i am just sending stuff via:

Code:

void USART_transmit( unsigned char data )

{

/* Wait for empty transmit buffer */

while ( !( UCSRA & (1<<UDRE)) )

;

/* Put data into buffer, sends the data */

UDR = data;

}

i get all the chars on HyperTerminal, but my Problem is, i cant recieve any Characters. I use the same Init as given in the tutorial. Could i've missed something or maybe its a Problem with a RX part of the cable? abcminiuser - Nov 13, 2007 - 08:42 AM

Page 67: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Post subject: I'd wager it's a hardware problem. If you've tried the datasheet code also, and others have tested my code then your failure to receive characters is most likely an issue with your RX pin connection.

- Dean Twisted Evil JimmyD - Nov 13, 2007 - 10:10 PM

Post subject: Yea, i tried another cable and its working now. Thanks for the great Tutorial, Dean. infibit - Feb 15, 2008 - 08:47 AM

Post subject: hi clawson - Feb 15, 2008 - 07:13 PM

Post subject: @infibit

Everything in this tutorial + everything in the ADC tutorial plus the use of the itoa() function in the C library. infibit - Feb 15, 2008 - 07:31 PM

Post subject: hi Lajon - Feb 17, 2008 - 11:21 AM

Post subject: Are you using the internal RC oscillator? If so, is it calibrated? At the very least you should load the calibration value for 8Mhz in the OSCCAL register. The calibration for 1Mhz is loaded at reset so you could try running at 1Mhz also (lower the baud rate to 4800 or lower if you do). You can ignore all this if you have an external 8Mhz crystal.

The ADC questions are off-topic here but anyway:

Quote:

dint even connect anything to the ADC port and numbers just kept flowing in randomly.

What do you expect if you have nothing connected? The input will be floating and you will get some random values. Start with grounding the input and verify you get 0. Then try some voltage near the reference and verify you get a value close to 1023.

Have you connected a reference voltage at AREF btw? AREF is what you have selected as the reference by having the bits REFS1 and REFS0 both 0 in ADMUX.

/Lars infibit - Feb 18, 2008 - 08:20 AM

Post subject: hi infibit - Feb 18, 2008 - 08:44 AM

Post subject: hi infibit - Feb 20, 2008 - 03:44 PM

Post subject: hi clawson - Feb 20, 2008 - 05:22 PM

Page 68: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Post subject:

Quote:

I have configured the atmega8 now to 1mhz

Crystal or internal RC oscillator? If latter how are you calibrating it? infibit - Feb 20, 2008 - 06:51 PM

Post subject: hi clawson - Feb 20, 2008 - 10:11 PM

Post subject: But you haven't told us how you are calibrating it?

(to cut a long story short, if you want to use the UART get a crystal) infibit - Feb 21, 2008 - 07:13 AM

Post subject: hi Lajon - Feb 21, 2008 - 12:19 PM

Post subject:

Quote:

I dint even connect any device.

Again, I suggest you connect some known voltage to the ADC input.

Calibration or not depends, if you are using a reasonable baud rate and are just experimenting you may not need it. But this is still good advice for long term reliable communication:

Quote:

(to cut a long story short, if you want to use the UART get a crystal)

And since you already have a crystal why not just enable it.

/Lars almightyeric - Mar 03, 2008 - 06:06 AM

Post subject: Using Interrupt method for UART prevents other use of INT0 ? First of all, I really found this guide useful. Thanks!

I am using an ATMEGA8L AVR. I have switches connected to my PIND2 and PIND3, which are used for INT0 and INT1 respectively. With this interrupt-driven UART code enabled, I can get INT1 to work, but not INT0. However, if I comment out all the UART code, both INT0 and INT1 work fine. Is there something about this code that alters the functionality of INT0? If so, can someone explain it to me? I can post my code if needed, but I figured my question is probably general enough not to require the posting of my code (not that I mind posting it; I just want to avoid the clutter here).

Page 69: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Thanks. Just getting back into the AVR after a hiatus due to the completion of an I2C-accelerometer project Smile

-Eric clawson - Mar 03, 2008 - 10:23 AM

Post subject: RE: Using Interrupt method for UART prevents other use of IN Eric,

That is not a general issue so I think we need to see your code but it'd probably be most appropriate to start a new thread about it in AVR Forum. sagenepal - Mar 04, 2008 - 04:15 PM

Post subject: Hello,

I want to share this code in order to help out Stefan and anyone else who wants to to UART transmit using interrupts. This code uses the TXC interrupt, not UDRE. I don't know much about the latter. Maybe it would be better? But this code works, and it has a nice wrap-around buffer for very efficient use of processor time.

- Sage Radachowsky

Boston, USA

Code:

// SendWithInterrupt - main.c

//

// by Sage Radachowsky, Feb-Mar 2008 ("sager" at "mit" dot "edu")

//

//

// Program to test sending data to the serial output (UART / RS232) using interrupts

// instead of actively polling to check if the last byte was written.

//

Page 70: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

// This has two advantages -- the CPU is using its built-in hardware signals rather than

// burning CPU instructions so it consumes less power, and (2) the CPU is freed

// to do other things rather than wait for some 9600 baud output or even 57k baud output,

// which is a heck of a long time in a multi-MHz world.

//

// This is written for the AT90CAN128 microcontroller, which has 2 UART lines. To rewrite

// it for any Atmel AVR micro that has just one serial line, you would have to change the

// names of all the UART registers to remove the "0".

//

// Note that interrupts must be globally enabled for this stuff to work - of course!

//

// This code sets up the interrupts to interface with stdout, so that "printf()" sends

// by interrupt! Easy and Sweet!

//

// NOTE: Be sure to change your CPU speed if it's not 1.8432 MHz !

//

//**********************************************

// DEFINITIONS

//**********************************************

// CPU frequency

Page 71: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

#define F_CPU 1843200L // 1.8432 MHz

// UART baud rate

#define UART_BAUD 9600

// UART buffer size

#define UART_BUFFER_SIZE 256

//**********************************************

// HEADER FILES

//**********************************************

#include <ctype.h>

#include <string.h>

#include <stdint.h>

#include <stdio.h>

#include <avr/io.h>

#include <avr/interrupt.h>

#include <avr/pgmspace.h>

#include <util/delay.h>

Page 72: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

//**********************************************

// FUNCTION DECLARATIONS

//**********************************************

void USART0_Init(void);

static int UART0_Putchar(char c, FILE *stream);

void DelayAwhile(void);

//**********************************************

// GLOBAL VARIABLES

//**********************************************

char UartBuffer[UART_BUFFER_SIZE]; // this is a wrap-around buffer

int UartBufferNextByteToSend; // position of next byte to be sent

int UartBufferNextFree; // position of next free byte of buffer

int UartSendingInProgress; // 1 = sending is in progress

/* This is the pointer to the serial interface */

/* Defines the stream interface for write only */

FILE uart_str = FDEV_SETUP_STREAM (UART0_Putchar, NULL, _FDEV_SETUP_WRITE);

Page 73: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

// ################## here we GO! ####################

int main()

{

// initialize the UART and enable interrupts

USART0_Init(); sei();

printf ("Hello from SendWithInterrupt.\n");

DelayAwhile();

// loop forever

while (1)

{

printf ("This is test output. How's the weather?\n");

DelayAwhile();

}

}

Page 74: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

//===============================================================================

void DelayAwhile()

//

// Delays a while, to slow down to a human level.

//

{

_delay_ms(200);

_delay_ms(200);

_delay_ms(200);

}

//****************************************************

// UART functions

//****************************************************

//===============================================================================

void USART0_Init()

Page 75: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

// This routine initializes the UART0 port of the AT90CAN128 and clears the

// write buffer.

//

// This routine does NOT enable the transmit-complete interrupt (TXCIE0).

// That is left up to the UART0_PutChar() routine, after it puts something in

// the buffer for the first time.

//

// This routine also does NOT enable general interrupts. That is left to the

// main() initializing code, and it MUST be done for this stuff to work.

//

// Also sets standard out to the uart interface, so printf() works sweetly.

//

{

// init buffer data structures

UartBuffer[0] = '\0'; // clear the first byte of buffer

UartBufferNextByteToSend = 0; // set "next byte to send" to beginning

UartBufferNextFree = 0; // next free byte is also beginning of buffer

UartSendingInProgress = 0; // clear "sending in progress" flag

// set baud rate

UBRR0H = (unsigned char) (((F_CPU/(16L*UART_BAUD))-1) >> 8);

UBRR0L = (unsigned char) ((F_CPU/(16L*UART_BAUD))-1);

// Set frame format: 8data, no parity & 1 stop bits

Page 76: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

UCSR0C = (0<<UMSEL0) | (0<<UPM0) | (0<<USBS0) | (3<<UCSZ00);

// Enable transmit

UCSR0B = (1<<TXEN0); //Enable the transmitter only

// set standard output stream to our UART interface

stdout = &uart_str;

}

//===============================================================================

static int UART0_Putchar(char c, FILE *stream)

// If transmit is in progress, adds a character to the UART output buffer.

// If transmit is not in progress, kicks off a transmit.

//

// The send buffer is a wrap-around buffer.

//

// If the buffer is full, then this routine returns EOF.

// A successful completion returns 0.

//

// This routine disables the UART Tx interrupt temporarily, because

// things would get funky if the interrupt signal routine were called during

// execution of this routione.

//

Page 77: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

// If the buffer was empty to start with, then this routine "primes the pump"

// sending the character directly to the UART.

//

// This routine also adds carriage returns to newlines.

//

{

register int ReturnStatus = 0; // return 0 for success

register int UartBufferNextFree_last; // space to save last UartBufferNextFree

// if character is a "newline" then add a "carriage return" before it.

if (c == '\n')

UART0_Putchar('\r', stream);

// if no send is already in progress, then "prime the pump" by sending directly to UART

if (UartSendingInProgress == 0)

{

// set "sending in progress" flag

UartSendingInProgress = 1;

// send the first byte!

UDR0 = c;

}

else

{

// disable the Tx Complete interrupt

UCSR0B &= ~( 1 << TXCIE0 );

Page 78: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

UartBuffer[UartBufferNextFree] = c;

// increment the next free byte index, while saving last value

UartBufferNextFree_last = UartBufferNextFree++;

// check for wrap-around

if (UartBufferNextFree == UART_BUFFER_SIZE) // if we reached the end of the buffer -

UartBufferNextFree = 0; // start back at the beginning

if (UartBufferNextFree == UartBufferNextByteToSend) // if buffer is full -

{

// bump back the index so transmit routine doesn't think buffer's empty

UartBufferNextFree = UartBufferNextFree_last;

// return with error code

ReturnStatus = EOF;

}

// enable the Tx Complete interrupt

UCSR0B |= ( 1 << TXCIE0 );

}

// return with status code

return ReturnStatus;

}

Page 79: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

//********************************

// INTERRUPT HANDLERS

//********************************

//===============================================================================

ISR (USART0_TX_vect)

// This interrupt service routine is called when a byte has been sent through the

// UART0 port, and it's ready to receive the next byte for transmission.

//

// If there are more bytes to send, then send the next one and increment the index.

// If the index reached the end of the buffer, then wrap around to the beginning.

//

// If there is not another byte to write, then clear the "UartSendingInProgress"

// flag, otherwise set it if a byte has just been sent.

//

Page 80: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

{

if (UartBufferNextByteToSend == UartBufferNextFree) // if nothing to send -

{

UartSendingInProgress = 0; // clear "sending in progress" flag

return; // then we have nothing to do, so return

}

// set "sending in progress" flag

UartSendingInProgress = 1;

// send the next byte on UART0 port

UDR0 = UartBuffer[UartBufferNextByteToSend];

// increment index and check for wrap-around

UartBufferNextByteToSend++;

if (UartBufferNextByteToSend == UART_BUFFER_SIZE) // if we reached the end of the buffer -

UartBufferNextByteToSend = 0; // then start back at the beginning

}

Have fun! bootstrap - Mar 07, 2008 - 02:32 PM

Post subject: nice tutorial sagenepal - Mar 10, 2008 - 07:48 PM

Post subject: After I wrote my UART transmit by interrupt, I found this library by Pascal Stang:

http://www.mil.ufl.edu/~chrisarnold/com ... VR/avrlib/

I repeat the link here, because I think every AVR freak should know about it. There are many good functions there.

Page 81: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Actually, this link is the documentation:

http://www.mil.ufl.edu/~chrisarnold/com ... docs/html/ michael_R - Mar 27, 2008 - 07:39 AM

Post subject: Note to self and others, GCC doesn't produce an error for a misspelled interrupt handle, it just gives you a warning.

Don't learn the hard way.... abcminiuser - Mar 27, 2008 - 07:51 AM

Post subject: I'd suggest *always* using the -Werror command line switch. That indicates to GCC that all warnings should be treated like errors, preventing successful compilation.

I'm a firm believer that correct code should produce no warnings, and no errors. If code which triggers a warning is desired, then it should either be reworked or the warning suppressed through other means.

- Dean Twisted Evil clawson - Mar 27, 2008 - 10:20 AM

Post subject:

michael_R wrote:

Note to self and others, GCC doesn't produce an error for a misspelled interrupt handle, it just gives you a warning.

The implication of that is that you just ignore the warnings? If there's a lesson to be learned it is never ignore the warnings. In fact strive to get code compiling with no warnings at all and even so that it is split/lint-able. As Dean says -Werror is a good idea. Salgat - Mar 29, 2008 - 12:55 AM

Post subject: Thanks a ton for the guides on USART, I'm now able to successfully talk to myself through my microcontroller, a new low! Very Happy FiniteRed - Apr 03, 2008 - 11:11 AM

Post subject: Good morning

It seems my interrupt is firing on its own (after about 20 seconds from MCU start up) without any data being sent to it (there physically are no wires connecting to the Rx pin!)

Code:

Page 82: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

ISR(USART0_RX_vect) {

// code

} // ISR USART0

Is there a timeout or some other function that would fire the interrupt even if there is no data being sent to it? anmol2701 - Apr 07, 2008 - 08:52 AM

Post subject: I am using modem in my project to send an sms depending of some conditions. The sending of sms is not urgent ie. sms is not supposed to be fired instantly. Now my question is which way is good one to use - polled or interrupt for interfacing modem.

Moreover, is there any limitation on number of interrupts that we can use. abcminiuser - Apr 07, 2008 - 08:54 AM

Post subject: If it's not urgent, don't use interrupts (which should be used for time-critical events). There's no code limitation on the number of interrupts, but keep in mind that each one requires cycles to process -- to many happening simultaneously and you'll start to miss some or have them severely delayed.

- Dean Twisted Evil pepper_bg - Apr 12, 2008 - 08:36 PM

Post subject: Trying the (excellent!) tutorial here I see something I don't understand. I modified the final code slightly:

Code:

//includes...

static void uart_putchar(char c) {

loop_until_bit_is_set(UCSRA, UDRE);

UDR = c;

}

int main(void) {

Page 83: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

//...init usart for the corresponding avr

UCSRB |= (1 << RXCIE);

sei();

uart_putchar('p'); //so I just print a character here

for (;;); // Loop forever

return 0;

}

ISR(USART_RX_vect) {

char ReceivedByte;

ReceivedByte = UDR;

UDR = ReceivedByte;

}

I load the binary to my attiny2313, go to my terminal program and surely see a

Code:

p

sitting there (I just printed it there, right). I press the comma (',') key of my keyboard and as expected the avr starts bouncing commas back to me. But the whole output actually looks like this:

Code:

p,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

Page 84: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,p,,,,,,,

,,,,p,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,p,,,

,,,,,,,,,,,,,,,,,,,,,p,,,,,,,,,,,,,,p,,,

,,,,p,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

which tells me that somehow the main routine gets re-executed or reset or something... And seems to be pretty undeterministic too - I could have any number of commas between the 'p's. I read wathcdog timers can reset your avr (so the main() starts over), but I don't have that fuse set. As far as I know in C, the main() can be executed only once (unless you do some sort of recursion may be?). Tried putting something more meaningful in the for loop (in my case flipping a pin between 0 and 1) but that didn't change things much. The only other possibility is that the interrupt causes the main program reset but haven't seen that mentioned as an option either (and frankly it would be a bit disturbing). So what am I missing? kakasi - Apr 14, 2008 - 01:36 PM

Post subject: Hi Dean,

Nice tutorial. I'm new to AVRs and serial programming but it's a lot of fun Wink

I went through this tutorial and the basic one about serial communications. I have changed the code just to test and to make sure the that it is really the AVR talking to me through the serial port. Basically I wanted it to send back a 'x' with echoed character I send to the AVR.

Code:

ISR(USART_RXC_vect)

{

char ReceivedByte;

ReceivedByte = UDR; // Fetch the recieved byte value into the variable "ByteReceived"

UDR = ReceivedByte; // Echo back the received byte back to the computer

while ((UCSRA & (1 << UDRE)) == 0) {};

UDR = 'x';

}

Page 85: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

What I get back is very weird though. At times it works fine and sometimes I get an 'a' back when I send an 'A' and sometimes I will get an '|' back instead of a 'x'. For example every second 'A' I send will return as 'a|' instead of 'Ax'. What's even stranger is that only 'A's will return in lower case. All other characters are echoed in the same case. Sometimes it works fine so results are very spontaneous and I can't pick up a pattern.

I use a Atmega8 and Minicom in linux (i've even tested it with my own C code on linux and with Bray's Terminal in windows, same result). I hooked up and external crystal clocking at 7.3728MHz

Is it caused by the extra code I have added? Like I said, that code is not needed, I'm just using for testing purposes. abcminiuser - Apr 14, 2008 - 01:48 PM

Post subject: pepper_bg:

That's very odd behavior. Is that the only code running in your system? Does it appear to reset by itself (when you don't try to send characters) or only after you're sending data to it?

kakasi:

Spinloops in ISRs are usually a very bad idea - you run the risk of delaying too far and missing other interrupts. That said, if that's your only ISR you should be fine with low data rates.

I'd suspect that its either an issue with noise on the line or (more likely) a slight baud mismatch. What are you using for your AVR's clock source? If it's the default internal RC oscillator, you'll have problems as it's too low tolerance for reliable communications.

- Dean Twisted Evil kakasi - Apr 14, 2008 - 02:13 PM

Post subject: I'm using the external crystal as the clock source. Both the PC's port and the AVR is set up for 9600 bps...is it possible that crystal is unstable?

Page 86: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Thanks for the info...there is a possibility of noise, coz i built the circuit on a breadboard, right?

Rolling Eyes abcminiuser - Apr 14, 2008 - 02:34 PM

Post subject: Noise is *always* a possibility Wink.

How certain are you that the external crystal is being used? Plenty of people attach the crystal and blindly assume it's the AVR's clock source, but never change the AVRs fuses. My apologies if I'm going over things you already know, but it's a common trip-point for newbies.

The crystal might be unstable if the breadboard is giving it too much capacitance. However that voodoo-electronics is not my area, and you'd really need an oscilloscope to check it easily.

I'd rule out the cable first, as bad (or too long) cables can garble data more easily than you'd think.

- Dean Twisted Evil kakasi - Apr 14, 2008 - 02:41 PM

Post subject: hehe, no problem. it's definitely using the external clock...I had a flashing LED app running on the mega8, and right after connecting the crystal and burning the fuses, it started to flash much faster. That was easily fixed by specifying the new clock speed (#define F_CPU 7372800UL) Wink kakasi - Apr 14, 2008 - 05:22 PM

Post subject: OK, i have taken out the code that send the 'x', so I obviously don't get the random '|' back from the AVR anymore. But, I still have a problem with the 'A'...sometimes it echoes 'A' back and sometimes 'a' when you send 'A'.

I went through all the keys on my keyboard, and it gets even weirder. When I send a 'P' or 'p' it returns a 'X' or 'x' and sometimes it returns the correct results.

I doubt if it is noise, because it ONLY happens to these characters.

Is this happening to anyone else?

Page 87: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

I don't know why it only happens to these chars but this is interesting:

P - 101 0000

X - 101 1000

p - 111 0000

x - 111 1000

A - 100 0001

a - 110 0001

...there's only one bit chat changes between the pairs. kakasi - Apr 14, 2008 - 07:04 PM

Post subject: It seem to be working now...I have changed the baud rate to 19200 and no more funny results echoed back the the PC Very Happy kakasi - Apr 18, 2008 - 08:29 AM

Post subject: ..just some feedback...

I have moved all the components to my "production" pc board, and I also used another crystal (same specs as the one I used on my breadboard). I changed the baud rate back to the original 9600bps and everything is working as it should.

I think that either the crystal I used was faulty, or there is less noise or less capacitance on the pcboard. Unfortunately I am not a guru in electronics so I'm not sure exactly what caused the strange behavior on the breadboard. Wink

Thanks for the assistance Dean! t.man - Apr 18, 2008 - 11:49 AM

Post subject: good tutoril!

i'm planning to implement rs485 network for my application,where i may have a PC and several mcu units and i think one more tutorial on multi-processor communication would be helpful to some me and someone out there! societyofrobots - Aug 04, 2008 - 05:28 AM

Post subject: Did anyone solve that 'USART_RXC_vect' problem? I'm using the latest WinAVR with ATmega640 and getting the same error . . . Does it have anything to do with the fact I have four UARTs?

Page 88: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

I've tried every permutation of it:

USART_RXC_vect

UART_RXC_vect

USART_RX_vect

UART_RX_vect

USART1_RXC_vect

UART1_RXC_vect

USART1_RX_vect

UART1_RX_vect

and more . . .

Interestingly, all of them give me the 'misspelled' error except this one:

USART1_RX_vect

Which gives me this error:

Loaded plugin STK500

Loaded plugin AVR GCC

Loaded partfile: C:\Program Files\Atmel\AVR Tools\PartDescriptionFiles\ATmega640.xml

gcc plug-in: Error: Object file not found on expected location C:\My_Robots\Axon\Axon.elf

Make sure your makefile specifies the output .elf file as Axon.elf abcminiuser - Aug 04, 2008 - 07:57 AM

Post subject: Looking at the part header files, "USARTn_RX_vect" is the correct vector name, where "n" is 0 to 3 inclusive.

That error indicates other build problems (as the binaries weren't produced). Run a "make clean" and then a "make all", and post the compiler output.

- Dean Twisted Evil clawson - Aug 04, 2008 - 12:26 PM

Post subject: You could always simply give in on the "guessing game" and read the manual:

Page 89: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

http://www.nongnu.org/avr-libc/user-man ... rupts.html

The mega640 is listed (for RX vectors) against:

USART0_RX_vect

USART1_RX_vect

USART2_RX_vect

USART3_RX_vect

So it's no surprise that USART1_RX_vect "half worked" for you. As to the rest of the error, it's probably a link error in the build so switch back to the build tab to see what that was. robtotoreb - Aug 06, 2008 - 10:29 PM

Post subject: Does anyone have any code for receiving a string of characters (15 bytes in specific). Each string begins with 0x41 and ends with 0x0A. I am using interrupt driven receive. I have my code working where I can get the first character stored in my receive[0] array, but I cannot seem to figure out how to collect the other 14 bytes in the transmission and put them in receive[1]-receive[14]. Any help would be great. Also thanks for the tutorials and the informative posts; very helpful to people who are new and stuck! stefanny - Aug 26, 2008 - 07:35 PM

Post subject: I am using USART_RXC interrupt, when when an '1' arrives to the UDR it's saves in a register and then return to the cycle loop where It's compared where if its 0, sending zeros to the port c, if it's 1, go will to the label start and starts the adc, when the conversion ends interrupt and go to ISR end_conversion, and returns to where the flag ADIF is polls so if the UDR comes a new date of information it receives in the ISR of RXC is executed but fails to return to the cycle of comparison but again the cycle of poll flag ADIF, Which I can do to solve this?

This is a my code

.cseg

.include "m8535def.inc"

Page 90: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

.EQU fq=4000000 ; Xtal frequency

.EQU baud=9600 ; Baudrate

.EQU bdpresc=(fq/(16*baud))-1 ; Baud-Divider

.DEF c=R30 ; char.

;VECTOR DE INTERRUPCIONES****************************************************

.ORG 0x0000

rjmp RESET

rjmp EXT_INT0

rjmp EXT_INT1

rjmp TIM2_COMP

rjmp TIM2_OVF

rjmp TIM1_CAPT

rjmp TIM1_COMPA

rjmp TIM1_COMPB

rjmp TIM1_OVF

rjmp TIM0_OVF

rjmp SPI_STC

rjmp UART_RXC

rjmp UART_UDRE

rjmp UART_TXC

rjmp fin_de_conv; interrupt end of conversion

Page 91: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

rjmp EE_RDY

rjmp ANA_COMP

EXT_INT0: reti

EXT_INT1: reti

TIM2_COMP: reti

TIM2_OVF: reti

TIM1_CAPT: reti

TIM1_COMPA: reti

TIM1_COMPB: reti

TIM1_OVF: reti

TIM0_OVF: reti

SPI_STC: reti

UART_UDRE: reti

UART_TXC: reti

EE_RDY : reti

ANA_COMP: reti

UART_RXC:

in c, udr

OUT UDR, c

Page 92: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

reti

fin_de_conv:

cbi adcsra, adie

in r18, adch

out portc, r18

reti

Reset:

ldi r26, low (RAMEND)

out spl, r26

ldi r26, high (RAMEND)

out sph, r26

Page 93: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

ldi r26, 0xff ; port c outputs

Out ddrc, r26

ldi r26, 0x00 ; Port a inputs

out ddra, r26

;Configuraci�n USART *****************************************************

ldi r20, HIGH (bdpresc)

out UBRRH, r20

ldi r21, LOW (bdpresc)

out UBRRL, R21

ldi r16, 0b10011000 ; RXCIE, RX y Tx

out UCSRB, r16

ldi r16, 0b10000110 ;

out UCSRC, r16

;Configuraci�n ADC *******************************************************

ldi r26, 0b01111100 ; Aref = vcc, adlar=1, adc4+, adc2-

Page 94: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

out admux, r26

ldi r26, 0b10100101 ; prescaler = 32

out adcsra, r26

sei

loop:

Ldi r22, '1'

cpse c, r22

rjmp stop

rjmp start

stop:

cbi adcsra, adie

clr r17

out portc, r17

rjmp loop

start:

sbi adcsra, adsc

sbi adcsra, adie

Page 95: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

fincon:

sbis adcsra, adif

rjmp fincon

rjmp loop suriva - Oct 09, 2008 - 12:03 PM

Post subject: how i can avoid buffer overrun?? i try to send data full duplex (continues both from AVR to PC), but after 3-4 minutes my avr stop communication, because data overrun? any suggestion about using timeout when receive data (interrupt AVR - UART RX)? clawson - Oct 09, 2008 - 12:56 PM

Post subject: Well you either have to consume the data at a faster rate than it arrives or slow the rate at which it is arriving.

If you are currently polling the received data then implenting an Rx-interrupt may help things. DiodeDan - Oct 12, 2008 - 02:33 AM

Post subject: Dean,

So, now lets say we've gotten advanced and have our UART code working nicely. How does one go about making a clean interface for handiling the transmission of multiple data streams?

Quote:

communication ISRs are generally made short by receiving in characters via an ISR, and placing them into a buffer which the main code may read at its leisure. This ensures that received data will not be missed, while giving the main program time to complete what it is currently doing before having to process the input. Similarly, long transmissions may be made by placing the data to be sent into a buffer, and have an interrupt send the data as the hardware is ready while the main program performs other tasks.

Page 96: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

From what I understand, we create a transmission buffer in which the main loop will place data in. Then, when it is ready, the program sends the data in the transmit buffer by successively printing each character.

When I try to do this, I have issues, such as one transmission being overwritten by another, etc. Could you point out some ways to fix this problem? Would it be wise to use flags? Perhaps some kind of flag to prevent the UART from printing more data until the latest data has finished being sent? Your help is much appreciated.

Diode Dan abcminiuser - Oct 12, 2008 - 03:35 AM

Post subject: You need two ring buffers - one for reception and one for transmission. When transmitting, before adding the next byte to the buffer you need to spinloop until space is available. The TX USART interrupt then fetches the next byte out of the buffer when it is available and puts it into the UDR register to send it.

You need to trigger the start of the transmission - otherwise, the TX USART interrupt will not fire for the first time and nothing will happen.

I suggest you download my MyUSB project (http://www.fourwalledcubicle.com/MyUSB.php) and take a look at the "USBtoSerial" demo in the demos folder; you can ignore all the USB code and just focus on the buffering and serial transmission/reception. It implements the proper way to make buffered USART communications.

- Dean Twisted Evil

PS: Please excuse any incoherency in the above due to my slight inebriation. If something is unclear ask again - in an hour or two. clawson - Oct 12, 2008 - 12:31 PM

Post subject: Personally I've often found it sufficient to just use interrupts and a ring buffer for Rx then do the Tx sychronously hayashi_leo - Oct 19, 2008 - 09:13 PM

Post subject: Great tutorial, thanks! I implemented in the 90S8515, cannot wait to program it into STK500, I need to get a USB to RS232, first, osaka - Oct 25, 2008 - 05:03 AM

Post subject: the code in the begining of this tutorial without the interruptions worked on my atmega16, but the one with the interruptions seems to be sending random numbers.

I dont know why... vilvide2 - Nov 04, 2008 - 09:44 PM

Page 97: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Post subject: I can not complie the simple code that is placed in this tutorials.

can anyone tell me what is wrong.

Code:

#include <avr/io.h>

#include <avr/interrupt.h>

#define USART_BAUDRATE 9600

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

int main (void)

{

UCSRB |= (1 << RXEN) | (1 << TXEN); // Turn on the transmission and reception circuitry

UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes

UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register

UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register

UCSRB |= (1 << RXCIE); // Enable the USART Recieve Complete interrupt (USART_RXC)

sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed

for (;;) // Loop forever

{

// Do nothing - echoing is handled by the ISR instead of in the main loop

}

Page 98: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

}

ISR(USART_RXC_vect) //SIG_USART_RECV

{ //linie 25

char ReceivedByte;

ReceivedByte = UDR; // Fetch the recieved byte value into the variable "ByteReceived"

UDR = ReceivedByte; // Echo back the received byte back to the computer

}

warnings in studio 4

Code:

../interupt6.c:25: warning: return type defaults to `int'

../interupt6.c: In function `ISR':

../interupt6.c:25: warning: type of "USART_RXC_vect" defaults to "int"

../interupt6.c:31: warning: control reaches end of non-void function

[/b][b] abcminiuser - Nov 04, 2008 - 10:24 PM

Post subject: Looks like your version of avr-libc is out of date. What version of WinAVR do you have installed? If it's not the latest version from the WinAVR website, you need to update.

- Dean Twisted Evil vilvide2 - Nov 05, 2008 - 09:37 AM

Post subject: I have version AVR Studio 4.14.589, but I really dont know about the avr-libc.

Will it not be updated when the studio is updated??? JohanEkdahl - Nov 05, 2008 - 09:53 AM

Post subject:

Quote:

Page 99: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Will it not be updated when the studio is updated???

No. AVR Studio is something separate from the avr-gcc/avrlibc toolchain. The latter is easily updated on a Windows system by installing/upgrading WinAVR. clawson - Nov 05, 2008 - 09:57 AM

Post subject:

Quote:

but I really dont know about the avr-libc.

Will it not be updated when the studio is updated???

No, it gets updated when you manually download and install the latest WinAVR (which is 20080610 at present):

http://sourceforge.net/projects/winavr/ vilvide2 - Nov 05, 2008 - 10:19 AM

Post subject: yeeeeeeeeees......your guys are the best...thanks vilvide2 - Nov 05, 2008 - 03:08 PM

Post subject: now I allmost got it.

I cant figure out what to do with the

Code:

void check_RS232(void)

I know the name should not be Buffer_GetElement. but what should it be. see my code below. and what is the error releated to.??

compiler errors and warnings

Build started 5.11.2008 at 15:49:54

../ring1.c: In function 'check_RS232':

../ring1.c:112: warning: implicit declaration of function 'Buffer_GetElement'

../ring1.c:115: error: expected ';' before 'if'

Page 100: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

make: *** [ring1.o] Error 1

Build failed with 1 errors and 1 warnings...

Code:

/*

Simple Ringbuffer Library

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

(c) Dean Camera, 2005

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

[email protected]

This library allows you to implement a ringbuffer into your code

(useful for buffering FIFO data while the processor is busy)

via easy-to-use functions.

By changing the typedefs in RingBuff.h, you can change both the

datatype stored and the size of the buffer.

An error variable is exposed via extern to your program; if the

buffer is full when you try to store data bit 1 of the error

variable is set, and if you try to read an empty buffer bit 0 is

set. Both bits are cleared after a sucessful data store or read.

The error masks are avaliable via the defines BUFF_ERR_OVERFLOW

and BUFF_ERR_EMPTY.

Page 101: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Before it can be used, you must execute the "InitialiseBuffer"

routine. To store data, use the "StoreBuffByte" routine and for

reading data you use the "StoreBuffByte" routine.

The extern BuffElements variable holds the number of elements

in the buffer. This can be polled to check if the buffer is

empty or not.

The macro "ClearBuffError()" is defined in the RingBuff.h file

so you can clear the error variable manually if you wish.

[{ Feedback Appreciated }]

*/

#define USART_BAUDRATE 9600

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

// Includes:

#include <avr/io.h>

#include "RingBuff.h"

#include <avr/interrupt.h>

// Global Variables:

volatile BuffType *StoreLoc;

volatile BuffType *RetrieveLoc;

volatile BuffType RingBuffer[BuffLen];

Page 102: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

volatile ElemType BuffElements;

volatile unsigned char BuffError;

volatile uint8_t TotalRecLines;

int main (void)

{

BUFF_InitialiseBuffer();

UCSRB |= (1 << RXEN) | (1 << TXEN); // Turn on the transmission and reception circuitry

UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes

UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register

UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register

UCSRB |= (1 << RXCIE); // Enable the USART Recieve Complete interrupt (USART_RXC)

sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed

for (;;) // Loop forever

{

// Do nothing - echoing is handled by the ISR instead of in the main loop

}

Page 103: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

}

ISR(USART_RXC_vect) //SIG_USART_RECV

{

char c;

c = UDR; // Fetch the recieved byte value into the variable "ByteReceived"

//UDR = c; // Echo back the received byte back to the computer

if (c != '\r') // Ignore the \r in the standard \r\n sequence

return;

if (c == '\n') // Reached the \n in the \r\n sequence

{

TotalRecLines++; // Indicate that an entire line is ready

c = '\0'; // Null terminate

}

if (c>1)

{

BUFF_StoreBuffByte(c);

}

}

void check_RS232(void)

Page 104: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

{

char LineBuffer[100]; // Max line length is 100 bytes

if (TotalRecLines) // Wait for a whole line to be buffered before reading it out

{

char c;

uint8_t LineSize = 0;

do

LineBuffer[LineSize++] = Buffer_GetElement(&RingBuffer);

while ((c != '\0') && (LineSize != sizeof(LineBuffer)))

if (LineSize == LineBuffer) // Line too long//linie 115 for buffer

LineBuffer[sizeof(LineBuffer) - 1] = '\0'; // Terminate string

TotalRecLines--;

// LineBuffer now contains the next line from the USART - process it here

}

}

// Routines:

void BUFF_InitialiseBuffer(void)

{

Page 105: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

StoreLoc = (BuffType*)&RingBuffer; // Set up the IN pointer to the start of the buffer

RetrieveLoc = (BuffType*)&RingBuffer; // Set up the OUT pointer to the start of the buffer

BuffElements = 0; // Reset the buffer elements counter

}

void BUFF_StoreBuffByte(BuffType DataToStore)

{

if(BuffElements == BuffLen) // Buffer full

{

BuffError |= BUFF_ERR_OVERFLOW; // Set the "buffer full" error flag

return;

}

else // Sucessfull operation

{

BuffError = 0; // Clear the error variable

}

*StoreLoc = DataToStore; // Store the data

StoreLoc++; // Increment the IN pointer to the next element

BuffElements++; // Increment the total elements variable

Page 106: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

if (StoreLoc == (BuffType*)&RingBuffer[BuffLen])

StoreLoc = (BuffType*)&RingBuffer; // Wrap pointer if end of array reached

}

BuffType BUFF_GetBuffByte(uint8_t Pop)

{

if(!(BuffElements)) // No elements in the buffer

{

BuffError |= BUFF_ERR_EMPTY; // Set the "buffer empty" error flag

return 0;

}

else // Sucessfull operation

{

BuffError = 0; // Clear the error variable

}

BuffType RetrievedData = *RetrieveLoc; // Grab the stored byte into a temp variable

if (Pop)

{

RetrieveLoc++; // Increment the OUT pointer to the next element if flag set

BuffElements--; // Decrement the total elements variable

}

if (RetrieveLoc == (BuffType*)&RingBuffer[BuffLen])

Page 107: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

RetrieveLoc = (BuffType*)&RingBuffer; // Wrap pointer if end of array reached

return RetrievedData; // Return the retrieved data

}

Code:

Code:

vilvide2 - Nov 05, 2008 - 03:16 PM

Post subject: I mean how do I read out from

Code:

BuffType BUFF_GetBuffByte(uint8_t Pop)

rutine......I dont get it vilvide2 - Nov 06, 2008 - 07:40 AM

Post subject: adv ringbuffer hallo all

where to finde

Code:

#include <avr/atomic.h>

to use for the adv ring buffer???

BR clawson - Nov 06, 2008 - 10:49 AM

Post subject: RE: adv ringbuffer Try:

Code:

#include <util/atomic.h>

as described in the user manual:

Page 108: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

http://www.nongnu.org/avr-libc/user-man ... tomic.html vortex84 - Jan 14, 2009 - 12:40 PM

Post subject: Usart interrupt Hi, I'm just a noob using AVR.. From what i know ISR do not allow any argument to be pass and do not return anything. How do you normally pass data receive by USART interrupt to be read by another function? I tried using structure but no luck.. Thanks in advance. clawson - Jan 14, 2009 - 12:57 PM

Post subject: RE: Usart interrupt Well here's a mad, wild, whacky, off-the-wall idea - why not try reading this thread?

Did the "ReceivedByte" Dean uses not ring any bells as a mechanism for returning a value from an ISR (basically write something 'global' in the ISR, read it in the main() loop)?

The extension of this is then a ring buffer where rather than just ReceiveByte you keep a whole array and separate Write and Read pointers to it.

Cliff JohanEkdahl - Jan 14, 2009 - 03:13 PM

Post subject: RE: Usart interrupt

Quote:

I tried using structure but no luck..

Did you declare the struct volatile? If not then read FAQ#1 in Cliff's footer above, and then move on to the avr-libc FAQ proper to read the explanation (also item #1). clawson - Jan 14, 2009 - 03:22 PM

Post subject: RE: Usart interrupt

Quote:

and then move on to the avr-libc FAQ proper to read the explanation (also item #1).

The quick route there is to click on my signature. nedsana - Mar 09, 2009 - 03:42 PM

Post subject: USART Hallo there. This was a great tutorial, and I had a great use of it.

But now I've made a communication, which behaves really strange. This is what I mean:

Page 109: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

I have Atmega32 with 16MHz external crystal(I have set the fuse on the bottom of the list, i can't remember its name). I want to communicate with 9600bps and it should be interrupt driven.

I use a simple way of communication. I send a character from PC, use the Rx ISR to handle it, and send back a character('!' in my case) by Tx ISR.

I use MATLAB in my PC to connect to the MCU. There I have a loop which is waiting for the '!' and when it receives it I send another character.

This is a breaf description of my idea.

Now the problem. The communication starts, but after I send some characters (1,2,3 different all the time) the communication hangs up. Matlab says 'A Timeout occured...'. The MCU goes on working properly though.

Can the problem be caused by the errors in the baud rates? I placed the code on an ATMEGA16 board with 7.3728MHz and it is working perfect, no timeouts.

This is the code, but the comments are not written in an english language:):

#include "avr/io.h"

#include "avr/interrupt.h"

#include "avr/eeprom.h"

//1. Inicializaciq na EEPROM

#define EEMEM __attribute__((section(".eeprom")))

unsigned char symbols[159][5] EEMEM=

{0x00,0x00,0x00,0x00,0x00, // sp sh indeks 0

0x00,0x30,0x7d,0x30,0x00, // ! sh 1

0x00,0x70,0x00,0x70,0x00, // " sh 2

0x14,0x7f,0x14,0x7f,0x14, // # sh 3

0x12,0x2a,0x7f,0x2a,0x24, // $ sh 4

Page 110: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

0x62,0x64,0x08,0x13,0x23, // % sh 5

0x36,0x49,0x55,0x22,0x05, // & sh 6

0x00,0x50,0x60,0x00,0x00, // ' sh 7

0x00,0x1c,0x22,0x41,0x00, // ( sh 8

0x00,0x41,0x22,0x1c,0x00, // ) sh 9

0x14,0x08,0x3e,0x08,0x14, // * sh 10

0x08,0x08,0x3e,0x08,0x08, // + sh 11

0x00,0x05,0x06,0x00,0x00, // , sh 12

0x04,0x04,0x04,0x04,0x04, // - sh 13

0x00,0x00,0x03,0x00,0x00, // . sh 14

0x02,0x04,0x08,0x10,0x20, // / sh 15

0x3e,0x45,0x49,0x51,0x3e, // 0 sh 16

0x00,0x21,0x7f,0x01,0x00, // 1 sh 17

0x21,0x43,0x45,0x49,0x31, // 2 sh 18

0x42,0x42,0x51,0x69,0x46, // 3 sh 19

0x0c,0x14,0x24,0x7f,0x04, // 4 sh 20

0x72,0x51,0x51,0x51,0x4e, // 5 sh 21

0x1e,0x29,0x49,0x49,0x06, // 6 sh 22

0x40,0x47,0x48,0x50,0x60, // 7 sh 23

0x36,0x49,0x49,0x49,0x36, // 8 sh 24

0x30,0x49,0x49,0x4a,0x3c, // 9 sh 25

0x00,0x36,0x36,0x00,0x00, // : sh 26

0x00,0x35,0x36,0x00,0x00, // ; sh 27

0x08,0x14,0x22,0x41,0x00, // < sh 28

0x14,0x14,0x14,0x14,0x14, // = sh 29

0x00,0x41,0x22,0x14,0x08, // > sh 30

0x20,0x40,0x45,0x48,0x30, // ? sh 31

Page 111: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

0x26,0x49,0x4f,0x41,0x3e, // @ sh 32

0x3f,0x44,0x44,0x44,0x3f, // A sh 33

0x7f,0x49,0x49,0x49,0x36, // B sh 34

0x3e,0x41,0x41,0x41,0x22, // C sh 35

0x7f,0x41,0x41,0x22,0x1c, // D sh 36

0x7f,0x49,0x49,0x49,0x41, // E sh 37

0x7f,0x48,0x48,0x48,0x40, // F sh 38

0x3e,0x41,0x49,0x49,0x2f, // G sh 39

0x7f,0x08,0x08,0x08,0x7f, // H sh 40

0x00,0x41,0x7f,0x41,0x00, // I sh 41

0x02,0x01,0x41,0x7e,0x40, // J sh 42

0x7f,0x08,0x14,0x22,0x41, // K sh 43

0x7f,0x01,0x01,0x01,0x01, // L sh 44

0x7f,0x20,0x18,0x20,0x7f, // M sh 45

0x7f,0x10,0x08,0x04,0x7f, // N sh 46

0x3e,0x41,0x41,0x41,0x3e, // O sh 47

0x7f,0x48,0x48,0x48,0x30, // P sh 48

0x3e,0x41,0x45,0x41,0x3e, // Q sh 49

0x7f,0x48,0x4c,0x4a,0x31, // R sh 50

0x31,0x49,0x49,0x49,0x46, // S sh 51

0x40,0x40,0x7f,0x40,0x40, // T sh 52

0x7f,0x01,0x01,0x01,0x7f, // U sh 53

0x7c,0x02,0x01,0x02,0x7c, // V sh 54

0x7f,0x01,0x0e,0x01,0x7f, // W sh 55

0x63,0x14,0x08,0x14,0x63, // X sh 56

0x70,0x08,0x70,0x08,0x70, // Y sh 57

0x43,0x45,0x49,0x51,0x61, // Z sh 58

Page 112: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

0x00,0x7f,0x41,0x41,0x00, // [ ok 59

0x20,0x10,0x08,0x04,0x02, // \ ok 60

0x00,0x41,0x41,0x7f,0x00, // ] sh 61

0x10,0x20,0x40,0x20,0x10, // ` sh 62

0x01,0x01,0x01,0x01,0x01, // _ sh 63

0x00,0x40,0x20,0x10,0x00, // ` sh 64

0x02,0x15,0x15,0x15,0x0f, // a sh 65

0x7f,0x09,0x11,0x11,0x0e, // b sh 66

0x0e,0x11,0x11,0x11,0x02, // c sh 67

0x0e,0x11,0x11,0x09,0x7f, // d sh 68

0x0e,0x15,0x15,0x15,0x0c, // e sh 69

0x08,0x3f,0x48,0x40,0x20, // f sh 70

0x18,0x25,0x25,0x25,0x3e, // g sh 71

0x7f,0x08,0x10,0x10,0x0f, // h sh 72

0x00,0x11,0x5f,0x01,0x00, // i sh 73

0x02,0x01,0x11,0x5e,0x00, // j sh 74

0x7f,0x04,0x0a,0x11,0x00, // k sh 75

0x00,0x41,0x7f,0x01,0x00, // l sh 76

0x1f,0x10,0x0C,0x10,0x0f, // m sh 77

0x1f,0x08,0x10,0x10,0x0f, // n sh 78

0x0e,0x11,0x11,0x11,0x0e, // o sh 79

0x1f,0x14,0x14,0x14,0x08, // p sh 80

0x08,0x14,0x14,0x0c,0x1f, // q sh 81

0x1f,0x08,0x10,0x10,0x08, // r sh 82

0x09,0x15,0x15,0x15,0x02, // s sh 83

0x10,0x7f,0x11,0x01,0x02, // t sh 84

0x1e,0x01,0x01,0x02,0x1f, // u sh 85

Page 113: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

0x1c,0x02,0x01,0x02,0x1c, // v sh 86

0x1e,0x01,0x06,0x01,0x1e, // w sh 87

0x11,0x0a,0x04,0x0a,0x11, // x sh 88

0x18,0x05,0x05,0x05,0x1e, // y sh 89

0x11,0x13,0x15,0x19,0x11, // z sh 90

0x00,0x08,0x36,0x41,0x00, // { sh 91

0x00,0x00,0x7f,0x00,0x00, // | sh 92

0x00,0x41,0x36,0x08,0x00, // } sh 93

0x20,0x40,0x20,0x10,0x20, // ~ sh index 94

//Kirilica Glavni

0x3f,0x44,0x44,0x44,0x3f,// A sh index 95

0x7f,0x49,0x49,0x49,0x06,// � sh 96

0x7f,0x49,0x49,0x49,0x36,// � sh 97

0x7f,0x40,0x40,0x40,0x40,// � sh 98

0x03,0x7f,0x42,0x42,0x7f,// � sh 99

0x7f,0x49,0x49,0x49,0x41,// E sh 100

0x63,0x14,0x7f,0x14,0x63,// � sh 101

0x42,0x41,0x51,0x69,0x46,// � sh 102

0x7f,0x04,0x08,0x10,0x7f,// � sh 103

0x7f,0x04,0x48,0x10,0x7f,// � sh 104

0x7f,0x08,0x14,0x22,0x41,// � sh 105

0x1f,0x20,0x40,0x20,0x1f,// � sh 106

0x7f,0x20,0x18,0x20,0x7f,// M sh 107

0x7f,0x08,0x08,0x08,0x7f,// H sh 108

0x3e,0x41,0x41,0x41,0x3e,// O sh 109

0x7f,0x40,0x40,0x40,0x7f,// � sh 110

0x7f,0x48,0x48,0x48,0x30,// � sh 111

Page 114: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

0x3e,0x41,0x41,0x41,0x22,// � sh 112

0x40,0x40,0x7f,0x40,0x40,// T sh 113

0x7f,0x09,0x09,0x09,0x7f,// � sh 114

0x1c,0x14,0x7f,0x14,0x1c,// � sh 115

0x63,0x14,0x08,0x14,0x63,// X sh 116

0x7f,0x02,0x02,0x7f,0x03,// � sh 117

0x78,0x08,0x08,0x08,0x7f,// � sh 118

0x7f,0x01,0x7f,0x01,0x7f,// � sh 119

0x7e,0x02,0x7e,0x02,0x7f,// � sh 120

0x40,0x7f,0x11,0x11,0x0e,// � sh 121

0x7f,0x11,0x11,0x0e,0x7f,// � sh 122

0x7f,0x11,0x11,0x11,0x0e,// � sh 123

0x22,0x41,0x49,0x49,0x3e,// � sh 124

0x7f,0x08,0x3e,0x41,0x3e,// � sh 125

0x39,0x46,0x44,0x44,0x7f,// � sh 126

//Kirilica malki

0x02,0x15,0x15,0x15,0x0f,// a sh 127

0x66,0x59,0x49,0x49,0x46,// � sh 128

0x3e,0x49,0x49,0x39,0x06,// � sh 129

0x02,0x15,0x15,0x15,0x09,// � sh 130

0x26,0x49,0x49,0x49,0x3e,// � sh 131

0x0e,0x15,0x15,0x15,0x0c,// � sh 132

0x1b,0x04,0x1f,0x04,0x1b,// � sh 133

0x11,0x15,0x15,0x15,0x0a,// � sh 134

0x1e,0x01,0x01,0x02,0x1f,// � sh 135

0x1e,0x41,0x21,0x41,0x1f,// � sh 136

Page 115: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

0x1f,0x04,0x0a,0x11,0x00,// � sh 137

0x01,0x1e,0x10,0x10,0x1f,// � sh 138

0x0f,0x10,0x0c,0x10,0x0f,// � sh 139

0x1f,0x04,0x04,0x04,0x1f,// � sh 140

0x0e,0x11,0x11,0x11,0x0e,// � sh 141

0x1f,0x08,0x10,0x10,0x0f,// � sh 142

0x1f,0x14,0x14,0x14,0x08,// � sh 143

0x0e,0x11,0x11,0x11,0x02,// � sh 144

0x10,0x10,0x1f,0x10,0x10,// � sh 145

0x18,0x05,0x05,0x05,0x1e,// � sh 146

0x0c,0x12,0x7f,0x12,0x0c,// � sh 147

0x11,0x0a,0x04,0x0a,0x11,// � sh 148

0x1c,0x02,0x02,0x1c,0x03,// � sh 149

0x1c,0x02,0x02,0x04,0x1f,// � sh 150

0x1e,0x01,0x1f,0x01,0x1f,// � sh 151

0x1c,0x02,0x1e,0x02,0x1f,// � sh 152

0x10,0x1f,0x05,0x05,0x02,// � sh 153

0x1f,0x05,0x05,0x02,0x1f,// � sh 154

0x1f,0x05,0x05,0x02,0x00,// � sh 155

0x02,0x11,0x15,0x15,0x0e,// � sh 156

0x1f,0x04,0x0e,0x11,0x0e,// � sh 157

0x09,0x16,0x14,0x1f,0x00// � sh index 158

};

#define CLOCK 0x35//zadavam clock kam hc595

#define SERIAL 0x05//zadavam vreme za podavane na serien signal kam hc595

#define PWM 0x05//tazi stoinost otgovarq na vremeto v koeto 6te sveti 1 led.

Page 116: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

#define SPEED 0x0000a000//opredelq skorostta na dvigenie. Za iz4islqvane na velocity

#define STAND 0x00100000//opredelq vremeto na nepodvigno sastoqnie na nadpisa

#define ROWS_passed 0x30//tova e broqt na redovete, koito trbva da se sledi a da se obnovi ekrana s nepodvigno saob6tenie

//RAZMERI NA SAOB6TENIETO KOETO SAHRANQVAM V MCU

#define ROW 0x0a//saob6tenie ot 10 reda

#define COL 0x19//25 bukvi na red

//Upravlenie na 74hc595 i portovete

unsigned char clocks=0x00;//broi kolko clock-a sa pusnati kam clock vhodovete na hc595

unsigned char write=0x00;//sledi dvigenieto na impulsa podaden kam hc595, koito obhogda kolonite na ekrana

unsigned char next595=0x00;//pokazva koga nastapva prehoda megdu dva sasedni hc595

unsigned char light_on=0x00;//pokazva koga trqbva da pusnem funkciqta PORT_ctrl

//SAOB6TENIE

unsigned char message[ROW][COL];//tova e saob6tenieto sahraneno kato char stoinosti

unsigned char mess_y=0x00;

unsigned char mess_x=0x00;

unsigned char mess_ind_x=0x00;//pokazva poziciqta do koqto sme stignali pri zapisvaneto v message po horizontala

unsigned char mess_ind_y=0x00;//pokazva poziciqta do koqto sme stignali pri zapisvaneto v message po vretikala

long int repeat=0x00000000;//pokazva kolko pati 6te se izpi6e vseki ot ekranite display_1/2 predi da se prehvarlim kam drugiq

Page 117: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

unsigned char mode=0x01;//tazi promenliva opredelq regima na rabota (dvigenie mode=0x00 nagore, mode=0x01 nadolu, mode=0x02 nalqvo i mode=0x00 nadqsno)

unsigned char disp=0x01;//kogato disp=1, zna4i display_1 e popalnen

//kogato disp=2, zna4i display_2 e popalnen

unsigned char display_1[0x06][0x7d];//tova sa dvata masiva koito sadargat obraza na ekrana

unsigned char display_2[0x06][0x7d];

unsigned char ctrl=0x00;//pokazva dali po serijniq port sledva da se podade komanda za upravlenie na displeq

unsigned char brightness=0x00;//pokazva kakva e qrkostta na izobragenieto

//promenlivi za kontrol na skorostta na dvigenie i za zadargane na obraza

//unsigned int velosity=SPEED;//pokazva kakva e skorostta na dvigenie na izobragenieto po ekrana

long int still=0x00;//pokazva kolko vreme nadpisat 6te stoi nepodvigen kogato se izpolzva regimat za zadargane na obraza

long int velosity=SPEED;

long int stat=STAND;

unsigned char to_go=0x00;//broi kolko reda sme preminali pri dvigenieto po vertikala predi za zadargim obraza

void init(void)

{

unsigned char i;

unsigned char j;

for(i=0x00;i<ROW;i++)

{

for(j=0x00;j<COL;j++)

Page 118: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

{

message[i][j]=0x00;

//message[i][j]=0x00;

}

}

//inicializiram display_1 i display_2

for(i=0x00;i<0x06;i++)

{

for(j=0x00;j<0x7d;j++)

{

//display_1[i][j]=0b01010101;

//display_2[i][j]=0b01010101;

display_1[i][j]=0x00;

display_2[i][j]=0x00;

}

}

//izhodni portove

DDRB=0xff;

PORTB=0x00;

DDRD=0xff;

PORTD=0b00100000;

DDRA=0xff;

PORTA=0x00;

//DDRC=0xff;

//PORTC=0x00;

Page 119: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

//puskam taimer 0 na prescaler /8. Izpolzva se za 6IM na didoite.

TCCR0=0b00000010;

//nastroivam taimer 2 za funkciqta delay

TCCR2=0b00000010; //8

//Taimer 1 se nastroiva da dava clock kam 595ta i data send kam 595.

//Nastroivam TIMER1 v regim NORMAL

TCCR1A=0x00;

TCCR1B=0b00000010;//x8 prescaler

TCNT1H=0x00;

TCNT1L=0x00;

OCR1AH=0x01;

OCR1AL=CLOCK;

//tozi registyr e ob6t za trite taimera

TIMSK=0b00010000;

//razre6avam zapis v EEPROM

EECR=0b00000011;

//RS232 setting

//1. nastroivame boad rate 9600 pri 16MHz

UBRRL=0x67;

//2.

UCSRA=0x00;

//3. nastroivame recieve, i interrupt pri receive, transmit disable i ne razre6avame prekasvane pri izprazvane na UDR

UCSRB=0b10010000;

//4. nastroivame 8bit duma, asinhronen regim, 1 stop bit,

Page 120: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

UCSRC=0b10000110;

/* //TWI nastroiki

TWBR=0xf2;//4estotata na clock-a za predavbane na danni e CPU_frequency/(16+2*TWBR*4^0)=16*10^6/500=46666Hz

TWSR=0b00000000;//bez prescaler

TWAR=0b00000011;//adresa na MCU. LSB pokazva 4e e pozvolen regima na GENERAL CALL

TWCR=0b00000101;//tova e kontrolniq registar. Dvata setnati bita pokazvat 4e sme

//pozvolili rabotata na interfeisa i sme razre6ili prekasvaneto. Tova e master regim

//TWCR=0b01000101;//tova sa nastroikite za slave regim

*/

sei();

}

//tazi funkciq puska taimer2 za da zadava vremeto, v koeto seriiniqt signal e v 1

void delay(unsigned int time)

{

TCNT2=0x00;

while(TCNT2<time)

{}

TCNT2=0x00;

}

//paramteri za funkciqta sa kolonite ot display_x masivite i led_on_x masivite

void PORT_ctrl(unsigned char b1, unsigned char a1, unsigned char cd1, unsigned char b2, unsigned char a2, unsigned char cd2)

Page 121: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

{

unsigned char c=0x00;

unsigned char d=0x00;

unsigned char hold_SREG;

hold_SREG=SREG;//zapazvam status registara

cli();//zabranqvam prekasvaniqta

//c=cd1;

//d=cd1;

//c = cd1 & 0b11111100;

//c = cd1 | c;

//d = cd1 & 0b00000011;

//d = cd1 | d;

PORTB=b1;

PORTA=a1;

//PORTC=c;

//PORTD=d;

SREG=hold_SREG;

sei();

}

void leds_on(unsigned char content[0x06][0x7d])

Page 122: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

{

PORT_ctrl(content[0x00][write],content[0x01][write],content[0x02][write],content[0x03][write],content[0x04][write],content[0x05][write]);

light_on=0x00;

if(write==0x40)

{

write=0x00;

}

}

ISR(TIMER1_COMPA_vect)

{

unsigned char hold_SREG;

unsigned char temp=0x00;

hold_SREG=SREG;//zapazvam status registara

cli();//zabranqvam prekasvaniqta

//1. Proverqvam sastoqnieto na PORTD 5

temp=PORTD;

temp=temp & 0b00100000;

if(temp==0x00)//ako do momenta e bil v nisko nivo podavam impuls i go slagam vav visoko nivo

{

clocks++;

if(clocks>=2 && clocks<=65)

Page 123: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

{

write++;

//light_on=0x01;

}

if(clocks==66)

{

//vdigam bit na DATA SEND

PORTD = PORTD & 0b11101111;

PORTD = PORTD | 0b00010000;

//4akam

delay(SERIAL);

//vdigam bit na CLOCK

PORTD=PORTD & 0b11011111;

PORTD=PORTD | 0b00100000;

//4akam

delay(SERIAL);

//svalqm bit na DATA SEND

PORTD = PORTD & 0b11101111;

PORTD = PORTD | 0b00000000;

clocks=0x00;

}

else

{

//PORTA=0x00;

//PORTB=0x00;

Page 124: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

PORTD=PORTD & 0b11011111;

PORTD=PORTD | 0b00100000;

PORTA=0x00;

PORTB=0x00;

if(disp==0x01)

{

leds_on(display_1);

}

else

{

leds_on(display_2);

}

}

}

else//ako do momenta sam bil vav visoko nivo, minavam v nisko

{

PORTD=PORTD & 0b11011111;

PORTD=PORTD | 0b00000000;

}

TCNT1H=0x00;

TCNT1L=0x00;

SREG=hold_SREG;

Page 125: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

sei();

}

unsigned char shift(unsigned char in1, unsigned char in2, unsigned char direction)

{

unsigned char temp=0x00;

unsigned char temp1=0x00;

switch(direction)

{

case 0x00:

//2. poplvam display_1 - obhogdam po koloni, vzimam element i shift nagore

temp=in1;//premestvam sadarganieto na byta

temp=temp<<0x01;//s edna poziciq

temp1=in2;//vzimam sledva6tiq byte

temp1=temp1>>0x07;//shift na MSB na mqstoto na LSB

temp=temp & 0b11111110;//promenqm sadarganieto na LSB ot byta, koito premestvame

temp=temp | temp1;

break;

case 0x01:

//2. poplvam display_1 - obhogdam po koloni, vzimam element i shift nagore

temp=in1;//premestvam sadarganieto na byta

temp=temp>>0x01;//s edna poziciq

temp1=in2;//vzimam sledva6tiq byte

temp1=temp1<<0x07;//shift na LSB na mqstoto na MSB

temp=temp & 0b01111111;//promenqm sadarganieto na MSB ot byta, koito premestvame

temp=temp | temp1;

Page 126: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

break;

}

return temp;

}

unsigned char row49(unsigned char addr, unsigned char mask, unsigned char in, unsigned char direction)

{

unsigned char temp,temp1;

switch(direction)

{

case 0x00:

temp=eeprom_read_byte((uint8_t*)addr);//tova e kolonata ot bukvata

temp=temp >> mask;//premestvam sadarganieto na temp bita koito 6te vliza na poziciq 0

temp=temp & 0b00000001;

temp=temp | 0b00000000;

temp1=in;

temp1=temp1 & 0b11111110;//6te promenqm samo bit 0 ot kolonata v display_2

temp1=temp1 | temp;//promenqm bita

break;

case 0x01:

temp=eeprom_read_byte((uint8_t*)addr);//tova e kolonata ot bukvata

temp=temp << mask;//premestvam sadarganieto na temp bita koito 6te vliza na poziciq 7

temp=temp & 0b10000000;

temp=temp | 0b00000000;

temp1=in;

Page 127: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

temp1=temp1 & 0b01111111;//6te promenqm samo bit 0 ot kolonata v display_2

temp1=temp1 | temp;//promenqm bita

break;

}

return temp1;

}

//iztrivame saob6tenieto

void clear_mess(void)

{

unsigned char i,j;

for(i=0x00;i<ROW;i++)

{

for(j=0x00;j<COL;j++)

{

message[i][j]=0x00;

}

}

mess_ind_x=0x00;

mess_ind_y=0x00;

}

//tazi funkciq opredelq dali po RS232 idva komanda ili bukva

void is_ctrl(unsigned char in)

{

Page 128: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

if(ctrl!=0x00)

{

switch(ctrl)

{

case 0x06://skorost

velosity=in;

ctrl=0x00;

break;

case 0x07://qrkost

brightness=in;

ctrl=0x00;

break;

case 0x08://zadragane

stat=in;

ctrl=0x00;

break;

}

}

}

//funkciqta se izpolzva za popalvane na bukvite

void get_char(unsigned char in)

{

if(mess_ind_y<ROW)//ako sam v ramkite na saob6tenieto

{

Page 129: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

if(mess_ind_x<COL)//ako sam v ramkite na reda

{

if(in>=0x20 || in<=0x7e)//ako podavam bukva na latinica

{

message[mess_ind_y][mess_ind_x]=in-0x20;

}

else//ako podavam bukva na kirilica

{

message[mess_ind_y][mess_ind_x]=in;

}

mess_ind_x++;

}

else//ako reda svar6i

{

mess_ind_y++;

if(in>=0x20 || in<=0x7e)//ako podavam bukva na latinica

{

message[mess_ind_y][0x00]=in-0x20;

}

else//ako podavam bukva na kirilica

{

message[mess_ind_y][0x00]=in;

}

mess_ind_x=0x01;

}

}

else

Page 130: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

{

message[0x00][0x00]=in;

mess_ind_x=0x01;

mess_ind_y=0x00;

}

}

//funkciqta se izpolzva za zapisvane na novoto saob6tenie.

void load(unsigned char in)

{

switch(in)

{

case 0x1c://ako e izprateno 28, zna4i sme stignali do kraq na saob6tenieto, prekratqvame komunikaciqta

break;

default:

get_char(in);

break;

}

}

//prekasvaneto za seriniq interfeis

ISR(USART_RXC_vect)

{

unsigned char temp;

Page 131: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

unsigned char stat_reg=0x00;

stat_reg=SREG;

cli();

temp=0x00;

temp=UDR;

is_ctrl(temp);//ako ctrl=0x00, ne pravim ni6to. Ina4e promenqm skorostta, qrkostta ili zadarganeto

switch(temp)

{

case 0x01://mode 0x01 - dvigenie nagore

mode=0x01;

break;

case 0x02://mode 0x02 - dvigenie nadolu

mode=0x02;

break;

case 0x03://mode 0x03 - dvigenie nalqvo

mode=0x03;

break;

case 0x04://mode 0x04 - dvigenie nadqsno

mode=0x04;

break;

Page 132: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

case 0x05://mode 0x05 - stati4en regim

mode=0x05;

break;

case 0x1b://ako e izprateno 27, zna4i iskame da iztriem saob6tenieto

clear_mess();

ctrl=0x00;

break;

case 0x06://upravlenie na skorostta

ctrl=0x06;

break;

case 0x07://upravlenie na qrkostta

ctrl=0x07;

break;

case 0x08://upravlenie na zadarganeto na teksta v neopdvigno sastoqnie

ctrl=0x08;

break;

default://default se izpolzva kogato podavame bukvi

if(temp!=0x0a)//ako e podaden0 10, zna4i e inicializirana komunikaciqta

{

load(temp);//ako e podadeno ne6to razli4no ot 10, zna4i trbva da zapi6em bukvata

}

Page 133: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

break;

}

//razre6avam 'transmit' i 'transmit interrupt', a zabranqvam 'receive' i 'receive interrupt'

UCSRB=0b01001000;

temp=0x21;

UDR=temp;

SREG=stat_reg;

sei();

}

ISR(USART_TXC_vect)

{

unsigned char stat_reg=0x00;

stat_reg=SREG;

cli();

//zabranqvam 'transmit' i 'transmit interrupt', a pozvolqvam 'receive' i 'receive interrupt'

UCSRB=0b10010000;

SREG=stat_reg;

sei();

}

void main(void)

Page 134: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

{

unsigned char i;

unsigned char offset=0x00;//tova e promenlivata koqto obhogda elementa ot tablicata v EEPROM PO KOLONI

unsigned char mask=0x07;//tazi promenliva sledi bita koito 6te vliza kam ekrana

unsigned char buffer_ready=0x00;//kogato display_1 ili display_2 se popalnqt, setvame tazi promenliva

unsigned char column=0x00;//tazi promenliva se izpolzva pri popalvane na display_x, za opredelqne na kolonata varhu koqto rabotim

init();

while(1)

{

switch(mode)

{

case 0x01:

PORT_ctrl(0x01,0x01,0x01,0x01,0x01,0x01);

break;

case 0x02:

PORT_ctrl(0x02,0x02,0x02,0x02,0x02,0x02);

break;

case 0x03:

PORT_ctrl(0x04,0x04,0x04,0x04,0x04,0x04);

break;

case 0x04:

PORT_ctrl(0x08,0x08,0x08,0x08,0x08,0x08);

break;

}

Page 135: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

}

} superchiku - Mar 12, 2009 - 07:14 PM

Post subject: RE: USART i followed ur tutorial and wrote thos code...to switch on a led when i send a from hyperterminal and switch off the led when i send d from hyper terminal but no matter wat i send iam not able to control the led coz it keeps on blinking as given in the default program bfore any serial commands are sent

plzz check my code...iam running my cpu at 8mhz internal oscillator

Code:

#include <avr/io.h>

#include <avr/interrupt.h>

#include <util/delay.h>

#define USART_BAUDRATE 38400

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

volatile int f=0;

void portinitialize();

void uartinitialize();

void handleleft();

void handleright();

void bytedecision(volatile unsigned char);

void portinitialize()

{

DDRD|=(1<<4);

Page 136: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

TCCR1B|=(1<<CS12);

}

void uartinitialize()

{

UCSRB |= (1 << RXEN) | (1 << TXEN); // Turn on the transmission and reception circuitry

UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes

UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register

UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register

UCSRB |= (1 << RXCIE); // Enable the USART Recieve Complete interrupt (USART_RXC)

sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed

}

void handleleft()

{

int m=0;

PORTD&=~(1<<4);

for(m=0;m<=100;m++)

_delay_ms(10);

}

void handleright()

{

int m=0;

Page 137: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

PORTD|=(1<<4);

for(m=0;m<=100;m++)

_delay_ms(10);

}

void bytedecision(volatile unsigned char a)

{

if(a=='a' || a=='A')

{

handleleft();

}

if(a=='d' || a=='D')

{

handleright();

}

}

int main (void)

{

portinitialize();

uartinitialize();

for(;;) // Loop forever

{

if(f==0)

Page 138: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

{

if(TCNT1>=31250)

{

PORTD^=(1<<4); // run test program blinking- echoing is handled by the ISR instead of in the main loop

TCNT1=0;

}

}

}

}

ISR(USART_RXC_vect)

{

f=1;

volatile unsigned char ReceivedByte;

ReceivedByte = UDR; // Fetch the recieved byte value into the variable "ByteReceived"

//UDR = ReceivedByte; // Echo back the received byte back to the computer

bytedecision(ReceivedByte);

}

superchiku - Mar 12, 2009 - 07:16 PM

Post subject: RE: USART i followed ur tutorial and wrote thos code...to switch on a led when i send a from hyperterminal and switch off the led when i send d from hyper terminal but no matter wat i send iam not able to control the led coz it keeps on blinking as given in the default program bfore any serial commands are sent

Page 139: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

plzz check my code...iam running my cpu at 8mhz internal oscillator

Code:

#include <avr/io.h>

#include <avr/interrupt.h>

#include <util/delay.h>

#define USART_BAUDRATE 38400

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

volatile int f=0;

void portinitialize();

void uartinitialize();

void handleleft();

void handleright();

void bytedecision(volatile unsigned char);

void portinitialize()

{

DDRD|=(1<<4);

TCCR1B|=(1<<CS12);

}

void uartinitialize()

Page 140: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

{

UCSRB |= (1 << RXEN) | (1 << TXEN); // Turn on the transmission and reception circuitry

UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes

UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register

UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register

UCSRB |= (1 << RXCIE); // Enable the USART Recieve Complete interrupt (USART_RXC)

sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed

}

void handleleft()

{

int m=0;

PORTD&=~(1<<4);

for(m=0;m<=100;m++)

_delay_ms(10);

}

void handleright()

{

int m=0;

PORTD|=(1<<4);

for(m=0;m<=100;m++)

_delay_ms(10);

Page 141: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

}

void bytedecision(volatile unsigned char a)

{

if(a=='a' || a=='A')

{

handleleft();

}

if(a=='d' || a=='D')

{

handleright();

}

}

int main (void)

{

portinitialize();

uartinitialize();

for(;;) // Loop forever

{

if(f==0)

{

if(TCNT1>=31250)

Page 142: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

{

PORTD^=(1<<4); // run test program blinking- echoing is handled by the ISR instead of in the main loop

TCNT1=0;

}

}

}

}

ISR(USART_RXC_vect)

{

f=1;

volatile unsigned char ReceivedByte;

ReceivedByte = UDR; // Fetch the recieved byte value into the variable "ByteReceived"

//UDR = ReceivedByte; // Echo back the received byte back to the computer

bytedecision(ReceivedByte);

}

nilswinkelmans - Apr 24, 2009 - 12:44 PM

Post subject: Hello,

I am using an atmega128. I have copied the program to avr but does anybody know how I can use 2 USART's at the same time. I want to connect a compas to UART0 and my pc on UART1. The meaning is that I can read the input on UART0(compas) via UART1(pc).

You can find my program in an attachement. abcminiuser - Apr 26, 2009 - 07:32 AM

Post subject: nilswinkelmans,

You need to append the USART number to the end of the register names (before any suffixes):

Page 143: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Code:

UCSRB

Becomes:

Code:

UCSR0B

For the first USART for example, or:

Code:

UCSR1B

For the second. You also need to change the ISR vector name to include the USART you are referencing:

Code:

ISR(USART_RXC_vect)

Becomes:

Code:

ISR(USART0_RXC_vect)

Page 144: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

For the first USART. You need to initialise and control each USART separately in the same way as the tutorial.

- Dean Twisted Evil tamamontu - May 13, 2009 - 03:17 AM

Post subject: nice tutorial...

i liked the idead of having 2 buffers for line processing.. if you want to implement help/configure menu... jwagner18 - Jun 04, 2009 - 09:17 PM

Post subject: I am trying to create a program that will receive a command from user via RS-232 port (eg. 'B1' ended with a carriage return). I want to store that command in a variable so that I can compare it to a predefined list of commands and output the correct response. I am not sure how to read in the command so that I can do my comparison. clawson - Jun 05, 2009 - 09:37 AM

Post subject: Start by setting up an RXC interrupt that populates a circular buffer, then you'll also have a getchar() style routine that just pulls characters after the buffer. As you strings are <CR> terminated then just loop doing getchar()s until you get '/r' (or possibly '/n') then strstr() the received string against each command.

Cliff ijcoxf - Jun 15, 2009 - 03:34 PM

Post subject: Hello Dean,

Would it be easy to make a version of your USART interrupts tutorial in PDF form, like your USART intro? abcminiuser - Jun 15, 2009 - 03:46 PM

Post subject: Sure, I've attached a PDF version to the original post. Enjoy!

- Dean Twisted Evil ijcoxf - Jun 17, 2009 - 10:47 AM

Post subject:

abcminiuser wrote:

Sure, I've attached a PDF version to the original post. Enjoy!

- Dean Twisted Evil

Page 145: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Thanks Dean, for both tutorials. Something good to read while the boy is watching endless Spongebob Squarepants Very Happy Tares_pl - Oct 13, 2009 - 01:01 PM

Post subject: First of all great tutorial Wink but I've managed to get here when I got "should-working" code Wink Anyway I still have problem with my ATmega48. USART on polling works perfectly (4MHz external quartz enabled through fuse bits), but interrupts doesn't.

here is my code :

Code:

#define FOSC 4000000 // Clock Speed

#define BAUD 9600

#define MYUBRR ((unsigned int) (FOSC/16/BAUD-1))

#include <avr/io.h>

#include <avr/interrupt.h>

volatile unsigned char data;

void PORTC_Init(void) {

DDRC=0xff; // Port C as output

PORTC=0x01; // first LED on, second off

}

void USART_Init( unsigned int ubrr ) {

PRR = ~_BV(PRUSART0);

/* Set baud rate */

UBRR0H = (unsigned char) (ubrr>>8);

UBRR0L = (unsigned char) ubrr;

/* Set frame format: 8data no parity 1stop bit */

UCSR0C = (0<<USBS0)|(1<<UCSZ00)|(1<<UCSZ01);

UCSR0B |= (1<<UCSZ02);

Page 146: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

/* Enable receiver and transmitter */

UCSR0B = (1<<RXEN0)|(1<<TXEN0);

/* Enable receiver interrupt */

UCSR0B |= (1<<RXCIE0);

}

ISR(USART_RX_vect) {

PORTC ^= _BV(0);

PORTC ^= _BV(1);

while ( !( UCSR0A & (1<<UDRE0)) );

UDR0 = 0x61;

}

int main (void) {

PORTC_Init();

USART_Init(MYUBRR);

while ( !( UCSR0A & (1<<UDRE0)) );

UDR0 = 0x4E;

while ( !( UCSR0A & (1<<UDRE0)) );

UDR0 = 0x61;

while ( !( UCSR0A & (1<<UDRE0)) );

UDR0 = 0x4E;

//send NaN on USART

Page 147: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

sei();

while(1);

return 0;

}

I've got two LEDs on portC and I want them to blink when interrupt is invoked and send something back to terminal.

As for now I just can't get this working. The first 3 letters are send ("NaN") and then when I press anything on keyboard I get nothing. Well sometimes I get frame error on realterm.

I'm using ubuntu 9.04 amd64 as my main system, so I'm compiling under it. After going through all pages here I think it's a compiler problem, but I may be wrong. Anyway I'm compiling it this way :

Code:

avr-gcc easy.c -mmcu=atmega48 -o easy.hex -Wall -Wstrict-prototypes -Werror -mcall-prologues -g2 -O1

Everything loads up fine... but still no luck. I would be glad if anyone could help me here a little Wink

EDIT :

If anyone has similar problem just copy makefile from avrstudio and run it... vuala, it works Very Happy bala1987 - Nov 18, 2009 - 02:55 PM

Post subject: @abcminiuser: the tutorial was very useful. By the way when i check my circuit by send for example 001 in decimal i get the response 255 .

Input Output

002 253

003 251

004 251

Page 148: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

What does this mean? this doesn't have a pattern.. Can you tell me why I get some random values?

PS:I used the software Hterm for checking(I connected to the computer by a COM port at 9600bps 8 bit no parity just as was in the tutorial)

Thanks a lot,

Bala ereihani - Nov 28, 2009 - 03:51 PM

Post subject: Thanks Dean!

It was so useful for me Smile Ganapathy - Nov 30, 2009 - 07:19 AM

Post subject: Hi

how to program modbus in gcc and could you tell me how to make a quary to tx and how to get rx respons from modbus through uart Smile avra - Nov 30, 2009 - 09:38 AM

Post subject:

Ganapathy wrote:

how to program modbus in gcc and could you tell me how to make a quary to tx and how to get rx respons from modbus through uart Smile

GCC: http://www.freemodbus.org/index.php?idx=32

ICC: http://www.avrfreaks.net/index.php?modu ... showinfo=1 Ganapathy - Nov 30, 2009 - 11:15 AM

Post subject: Thank u

I have another problem now. my program to transmit data of query but modbus couldn't response Ganapathy - Dec 01, 2009 - 07:02 AM

Post subject: hi

could you tell me. modbus are synchronous or asynchronous data transmission? plz avra - Dec 02, 2009 - 05:25 PM

Post subject: Have you heard of google? Do your homework. Enter "modbus asynchronous" into google and you will have an answer.

These are the tools that will help you with modbus troubleshooting:

Page 149: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

http://www.modbusdriver.com/modpoll.html

http://www.modbusdriver.com/diagslave.html bittusrk - Dec 13, 2009 - 07:39 PM

Post subject: Is there any way in which we can change the priorities of the interrupts? abcminiuser - Dec 13, 2009 - 10:38 PM

Post subject: No, the interrupt priority (on the regular AVR8) is fixed and cannot be changed. The best you can do would be either to selectively disable certain interrupts for short periods, or make your low priority interrupts themselves interruptable (which is dangerous).

- Dean Twisted Evil DragonSoul - Dec 23, 2009 - 07:10 PM

Post subject: Newbie strange problem Hello all.

I just wondering as newbie, witch great pottencial have programing atmel product.

So maybe can you help me with this problem.

I just copy the program and made some changes.

When I open Windows Hyperterminal and send "a" or "b" everything is working, just to situatiation when I disconnect the programing LPT cable. Till LPT programing cable is connected then all is working, but when I disconnect cable the communication is not working (but hyperterminal says that is connected).

Here is Code

Code:

#define F_CPU 8000000UL

#include <avr/io.h>

#include <avr/interrupt.h>

#define USART_BAUDRATE 2400

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

volatile unsigned char LED1;

Page 150: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

int main (void)

{

DDRC=0xff;

LED1=0x00;

UCSRB |= (1 << RXEN) | (1 << TXEN); // Turn on the transmission and reception circuitry

UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes

UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register

UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register

UCSRB |= (1 << RXCIE); // Enable the USART Recieve Complete interrupt (USART_RXC)

sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed

for (;;) // Loop forever

{

// Do nothing - echoing is handled by the ISR instead of in the main loop

}

}

ISR(USART_RXC_vect)

{

char ReceivedByte;

ReceivedByte = UDR; // Fetch the recieved byte value into the variable "ByteReceived"

if (ReceivedByte==0x61) LED1=LED1^0b00000001;

if (ReceivedByte==0x62) LED1=LED1^0b00000010;

Page 151: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

if (ReceivedByte==0x63) LED1=LED1^0b00000100;

if (ReceivedByte==0x64) LED1=LED1^0b00001000;

if (ReceivedByte==0x65) LED1=LED1^0b00010000;

if (ReceivedByte==0x66) LED1=LED1^0b00100000;

PORTC=LED1;

UDR = ReceivedByte;// Echo back the received byte back to the computer

}

And schematics is in file.

Thanks you for help, maybe you kick my ass to next stair step

Smile DragonSoul - Dec 23, 2009 - 07:23 PM

Post subject: RE: Newbie strange problem I forgot to write that I use internal 8Mhz oscilator

thanks ArnoldB - Dec 23, 2009 - 08:26 PM

Post subject: Re: RE: Newbie strange problem

DragonSoul wrote:

I forgot to write that I use internal 8Mhz oscilator

thanks

That's asking for trouble with the serial interface. Please use the forum search function to find out why. It is an FAQ. JohanEkdahl - Dec 23, 2009 - 09:28 PM

Post subject: RE: Re: RE: Newbie strange problem

Quote:

but when I disconnect cable the communication is not working

Either I'm totally missing something or the obvios reply to that is "Yes, what did you expect?".

Quote:

Page 152: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

(but hyperterminal says that is connected).

Hypertermial is probably not set up to detect if there is a physical connection. For RS232 communications this is handled by separate signal lines, typically DSR and DTR (not TxD and RxD). And something needs to keep those signals on the required levels. This can be done by the AVR (conuming two IO pins, and needing a external level adjustment arrangement). You could also arrange for a simple "loopback" of DTR to DSR at the PC side of the physical connection. And then you need to set up Hyperterminal to detect existence of connection with DTR-DSR. DragonSoul - Dec 24, 2009 - 07:07 AM

Post subject: RE: Re: RE: Newbie strange problem

Quote:

Quote:

but when I disconnect cable the communication is not working

Either I'm totally missing something or the obvios reply to that is "Yes, what did you expect?".

Sorry I forgot to write when I disconnect LPT communication cable, then RS232 communication stop working.

I develop, that when I just connect GND to GND LPT cable the communication start working and when I disconnect the GND from GND LPT cable that communication stop working. Maybe the GND from adapter witch generate 12 Volts is not real GND and of course the LPT ground is grounded to PC, but I cant develop, how to ground this system without computer.

Thank for you time JohanEkdahl - Dec 24, 2009 - 11:22 AM

Post subject: RE: Re: RE: Newbie strange problem Where does the LPT cable go? To the AVR? Is it the LPT cable that is supplying power to the AVR perhaps? DragonSoul - Dec 25, 2009 - 07:43 AM

Post subject: RE: Re: RE: Newbie strange problem The LPT cable is painted on schematic as 'To PC LPT'. Is connected as explained on http://www.scienceprog.com/simplest-128-atmega-programmer/ and is used for programing ATMega8. Normally I disconect the cable and ATmega is feed with 5V through 7805 as showed on my schematics. For another application as flashing LED i disconnect programing LPT (printer) cable and procesor is working. But I develop, that when LPT cable is connected then RS232 communication is working, when I disconnect LPT cable, then communication is not working. But processor is still running. When I connect any GND to GND of LPT cable, then

Page 153: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

RS232 communication start working. Now I dont know, how I can ground GND in my room without computer. abcminiuser - Dec 25, 2009 - 11:56 AM

Post subject: RE: Re: RE: Newbie strange problem On your serial port cable, do you have all three of Tx, Rx and GND connected? You have to have the serial cable's ground pin connected to your circuit ground, or the two circuits (PC and your board) will be floating in regards to one-another and the communications won't work.

- Dean Twisted Evil JohanEkdahl - Dec 25, 2009 - 11:56 AM

Post subject: RE: Re: RE: Newbie strange problem You have no common ground for the AVR and the device you are communicating with? If so: Bad. You need that. DragonSoul - Dec 25, 2009 - 01:12 PM

Post subject: RE: Re: RE: Newbie strange problem Dean.

Yes. I have all three cable Rx, Tx and ground connected, RS232 ground is connected to my circuit ground (middle pin of 7805 see schematic).

JehanEkdalh

So you mean, that what is writen on my 12V adapter as GND is not ground, but just 0V potencial? JohanEkdahl - Dec 25, 2009 - 01:45 PM

Post subject: RE: Re: RE: Newbie strange problem

Quote:

So you mean, that what is writen on my 12V adapter as GND is not ground, but just 0V potencial?

There is no universal ground. If two devices are to interpret signals from eah other they have to share a ground, which is the "zero reference" for them.

Disconnect the LPT cable. Have the RS232 cable connected. Now measure the voltage between GND on your AVR circuit and some good, known GND on your PC. Not zero Volts? Then something in the GND circuit between the AVR and the PC is broken. Do a continuity check on the RS232 cable to make sure the GND is wired correctly to both connectors (pin 7 on a DB-25 connector, pin 5 on a DE-9 connector). Difool - Dec 28, 2009 - 09:27 PM

Post subject: RE: adv ringbuffer Hi,

A question perturbs me :

Page 154: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

I understand the interest to use interrupts and ring buffer for Rx because we cannot really control it but which is the interest to use interrupts and rint buffer for Tx ?

What can be the problems to do the Tx synchronously ?

Thank you abcminiuser - Dec 28, 2009 - 09:58 PM

Post subject: RE: adv ringbuffer No problems doing Tx synchronously -- some people just like to buffer data before sending. This is useful in some cases where the serial data has a timeout on the receiver's end, so you buffer the data and send it as a single chunk to ensure that the receiver's timeout period doesn't expire prematurely.

- Dean Twisted Evil DragonSoul - Jan 07, 2010 - 08:05 PM

Post subject: RE: adv ringbuffer Hello.

Thanks very much to JohanEkdahl and abcminiuser for help with problem with RS232 communication.

Problem was, that on the 9-pin connector witch lead to MAX232 pin 5 haved cold connection. So after measurement i develop, that GND was not in same level, but I dont know why. After resolder all connection, now all is working. Very good job with help Thanks JohanEkdahl - Jan 07, 2010 - 09:18 PM

Post subject: RE: adv ringbuffer Ha! My suspicions about bad grounding was well grounded! Very Happy

Happy that it worked out for you! oitguy - Feb 28, 2010 - 05:01 AM

Post subject: Thanks Dean, this is another clean tutorial. This has possibly been mentioned by others: The interrupt vector table (Attiny2313) gives a source of "USART0, RX" which would be thought to be converted to "USART0_RX_vect" for use in ISR(), however it must be specified as "USART_RX_vect" as stated here:

http://www.nongnu.org/avr-libc/user-man ... rupts.html Jericho_D_Niera - Mar 01, 2010 - 10:38 AM

Post subject: hello guys! i'm jericho. i'm trying to learn avr micros, i'm studying it for about 3 weeks now and this site help me a lot!

Page 155: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

now i'm having a hard time doing my code. i'm using atmega8 to be interfaced with a GPS module. i already made a code displaying GPS data sent to the MCU then the MCU sending the gps data to hyperterminal..

but now, i'm trying to display this in hyperterminal

Code:

time: (current GPS time)

unfortunately, i can't do it. it seems like my code is not working.. here it is..

Code:

// atmega8 //

#include <avr/io.h>

#include <inttypes.h>

#include <util/delay.h>

#include <avr/interrupt.h>

#define USART_BAUDRATE 4800

Page 156: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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

volatile uint8_t data, parsing_state, state;

volatile int8_t ReceivedByte[5], time[13], latitude[12];

volatile int8_t longitude[13], speed[6], date[9] ;

void init_uart()

{

// enable Tx/Rx circuitry

UCSRB |= (1<<RXEN) | (1<<TXEN);

// 4800bps, 8-bit data, no parity, 1 stop bit

UCSRC |= (1<<URSEL) | (1<<UCSZ0) | (1<<UCSZ1);

UBRRL = BAUD_PRESCALE;

UBRRH = (BAUD_PRESCALE>>8);

}

void gprmc_only()

{

int8_t GPRMC[] = "$PSTMNMEACONFIG,0,4800,64,1\r\n";

while (GPRMC[data] != 0x00)

{

Page 157: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

while ((UCSRA & (1<<UDRE)) == 0) {};

UDR = GPRMC[data++];

}

}

void time_menu()

{

data = 0;

int8_t real_time[] = "time: ";

while (real_time[data] != 0x00)

{

while ((UCSRA & (1<<UDRE)) == 0) {};

UDR = real_time[data++];

}

data = 0;

while (time[data] != ',')

{

while ((UCSRA & (1<<UDRE)) == 0) {};

UDR = time[data++];

}

state = 0;

Page 158: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

}

int main (void)

{

init_uart();

state = 0;

parsing_state = 0;

data = 0;

UCSRB |= (1<<RXCIE); // enable Rx complete interrupt

_delay_ms(1000);

_delay_ms(1000);

_delay_ms(1000);

gprmc_only();

sei(); // enable all interrupt

while (1)

{

if (state == 1)

{

UCSRB |= (0<<RXCIE); // disable Rx interrupt

time_menu();

Page 159: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

UCSRB |= (1<<RXCIE); // enable Tx interrupt

}

}

}

ISR (USART_RXC_vect)

{

switch (parsing_state)

{

case 0:

data = 0;

ReceivedByte[data] = UDR;

if (ReceivedByte[data] == '$')

parsing_state++;

else

{

parsing_state = 0;

state = 0;

}

Page 160: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

break;

case 1:

ReceivedByte[data] = UDR;

if (ReceivedByte[data] == ',')

parsing_state++;

else

{

parsing_state = 1;

state = 0;

}

break;

case 2:

data = 0;

time[data] = UDR;

if (time[data] == ',')

parsing_state++;

Page 161: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

else

{

data++;

parsing_state = 2;

state = 0;

}

break;

case 3:

data = 0;

ReceivedByte[data] = UDR;

if (ReceivedByte[data] == ',')

parsing_state++;

else

{

parsing_state = 3;

state =0;

}

break;

Page 162: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

case 4:

data = 0;

latitude[data] = UDR;

if (latitude[data] == ',')

parsing_state++;

else

{

parsing_state = 4;

data++;

state = 0;

}

break;

case 5:

data = 0;

ReceivedByte[data] = UDR;

Page 163: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

if (ReceivedByte[data] == ',')

parsing_state++;

else

{

parsing_state = 5;

state = 0;

}

break;

case 6:

data = 0;

longitude[data] = UDR;

if (latitude[data] == ',')

parsing_state++;

else

{

parsing_state = 6;

data++;

state = 0;

}

Page 164: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

break;

case 7:

data = 0;

ReceivedByte[data] = UDR;

if (ReceivedByte[data] == ',')

parsing_state++;

else

{

parsing_state = 7;

state = 0;

}

break;

case 8:

data = 0 ;

speed[data] = UDR;

Page 165: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

if (speed[data] == ',')

parsing_state++;

else

{

parsing_state = 8;

data++;

state = 0;

}

break;

case 9:

data = 0;

ReceivedByte[data] = UDR;

if (ReceivedByte[data] == ',')

parsing_state++;

else

{

parsing_state = 9;

state = 0;

Page 166: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

}

break;

case 10:

data = 0;

date[data] = UDR;

if (date[data] == ',')

parsing_state++;

else

{

parsing_state = 10;

data++;

state = 0;

}

break;

case 11:

data = 0;

Page 167: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

ReceivedByte[data] = UDR;

if (ReceivedByte[data] == 0x00)

{

parsing_state = 0;

state = 1;

}

else

{

parsing_state = 11;

state = 0;

}

break;

}

}

i hope you can tell me what's wrong with my code.. thanks! clawson - Mar 01, 2010 - 11:00 AM

Post subject: Forget the interrupts and the GPS parsing to start with. Are the basics working? If you simply:

Code:

int main(void) {

init_uart();

Page 168: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

while(1) {

while ((UCSRA & (1<<UDRE)) == 0) {};

UDR = 'A';

}

}

do you see a stream of 'A's at 4,800 baud on your PC terminal?

If you then modify that to just have a single character RXC interrupt handler that main() echoes back does that then work?

Continue adding the program complexity back in and retesting until you find any flaw in the logic but don't expect all of such a complex program to all work right from the start.

Make a lot of use of the PC terminal for debugging. Remember that if the AVR only RX's from the GPS then as long as you stick to 4800 you can split TX/RX so TX goes to the PC terminal as a debug output and RX is the connection from the GPS Jericho_D_Niera - Mar 01, 2010 - 03:04 PM

Post subject: hi clawson! thanks for the reply!

i already did what you've said before doing this. and it worked fine. i also finished writing a code that will display the GPS data sent to the MCU then the MCU sending the data to hyperterminal. but after inserting the parsing routine, it seems stopped working..

Sad clawson - Mar 01, 2010 - 03:06 PM

Post subject:

Quote:

but after inserting the parsing routine, it seems stopped working..

Page 169: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

In which case you have identified the bit that requires the work - now break that into small implementation steps and try to find the point where it stops behaving as expected. rnable - Mar 23, 2010 - 10:55 AM

Post subject: Hello all,

How i can extract only #GPRMC sentence from all nmea sentences ? Jericho wrote code isn't universal function for taking only gprmc. Im thinking to use data from "$" to "*" but how ? clawson - Mar 23, 2010 - 11:10 AM

Post subject:

Quote:

How i can extract only #GPRMC sentence

http://www.maartenlamers.com/nmea/

(it's C++ for Arduino but you should be able to convert if you need it in C) rnable - Mar 23, 2010 - 05:19 PM

Post subject: How i should convert it ? i never worked with Arduino :\

Any other suggestions in c language ? clawson - Mar 23, 2010 - 05:57 PM

Post subject:

Quote:

Any other suggestions in c language ?

I found that after 2 minutes with Google. If I'd spent the whole 5 minutes I'm sure I could have found C code - it's not like you are the first person who wants to parse NMEA. Try "parse NEMA GPRMC C source" or similar. rnable - Mar 23, 2010 - 07:26 PM

Post subject: Need some TUTorials about avr interfacing with gps, like TUT using usart.. Confused clawson - Mar 24, 2010 - 09:59 AM

Post subject:

Quote:

Need some TUTorials about avr interfacing with gps, like TUT using usart..

Page 170: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Surely it's the same thing. They almost all use a 4800 baud UART link so this thread applies. rnable - Mar 24, 2010 - 07:12 PM

Post subject:

rnable wrote:

Need some TUTorials about avr interfacing with gps, like TUT using usart.. Confused

whoops, I meant parsing gps data with avr.. Rolling Eyes JohanEkdahl - Mar 24, 2010 - 07:51 PM

Post subject:

Quote:

I meant parsing gps data with avr..

That would be "Parsing GPS data in C", yes? C is a standardized language so, as long as you have the NMEA, you should be able to use any C code with only small changes.

Keeping the reception and the parsing divided is recommended: Getting the string is one thing. Parsing it is another. You could even develop and test the parsing code in on a PC with eg MS Visual Studio (a free Express version is available) so that you don't have to go through the relative awkwardness of debugging in AVR Studio, simulated or with on-chip debugging).

I'm fairly sure that we've had NMEA string parsing up here before. And it is almost sure that you can find C code on the web that is close to what you need.

Quote:

Need some TUTorials about avr interfacing with gps, like TUT using usart..

Page 171: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

What you need, as I hinted about, is to try to think about the complete problem you're facing as consisting of several smaller, more manageable, problems.

The communication, getting the NMEA string is plain UART communication, and for that there is a tutorial (as you yourself has noted). Gete that working receiving the complete NMEA string.

Then create a new little project that sets up a constant NMEA string and start working on parsing that. (Steal code from the net. Or just get inspired by it.) The advantage of this approach is that you dont have the complete hardware setup running, and more importantly that you know what the string you're parsing looks like so you have a better chance of detecting bugs and debugging. When it works for that string you test it with a few variants. When you're gaining confidence in the parser, you hook the two things together.

Any successful programmer uses the principle of "divide and conquer" to solve problems. Un-experienced programmers not applying this principle most likely gets overwhelmed by the problem, or gets lost in a maze of problems and symptoms leading to an uncontrollable situation.

Going from one place to another with success is a matter of taking many small steps, rather than one giant leap. Patience is a necessary virtue of a programmer. divide_overflow - May 21, 2010 - 03:03 AM

Post subject: avr-gcc stealth As a certified newbie to AVR and and a current 8051 user(don't laugh), most of the tutorials and example code in proliferation it seems is written using GCC which is not obvious to the casual observer except for the #include <avr/io.h>. GCC is such a mountain of macros and header files that for someone (especially new)trying to decipher it into a working version using something other than GCC is a herculean and time consuming effort. Nowhere can I find anything that fully makes this known up front to someone using a commercial compiler. Mayabe I should have known...Turns out when it comes to gcc I have more money than time.

But again for beginners at AVR, it would be very helpful to put a disclaimer with the gcc stuff.

Sorry but this vent (not against anyone in particular it's just a beef with the way gcc seems "universal") has been building a while.

So feel free to torch back. ArnoldB - May 21, 2010 - 06:30 AM

Page 172: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Post subject: Re: avr-gcc stealth

divide_overflow wrote:

GCC is such a mountain of macros and header files that for someone (especially new)trying to decipher it into a working version using something other than GCC is a herculean and time consuming effort.

And why is that our problem?

Typical kids. They get code for free, but than insist the get also spoon feed. If they don't get spoon feed they spread FUD like

Quote:

GCC is such a mountain of macros and header files

. Whine, whine, whine. How disgusting.

Remember, YOU decided to use that "something other". No one forced you. YOU decided to not read the GCC and avr-libc manuals. And I am sure you worked very hard to avoid reading any serious text book about C programming ("For Dummies" guides and "in 21 days" junk don't count). And may I guess, YOU decided to use oh so simple looking stuff like MikroE C or Arduino, and now you are surprised that the rest of the world doesn't feed you with code.

If you are a professional programmer, please, consider a career change. You are obviously not even capable of operating a compiler. Like a carpenter isn't able to handle a saw. clawson - May 21, 2010 - 10:09 AM

Post subject: RE: Re: avr-gcc stealth didvide_overflow,

I fear you may have missed the point of this Tutorial forum. Any user of any compiler is quite at liberty to submit an article about how some function is performed using their compiler. I guess if there is an error here it is that tutorial authors are encouraged to either include "[GCC]" (or whatever "[IAR]", "[CV]", ...) in the name of the thread though many just use a title such as "using GCC's PROGMEM attribute". So perhaps this tutorial should have mentioned GCC in the thread title. OTOH the techniques it presents are generally portable to any compiler with the only part that is GCC specific being the ISR syntax but presumably the users of other compilers will know the corresponding ISR syntax to use?

Page 173: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

The propensity of GCC articles here simply reflects its wide spread usage amongst both hobbyists and professionals.

Personally I'm having a hard time understanding how GCC is "worse" in the sense of header macro usage. The standard headers of most compilers are actually very close.

Moderator.

PS feel free to write and submit your own tutorials - they are always welcome. Ragooman - Jul 29, 2010 - 06:39 PM

Post subject: Hello,

thanks for a great tutorial here.

I'm trying to upgrade the serial code in my robot. I'm using a ATMega128. I currently use a software polling code to send & receive thru the usart.

I added a little command line routine in our code to allow me to type in commands using TeraTerm terminal to access the Robot hardware and display telemetry data on the screen. At the moment, the robot is on a tether(serial cable), eventually we will upgrade to using a RF transceiver.

But now as the project gets larger I need to move to this type of Interrupt servicing USART method so as to keep the robot running and not sit waiting at the command line with software polling .

So since I'm dealing with strings on the command line, I use some of the standard library to get things done. Such as fgets and strcmp, as shown here below, but it's all software pollling. This works fine as it is, but when working with robots, you need to have the robot run independantly, and not wait for your commands using software polling.

I had initially used the sample code you have in this tutorial and stored each character of the command line into a buffer array. But then I didn't know how to continue using the 'strcmp' library to compare strings with what I have in the buffer array. I had to resort to comparing one character at a time, which becomes self-defeating--and the code becomes larger-- when working with a command line interface.

So I thought maybe there's someway of using Timer1 in combination with this, to simply check the usart few times a sec--without polling, but I'm not sure.

Page 174: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

I hope you can suggest something.

Code:

//-----------------------------------------------

char cmd[80]; // buffer to construct parsable string terminating with CR

int main(void)

{

.

.

.

fgets( cmd, 80, stdin ); '//get command line string

strip_newline( cmd, 80 ); //remove null terminator

.

.

.

if ( strcmp ( cmd, "quit" ) == 0 ) //time to quit

{

//do something

}

}

//-----------------------------------------------

// remove the null terminator from input string

void strip_newline( char *str, int size )

{

int i;

for ( i = 0; i < size; ++i )

Page 175: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

{

if ( str[i] == '\n' )

{

str[i] = '\0';

return; /* we're done, exit function */

}

}

/* if exit here, must not have been any newline! */

}

//-----------------------------------------------

genetica - Aug 17, 2010 - 04:40 PM

Post subject: Good day

I have a problem with interrupt driven USART.

firstly here is my code that does not work:

Code:

#include <avr/io.h>

#include <avr/interrupt.h>

#include <stdlib.h>

#include <string.h>

#define Buffer_Size 32

#define USART_BAUDRATE 9600

#define BAUD_PRESCALE 103

// Define the buffer structure

Page 176: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

typedef struct buffer_

{

char data[Buffer_Size];

uint8_t size;

} buffer;

// Set permanent buffer

buffer buf;

char Command[Buffer_Size];

// Global variables

uint8_t tel;

int main (void)

{

// Initialize Buffer

buf.size = 0;

// Set RS485 enable pin as output

DDRD |= (1<<DDD6);

PORTD &= (0<<PORTD6);

// SETUP of USART 0

// Turn on the TX RX

UCSR0B |= (1 << RXEN0) | (1 << TXEN0);

// Use 8-bit char - Asynchronous, no parity, 1 Stop-bit

Page 177: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

UCSR0C |= (1 << UCSZ00) | (1 << UCSZ01);

//Baud rate

// Load lower 8-bits

UBRR0L = BAUD_PRESCALE;

// Load upper 8-bits

UBRR0H = (BAUD_PRESCALE >> 8);

tel = 0;

// Enable the handling of USART interrupt vector

UCSR0B |= (1 << RXCIE0)|(1 << TXCIE0);

// Enable the Global Interrupts

sei();

for(;;)

{

if (tel == 1)

{

//Set end of string

buf.data[buf.size] = 0;

//Copy string for command line

strcpy(Command,&buf.data[1]);

// Reset buffer

buf.size = 0;

tel = 0;

Page 178: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

//Output Enter

PORTD |= (1<<PORTD6);

UDR0 = '\r';

}

}

}

ISR(USART0_RX_vect)

{

// Code to be executed when the USART receives a byte here

char ReceivedByte;

// Fetch the recieved byte

ReceivedByte = UDR0;

buf.size += 1;

buf.data[buf.size] = ReceivedByte;

if (ReceivedByte == '\r')

{

tel = 1;

}

else

{

//Clear previous data

buf.data[buf.size+1] = 0;

Page 179: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

//Reflect received character

PORTD |= (1<<PORTD6);

UDR0 = buf.data[buf.size];

}

}

ISR(USART0_TX_vect)

{

PORTD &= (0<<PORTD6); // Enable RS485 receive

}

The code above works when you replace:

Code:

tel = 1;

(which is in the ISR) with the code within the if statement:

Code:

if (tel == 1)

{

//Set end of string

buf.data[buf.size] = 0;

//Copy string for command line

strcpy(Command,&buf.data[1]);

// Reset buffer

buf.size = 0;

Page 180: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

tel = 0;

//Output Enter

PORTD |= (1<<PORTD6);

UDR0 = '\r';

}

Why is that? What am I doing wrong when using the first code presented? Is it the way that USART interrupts work? clawson - Aug 17, 2010 - 04:46 PM

Post subject:

Quote:

Why is that?

FAQ#1 genetica - Aug 17, 2010 - 04:56 PM

Post subject: WOW thanks clawson.

Great FAQ! They should include it in the webpage background or header or flash it every now and then over the screen.Wink solanki - Aug 24, 2010 - 08:01 PM

Post subject:

Code:

ISR(USART_TXC_vect)

{

sensor= ((ADCH << 8 ) | ADCL);//read value out of ADC

UDR = ((sensor<< 6)>>4)| 0x01; //send value to software

}

It shows me error:

Page 181: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

../try_usart.c:27: warning: 'USART_RXC_vect' appears to be a misspelled signal handler clawson - Aug 24, 2010 - 08:03 PM

Post subject:

Quote:

'USART_RXC_vect' appears to be a misspelled signal handler

Which AVR are you building for? Have you checked what the vector is actually called in the User Manual or the ioXXX.h file? JohanEkdahl - Aug 24, 2010 - 08:10 PM

Post subject:

Quote:

It shows me error:

../try_usart.c:27: warning: 'USART_RXC_vect' appears to be a misspelled signal handler

but the code you show is

Quote:

Code:

ISR(USART_TXC_vect)

...

Rolling Eyes

Something is mis-quoted... solanki - Aug 24, 2010 - 08:22 PM

Post subject: I am building for ATMEGA640...

Page 182: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Here is my code:

Code:

#include <avr/io.h>

#include <avr/interrupt.h>

#include <avr/eeprom.h>

void USART_Init(void);

void USARTTransmit( unsigned char data );

unsigned char USARTReceive( void );

void USART_Init()

{

/* Set baud rate hard coded to 19200 for 12MHz */

UBRR0L = 38;

/* Enable receiver and transmitter */

UCSR0B = (1<<RXEN0)|(1<<TXEN0);

/* Set frame format: 8data, 2stop bit */

UCSR0C = (1<<USBS0)|(3<<UCSZ00);

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

sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed

}

int main (void)

{

USART_Init();

Page 183: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

for(;;);

}

//*****************************************

ISR(USART0_RXC_vect)

{

uint8_t c;

uint16_t address;

uint8_t byteValue;

uint16_t wordValue;

c = UDR0;

//Disable the intrrupt

if( c == 'b') // Read Byte

{

// Send command byte 0x62

// Send address byte

// Receive data byte

address = USARTReceive();

USARTTransmit(eeprom_read_byte((uint8_t*)address));

}

else if(c == 'B') // Write Byte

{

// Send command byte 0x42

// Send address byte

Page 184: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

// Send byte to write

address = USARTReceive();

byteValue = USARTReceive();

eeprom_busy_wait();

eeprom_write_byte((uint8_t*)address,byteValue);

}

else if(c == 'w') // Read Word

{

// Send command byte 0x77

// Send address high byte

// Send address low byte

// Receive word high byte

// Receive word low byte

address = (USARTReceive() << 8);

address |= USARTReceive();

wordValue = eeprom_read_word((uint16_t*)address);

USARTTransmit(wordValue>>8);

USARTTransmit(wordValue);

}

else if(c == 'W') // Write Word

{

// Send command byte 0x57

Page 185: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

// Send address high byte

// Send address low byte

// Send word high byte

// Send word low byte

address = (USARTReceive() << 8);

address |= USARTReceive();

wordValue = (uint16_t)(USARTReceive()<<8);

wordValue |= (uint16_t)USARTReceive();

eeprom_busy_wait();

eeprom_write_word((uint16_t*)address,wordValue);

}

else if(c == 'k') // Read Block

{

// Send command byte 0x6b

// Send size high byte

// Send size low byte

// Send EEPROM address start high byte

// Send EEPROM address start low byte

// Receive number of bytes specified by size

//NOTE: We are limiting this to 80 bytes for this test

// this code SHOULD work for the full EEPROM if the

// array is set to the EEPROM size - not tested though.

Page 186: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

uint8_t localBlock[80];

uint16_t size;

uint16_t address;

size = (USARTReceive() << 8);

size |= USARTReceive();

address = (USARTReceive() << 8);

address |= USARTReceive();

// Limit size to 80 due to localBlock array size

if(size > 80)

{

USARTTransmit('?');

return;

}

eeprom_read_block((void*)localBlock,(const void*)address,size);

int i;

for(i=0;i<size;i++)

{

USARTTransmit(localBlock[i]);

}

}

else if(c == 'K') // Write Block

{

Page 187: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

// Send command byte 0x4b

// Send size byte - limit to <= 80

// Send EEPROM address start high byte

// Send EEPROM address start low byte

// Receive number of bytes specified by size

// NOTE: We are limiting this to 80 bytes for this test

// this code SHOULD work for the full EEPROM if the

// array is set to the EEPROM size - not tested though.

uint8_t localBlock[80];

uint16_t size;

uint16_t address;

size = (USARTReceive() << 8);

size |= USARTReceive();

address = (USARTReceive() << 8);

address |= USARTReceive();

int i = 0;

for(i = 0; i < size && i < sizeof(localBlock); i++)

{

localBlock[i] = USARTReceive();

}

eeprom_write_block((const void*)localBlock,(void*)address,size);

Page 188: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

}

else USARTTransmit('?');

}

/*****************************************************

Functions from UART_Test

******************************************************/

void USARTTransmit( unsigned char data )

{

/* Wait for empty transmit buffer */

while ( !( UCSR0A & (1<<UDRE0)) )

;

/* Put data into buffer, sends the data */

UDR0 = data;

}

unsigned char USARTReceive( void )

{

/* Wait for data to be received */

while ( !(UCSR0A & (1<<RXC0)) )

;

/* Get and return received data from buffer */

return UDR0;

}

solanki - Aug 24, 2010 - 08:24 PM

Page 189: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Post subject: I am using ATMEGA640.Yes I check manual.

0x0032 jmp USART0_RXC ; USART0 RX Complete Handler clawson - Aug 24, 2010 - 08:27 PM

Post subject: Vector names for 640 are:

Code:

C:\WinAVR-20100110\avr\include\avr>grep _vect iomxx0_1.h | grep USART

#define USART0_RX_vect _VECTOR(25)

#define USART0_UDRE_vect _VECTOR(26)

#define USART0_TX_vect _VECTOR(27)

#define USART1_RX_vect _VECTOR(36)

#define USART1_UDRE_vect _VECTOR(37)

#define USART1_TX_vect _VECTOR(38)

#define USART2_RX_vect _VECTOR(51)

#define USART2_UDRE_vect _VECTOR(52)

#define USART2_TX_vect _VECTOR(53)

#define USART3_RX_vect _VECTOR(54)

#define USART3_UDRE_vect _VECTOR(55)

#define USART3_TX_vect _VECTOR(56)

solanki - Aug 24, 2010 - 08:35 PM

Post subject: OK I got my mistake... I have one more question... How should I debugg my UART? solanki - Aug 25, 2010 - 04:55 PM

Post subject: I am trying to follow this tutorial and test UART. I am using ATMEGA640. so I modify the code accordingly. I am using hyper terminal to send and recieve the data.

I am using the internal clock source of 2MZ. I read the datasheet and set the baudrate 9600 to set the minimum error 0.2% according to the table given in datasheet.

I have few question regarding the hyper terminal

(1) Which protocol should I select to send the file

Page 190: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

(2) what should be my type of file which I am sending. TEXT or Hex

(3) What should be the type of connection

Here is the my code which I am using:

Code:

#include <avr/io.h>

#define USART_BAUDRATE 9600

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

int main (void)

{

char ReceivedByte;

UCSR0B |= (1 << RXEN0) | (1 << TXEN0); // Turn on the transmission and reception circuitry

UCSR0C |= (1 << UCSZ00) | (1 << UCSZ01); // Use 8-bit character sizes

UBRR0L = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register

UBRR0H = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register

for (;;) // Loop forever

{

while ((UCSR0A & (1 << RXC0)) == 0) {}; // Do nothing until data have been recieved and is ready to be read from UDR

ReceivedByte = UDR0; // Fetch the recieved byte value into the variable "ByteReceived"

Page 191: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

while ((UCSR0A & (1 << UDRE0)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it

UDR0 = ReceivedByte; // Echo back the received byte back to the computer

}

}

clawson - Aug 25, 2010 - 05:06 PM

Post subject:

Quote:

I am using the internal clock source of 2MZ.

You SURE about that? Is it actually working? (once again you have failed to say what the problem actually is)

As for sending files - what kind of files? how big? Sending them from where and to where? Obviously X/Y/Z modem are obvious choices for binary file transfers but is the data binary or is it ASCII? If the latter most terminal programs simply have "send text file" and "capture text file" options anyway.

BTW this thread is to discuss the tutorial and possibly ask questions directly related to it. When your question becomes more general this is NOT the right thread to use to ask about this. assad111 - Sep 10, 2010 - 02:24 PM

Post subject:

Code:

#include <avr/io.h>

#include <avr/interrupt.h>

#include <inttypes.h>

#include "usart.h"

Page 192: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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);

/*Enable Interrupts

RXCIE- Receive complete

UDRIE- Data register empty

Enable The recevier and transmitter

Page 193: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

*/

UCSRB=(1<<RXCIE)|(1<<RXEN);

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

Page 194: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

UQEnd++;

URBuff[UQEnd]=data;

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

}

assad111 - Sep 10, 2010 - 02:25 PM

Post subject: some one can explain this coding? clawson - Sep 10, 2010 - 02:48 PM

Post subject:

Quote:

some one can explain this coding?

It'd be far easier if the author hadn't stripped the comments from it!

It's not complete code. There's no sign of the global variables it uses and it enabled both TX and RX interrupts but only provide an ISR for RX.

However of what is shown 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).

To be honest it looks like a poor implementation of a circular buffer (not least of which is because of the lack of comments). In this thread you'll find a link posted by abcminiuser to his site at fourwalledcubicle.com which has circular buffer routines. You'd be FAR better off using those.

Page 195: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

(apart from anything else you get very easy access to support as Dean is a regular here) assad111 - Sep 10, 2010 - 07:56 PM

Post subject: this is complete code use as librery file in project of rf communication

[code]

#include <avr/io.h>

#include <avr/interrupt.h>

#include <inttypes.h>

#include "usart.h"

void USARTInit(uint16_t ubrrvalue)

{

//Setup q

UQFront=UQEnd=-1;

//Set Baud rate

UBRRH=(unsigned char)(ubrrvalue>>Cool;

UBRRL=(unsigned char)ubrrvalue;

/*Set Frame Format

Asynchronous mode

No Parity

1 StopBit

char size 8

Page 196: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

*/

UCSRC=(1<<URSEL)|(3<<UCSZ0);

/*Enable Interrupts

RXCIE- Receive complete

UDRIE- Data register empty

Enable The recevier and transmitter

*/

UCSRB=(1<<RXCIE)|(1<<RXEN);

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))

{

Page 197: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

//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];

Page 198: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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(!(UCSRA & (1<<UDRE)));

//Now write

UDR=data;

}

Page 199: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

uint8_t UDataAvailable()

{

if(UQFront==-1) return 0;

if(UQFront<UQEnd)

return(UQEnd-UQFront+1);

else if(UQFront>UQEnd)

return (RECEIVE_BUFF_SIZE-UQFront+UQEnd+1);

else

return 1;

}

void UWriteString(char *str)

{

while((*str)!='\0')

{

UWriteData(*str);

str++;

} assad111 - Sep 10, 2010 - 08:00 PM

Post subject: complete code is given above this is use as librery file in project

pleas explain uint8_t UDataAvailable() and ISR(USART_RXC_VECT)block

the main block is

Code:

#include <avr/io.h>

#include "usart.h"

Page 200: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

void main()

{

uint8_t i; //Clasical loop varriable

uint8_t packet[5],data=0;

DDRC|=0xFF; //All Output

//Initialize the USART with Baud rate = 2400bps

USARTInit(416);

/*

Get data from the remote Tx Station

The data is the value of PORTC on Remote Tx Board

So we will copy it to the PORTC of this board.

*/

while(1)

{

//Wait for a packet

while(!UDataAvailable());

if(UReadData()!='A') continue;

while(!UDataAvailable());

if(UReadData()!='A') continue;

while(UDataAvailable()!=3);

Page 201: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

//Get the packet

for(i=2;i<5;i++)

{

packet[i]=UReadData();

}

//Is it ok?

if(packet[2]!=((uint8_t)~packet[3])) continue;

if(packet[4]!='Z') continue;

//The packet is ok

data=packet[2];

//Now we have data put it to PORTC

PORTC=data;

}

}

assad111 - Sep 11, 2010 - 05:15 PM

Post subject: pleas someone explain above 2 coding clawson - Sep 11, 2010 - 06:54 PM

Post subject: Why? If you want circular buffers I've already told you a better solution where you'll get well documented code and access to the author if there's anything you don't understand.

You can generally judge the quality of code by how well commented it is. The code you present probably scores 1/10 on the quality scale by that measure.

Page 202: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

For a general explanation of circular (aka ring) buffers just google "circular buffer" or "ring buffer". sravani - Oct 02, 2010 - 07:48 AM

Post subject: usart reception hai.........

i am working on gsmproject using interrupts.......

i managed to send AT command continuously and i used interrupt subroutine as below:

usart_receive()

{

while ((UCSRA & (1 << RXC)) == 0) {};

return UDR0;

}

ISR(USART0_RX_vect)

{

ch[i]=usart_receive();

i++;

}

using this sub routine i am trying to accept the characters check for "OK" and then trying to glow leds when ch=="OK"............

when MICROCONTROLLER is connected to PC and using hyperterminal AT is transmitted continuously and whenever in between i send "OK" the leds are glowing.......

Page 203: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

but when the same thing connected to gsm modem its not responding.....

but when gsm is connected to PC using hyperterminal i sent at and received "OK".......

PROBLEM IS : when i am integrating MICROCONTROLLER with GSM there is no response..........

please suggest me if any modifications is needed....... abcminiuser - Oct 02, 2010 - 07:53 AM

Post subject: RE: usart reception You don't need the while() loop in your code - when the USART0_RX_vect interrupt fires, this bit will always be set (since the interrupt executes only when a character has been received). However, your problem is unrelated to that, it is just less than optimal code.

I suspect that your modem makes use of the extra serial handshake lines, such as DCD and RTS/CTS. You may need to connect these to the appropriate logic levels to allow the modem to transmit. These special handshake lines are used for "flow control", so that the host device (usually a PC) can stop the modem from transmitting until it is ready to receive more data.

- Dean Twisted Evil sravani - Oct 02, 2010 - 09:06 AM

Post subject: RE: usart reception yes...........

RTS and CTS of microcontroller are shorted as mentioned in avr tool user guide in help option of avr studio software......... meslomp - Oct 04, 2010 - 06:37 AM

Post subject: RE: usart reception ALL watchout this is a cross post.

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=98522&start=all&postdays=0&postorder=asc

the OP has a timing issue but is not listening to what others say. sravani - Oct 04, 2010 - 07:03 AM

Post subject: RE: usart reception sorry sir, very sorry for not replying you and made you angry.....now the LEDs problem and transmission with USART is solved. now we are working with reception. And reception is also working when PC & MICROCONTROLLER is interfaced, but when we connect MICROCONTROLLER with GSM modem is not responding.

Page 204: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

we identified:

when we type OK in the hyperterminal, LEDs will glow which is a part of the program that we have written as

ISR(USART0_RX_vect)

{

received[i] = UDR0;

i++;

if(strcmp(received,"OK")==0)

PORTA = 0x00;

}

so that we could come to know that it is responding when we interfaced PC & MICROCONTROLLER

PROBLEM:

same command when MICROCONTROLLER transmits to the GSM modem,LEDs are not glowing. clawson - Oct 04, 2010 - 09:22 AM

Post subject: RE: usart reception This is a tutorial thread to teach people about using the USART. The subsequent thread is here ONLY to discuss aspects of that article directly. It's not Aunt Agatha's problem page to air every last UART problem you may have. We have a whole forum (AVR Forum) for that. If this is a cross post as meslomp says then continue the discussion in the OTHER thread. Not here.

Moderator.

PS and DO NOT cross post in future. Internetwarrior - Oct 05, 2010 - 12:07 PM

Post subject: RE: usart reception Excellent guide man, as usual! muhammadabdur - Oct 27, 2010 - 12:33 PM

Post subject: Hello Dean, this is great tutorial, I think. Thank you very much.

Page 205: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

I want create a project that use UART to communicate two processors. I use ATMEGA168 with 20MHz system clock to send 19 blocks of characters and ATMEGA32 with 16MHz system clock to receive those characters. I also use similar code as "Ring Buffer" that you told it before.

My question, will different system clock on two processor cause trouble in sending and receiving those characters?

and is there any suggestion for me on what type of serial communication that I should use, UART or USRT?

thank you very much.

best regard,

muhammad abdur clawson - Oct 27, 2010 - 12:49 PM

Post subject:

Quote:

My question, will different system clock on two processor cause trouble in sending and receiving those characters?

No, as long as they are running the same baud rate then however they get to that doesn't matter. The key thing is simply that both systems are within 2% of the other one's baud rate.

As long as they are using crystals (I guess they must be to run at 16/20MHz) then asynchronous, rather than synchronous will be just fine. felipedelaxe - Nov 10, 2010 - 02:05 PM

Post subject: Thank you very much Dean!!

That's a great tutorial!! coffeelove - Dec 02, 2010 - 06:05 PM

Post subject: Wonderful tutorial Dean. I would like to add in my 2ç though. If following along with this tut on an atmega168-20pu, like I was. The ISR vector is USART_RX_vect. No 'C' or number. This one caught me up good even while staring at the page of interrupt vectors for the chip. But I am happy that it now works as expected. Smile

Page 206: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

edit: spelling. Moses - Dec 13, 2010 - 11:20 AM

Post subject: AVR Serial Interrupt - Problem Hey,

I'm new to using Atmega uC. I've written the following code to receive the data serially from serial port at 9600 baud. The code works fine!

I wish to increment a variable so that I can keep account of number of bytes recevied in my main program, but while loop which doesnot seem to get this done for me. Can someone kindly point the bug!

I've attached the code herewith; JohanEkdahl - Dec 13, 2010 - 11:34 AM

Post subject: RE: AVR Serial Interrupt - Problem You've fallen into the #1 trap regarding using C in embedded apps: You've failed to declare your ISR/main-shared variable(s) volatile.

Read more here: http://www.nongnu.org/avr-libc/user-man ... q_volatile

And here: http://www.avrfreaks.net/index.php?name ... mp;t=97382 Moses - Dec 13, 2010 - 03:04 PM

Post subject: RE: AVR Serial Interrupt - Problem Hey!

Thanks for your valuable time! It's was the problem, just declaring it to volatile did the trick!

Thanks very much!!!

- Moses muhammadabdur - Dec 17, 2010 - 10:31 AM

Post subject:

clawson wrote:

Quote:

Page 207: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

My question, will different system clock on two processor cause trouble in sending and receiving those characters?

No, as long as they are running the same baud rate then however they get to that doesn't matter. The key thing is simply that both systems are within 2% of the other one's baud rate.

As long as they are using crystals (I guess they must be to run at 16/20MHz) then asynchronous, rather than synchronous will be just fine.

thx you clawson.

my second question, is that possible, if I use Rx Interrupt and Tx non interrupt?

thx you so much.

best regards,

muhammadabdur. clawson - Dec 17, 2010 - 10:51 AM

Post subject:

Quote:

is that possible, if I use Rx Interrupt and Tx non interrupt

That's what I often use myself - so, yes. Moses - Dec 19, 2010 - 08:27 AM

Post subject: Ring buffer - Atmega32 problem... ERR JohanEkdahl - Dec 19, 2010 - 08:43 AM

Post subject: RE: Ring buffer - Atmega32 problem...

Quote:

Page 208: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

I'm unable to post a longer code using the "code" & "/code" don't know why, so attached it);

The forum does not like percent-signs in posts. clawson - Dec 19, 2010 - 01:15 PM

Post subject: RE: Ring buffer - Atmega32 problem...

Quote:

Can anyone guide me where I'm going wrong?

Your code seems to assume that the buffer is of infinite size and that indx++ can continue until the end of eternity. The whole point about a "ring" or "circular" buffer is that you know that the buffer is N bytes long so you do something like:

Code:

indx++

if (indx >= N) {

indx = 0;

}

in this way you never write past buff[N-1]. When you get to the end of the buffer this just takes it back to the start. Hence the terms "ring" or "circular". Moses - Dec 20, 2010 - 11:23 AM

Post subject: Re: RE: Ring buffer - Atmega32 problem...

JohanEkdahl wrote:

Quote:

I'm unable to post a longer code using the "code" & "/code" don't know why, so attached it);

The forum does not like percent-signs in posts.

Yes I read it a bit late! Now I've no problem with this! Thanks!!! Moses - Dec 20, 2010 - 11:41 AM

Page 209: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Post subject: RE: Re: RE: Ring buffer - Atmega32 problem... Hey,

I got the trick!!! As Clawson interpreted correctly I was trying to fetch every thing that comes my way from UART, finding it a odd way. I got the concept of circular buffer understood right, but my difficulty goes something like this;

I'll read N(N is Known, say 10 bytes) & shift them as the new bytes is available, just like FIFO. Thus at any point I'll have last 10 bytes with me. During process I also have to check the buffer for a particular pattern say "te:" or "No:". Once detected I want to store what ever follows to a safe location up to '\r' or '\n'. If the buffer is shifting continously I'm finding it difficulty in locating the position of the found element pattern. Some guidance needed for this, I'll write my own code.

-Moses Abhilash25091989 - Mar 07, 2011 - 09:11 PM

Post subject: It was really very helpfull.

Actually Im doing a project on GSM based home automation.

and im using SIM COM 300 GSM module and Atmega16L.....

Im having problem in the coding part,,,,,and i need help,,,, Im not getting what will happen when a new message is received and how to monitor an incoming message....please help..... clawson - Mar 07, 2011 - 09:19 PM

Post subject: This thread only exists to discuss details of the tutorial in the first post - not to diagnose every last UART problem. Take your question to a separate thread in AVR Forum.

Moderator. farshad4017 - Mar 22, 2011 - 04:07 PM

Post subject: Hi

I now how to send a character?

The program that you've written, any changes I will not care.

Code:

#include <avr/io.h>

#include <avr/interrupt.h>

#define USART_BAUDRATE 9600

Page 210: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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

int main (void)

{

UCSRB |= (1 << RXEN) | (1 << TXEN); // Turn on the transmission and reception circuitry

UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes

UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register

UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register

UCSRB |= (1 << RCXIE); // Enable the USART Recieve Complete interrupt (USART_RXC)

sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed

for (;;) // Loop forever

{

// Do nothing - echoing is handled by the ISR instead of in the main loop

}

}

ISR(USART_RXC_vect)

{

char ReceivedByte;

ReceivedByte = UDR; // Fetch the recieved byte value into the variable "ByteReceived"

UDR = ReceivedByte; // Echo back the received byte back to the computer

}

Page 211: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

I want to send a number to the micro and micro to the number dialed then I have a job.

But I do not know inside how do I put variable! Please let s a clearer example of the program?

thnx clawson - Mar 23, 2011 - 09:31 AM

Post subject: To send/receive variable contents it's often easiest (because humans can read these things) to convert to and from ASCII digits. Use sprintf()/itoa() to convert a variable into a human readable string of characters - send this across the UART link then use atoi() at the receiving end to convert the ASCII back to binary if you need it in that form. AxelAxis - Mar 24, 2011 - 05:07 AM

Post subject: Adapting stream output methodology from input capture

sagenepal wrote:

Hello,

I want to share this code in order to help out Stefan and anyone else who wants to to UART transmit using interrupts. This code uses the TXC interrupt, not UDRE. I don't know much about the latter. Maybe it would be better? But this code works, and it has a nice wrap-around buffer for very efficient use of processor time.

- Sage Radachowsky

Boston, USA

Code:

// SendWithInterrupt - main.c

//

// by Sage Radachowsky, Feb-Mar 2008 ("sager" at "mit" dot "edu")

//

//

// Program to test sending data to the serial output (UART / RS232) using interrupts

// instead of actively polling to check if the last byte was written.

//

// This has two advantages -- the CPU is using its built-in hardware signals rather than

Page 212: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

// burning CPU instructions so it consumes less power, and (2) the CPU is freed

// to do other things rather than wait for some 9600 baud output or even 57k baud output,

// which is a heck of a long time in a multi-MHz world.

//

// This is written for the AT90CAN128 microcontroller, which has 2 UART lines. To rewrite

// it for any Atmel AVR micro that has just one serial line, you would have to change the

// names of all the UART registers to remove the "0".

//

// Note that interrupts must be globally enabled for this stuff to work - of course!

//

// This code sets up the interrupts to interface with stdout, so that "printf()" sends

// by interrupt! Easy and Sweet!

//

// NOTE: Be sure to change your CPU speed if it's not 1.8432 MHz !

//

//**********************************************

// DEFINITIONS

//**********************************************

// CPU frequency

#define F_CPU 1843200L // 1.8432 MHz

Page 213: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

// UART baud rate

#define UART_BAUD 9600

// UART buffer size

#define UART_BUFFER_SIZE 256

//**********************************************

// HEADER FILES

//**********************************************

#include <ctype.h>

#include <string.h>

#include <stdint.h>

#include <stdio.h>

#include <avr/io.h>

#include <avr/interrupt.h>

#include <avr/pgmspace.h>

#include <util/delay.h>

Page 214: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

//**********************************************

// FUNCTION DECLARATIONS

//**********************************************

void USART0_Init(void);

static int UART0_Putchar(char c, FILE *stream);

void DelayAwhile(void);

//**********************************************

// GLOBAL VARIABLES

//**********************************************

char UartBuffer[UART_BUFFER_SIZE]; // this is a wrap-around buffer

int UartBufferNextByteToSend; // position of next byte to be sent

int UartBufferNextFree; // position of next free byte of buffer

int UartSendingInProgress; // 1 = sending is in progress

/* This is the pointer to the serial interface */

/* Defines the stream interface for write only */

FILE uart_str = FDEV_SETUP_STREAM (UART0_Putchar, NULL, _FDEV_SETUP_WRITE);

Page 215: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

// ################## here we GO! ####################

int main()

{

// initialize the UART and enable interrupts

USART0_Init(); sei();

printf ("Hello from SendWithInterrupt.\n");

DelayAwhile();

// loop forever

while (1)

{

printf ("This is test output. How's the weather?\n");

DelayAwhile();

}

}

//===============================================================================

Page 216: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

void DelayAwhile()

//

// Delays a while, to slow down to a human level.

//

{

_delay_ms(200);

_delay_ms(200);

_delay_ms(200);

}

//****************************************************

// UART functions

//****************************************************

//===============================================================================

void USART0_Init()

Page 217: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

// This routine initializes the UART0 port of the AT90CAN128 and clears the

// write buffer.

//

// This routine does NOT enable the transmit-complete interrupt (TXCIE0).

// That is left up to the UART0_PutChar() routine, after it puts something in

// the buffer for the first time.

//

// This routine also does NOT enable general interrupts. That is left to the

// main() initializing code, and it MUST be done for this stuff to work.

//

// Also sets standard out to the uart interface, so printf() works sweetly.

//

{

// init buffer data structures

UartBuffer[0] = '\0'; // clear the first byte of buffer

UartBufferNextByteToSend = 0; // set "next byte to send" to beginning

UartBufferNextFree = 0; // next free byte is also beginning of buffer

UartSendingInProgress = 0; // clear "sending in progress" flag

// set baud rate

UBRR0H = (unsigned char) (((F_CPU/(16L*UART_BAUD))-1) >> 8);

UBRR0L = (unsigned char) ((F_CPU/(16L*UART_BAUD))-1);

// Set frame format: 8data, no parity & 1 stop bits

UCSR0C = (0<<UMSEL0) | (0<<UPM0) | (0<<USBS0) | (3<<UCSZ00);

Page 218: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

// Enable transmit

UCSR0B = (1<<TXEN0); //Enable the transmitter only

// set standard output stream to our UART interface

stdout = &uart_str;

}

//===============================================================================

static int UART0_Putchar(char c, FILE *stream)

// If transmit is in progress, adds a character to the UART output buffer.

// If transmit is not in progress, kicks off a transmit.

//

// The send buffer is a wrap-around buffer.

//

// If the buffer is full, then this routine returns EOF.

// A successful completion returns 0.

//

// This routine disables the UART Tx interrupt temporarily, because

// things would get funky if the interrupt signal routine were called during

// execution of this routione.

//

// If the buffer was empty to start with, then this routine "primes the pump"

Page 219: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

// sending the character directly to the UART.

//

// This routine also adds carriage returns to newlines.

//

{

register int ReturnStatus = 0; // return 0 for success

register int UartBufferNextFree_last; // space to save last UartBufferNextFree

// if character is a "newline" then add a "carriage return" before it.

if (c == '\n')

UART0_Putchar('\r', stream);

// if no send is already in progress, then "prime the pump" by sending directly to UART

if (UartSendingInProgress == 0)

{

// set "sending in progress" flag

UartSendingInProgress = 1;

// send the first byte!

UDR0 = c;

}

else

{

// disable the Tx Complete interrupt

UCSR0B &= ~( 1 << TXCIE0 );

Page 220: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

UartBuffer[UartBufferNextFree] = c;

// increment the next free byte index, while saving last value

UartBufferNextFree_last = UartBufferNextFree++;

// check for wrap-around

if (UartBufferNextFree == UART_BUFFER_SIZE) // if we reached the end of the buffer -

UartBufferNextFree = 0; // start back at the beginning

if (UartBufferNextFree == UartBufferNextByteToSend) // if buffer is full -

{

// bump back the index so transmit routine doesn't think buffer's empty

UartBufferNextFree = UartBufferNextFree_last;

// return with error code

ReturnStatus = EOF;

}

// enable the Tx Complete interrupt

UCSR0B |= ( 1 << TXCIE0 );

}

// return with status code

return ReturnStatus;

}

Page 221: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

//********************************

// INTERRUPT HANDLERS

//********************************

//===============================================================================

ISR (USART0_TX_vect)

// This interrupt service routine is called when a byte has been sent through the

// UART0 port, and it's ready to receive the next byte for transmission.

//

// If there are more bytes to send, then send the next one and increment the index.

// If the index reached the end of the buffer, then wrap around to the beginning.

//

// If there is not another byte to write, then clear the "UartSendingInProgress"

// flag, otherwise set it if a byte has just been sent.

//

{

Page 222: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

if (UartBufferNextByteToSend == UartBufferNextFree) // if nothing to send -

{

UartSendingInProgress = 0; // clear "sending in progress" flag

return; // then we have nothing to do, so return

}

// set "sending in progress" flag

UartSendingInProgress = 1;

// send the next byte on UART0 port

UDR0 = UartBuffer[UartBufferNextByteToSend];

// increment index and check for wrap-around

UartBufferNextByteToSend++;

if (UartBufferNextByteToSend == UART_BUFFER_SIZE) // if we reached the end of the buffer -

UartBufferNextByteToSend = 0; // then start back at the beginning

}

Have fun!

Can this method of using streams and stdout etc be used in a similar way to read in strings? Ie stdin, an Rx interrupt, buffer and then reading with say scanf?

Im half way through doing so and wanted to make sure Im not on a futile path. Im aiming towards a simple way to have interrupt powered functions that easily send and capture complete strings from the UARTs. Thanks guys! clawson - Mar 24, 2011 - 09:18 AM

Page 223: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Post subject: RE: Adapting stream output methodology from input capture

Quote:

Can this method of using streams and stdout etc be used in a similar way to read in strings? Ie stdin, an Rx interrupt, buffer and then reading with say scanf?

See the user manual:

http://www.nongnu.org/avr-libc/user-man ... odemo.html

As you'll see that implements two output streams (LCD and UART) and one input stream (UART) hobbss - Apr 05, 2011 - 03:32 PM

Post subject: RE: Adapting stream output methodology from input capture Preface: I have not read all 13 pages of comments -- just the original tutorial, and pages 11 - 13 of comments (i.e., "recent" comments).

After reading the tutorial, I have written my ISR as:

Code:

ISR(USART1_RX_vect) {

uint8_t rxByte;

uint8_t dummyByte;

if(!rxFlag1) { //Buffer has been read by decode function

while(!(UCSR1A & (1 << RXC1)))

{}

rxByte = UDR1;

if(rxByte == 10 || rxByte == 13) { //NL or CR

Page 224: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

rxFlag1 = 1;

}

else {

if(bufcnt1 > (RXBUFSZ-1))

bufcnt1 = (RXBUFSZ - 1);

rx_buffer[bufcnt1] = rxByte;

bufcnt1++;

}

}

else {

while(!(UCSR1A & (1 << RXC1)))

{}

dummyByte = UDR1; //throw away bytes received before ready

}

}

If I am understanding a comment several pages earlier (by Dean?) correctly, the while(!...) loops are not necessary, because the bit will definitely be set if the ISR is called. Is this correct? Does this change if the incoming messages are extremely rapid, i.e., faster than the ISR can handle them? clawson - Apr 05, 2011 - 05:56 PM

Post subject: RE: Adapting stream output methodology from input capture

Quote:

Is this correct?

Yes, there are two ways to use a bit such as RXC or UDRE. One is to simply have a "polled" receive or transmit routine which is called synchronously and does not return until the action has completed. In this case you "block" on the specified bit in a while() loop that repeats until the desired state is achieved. The other way to use the flags is to make use of interrupts and do things asychronously so

Page 225: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

the main() code can get on and do other things and when triggered the ISR fires and receives/sends the character. The main() code *may* block in this case but it will be on a volatile flag set by the ISR to say something of relevance has happened (perhaps an entire string has been received to the buffer or similar).

What you should not do is mix asychronous use of the flags together with synchronous polling loops. In fact, unless it's guaranteed to happen in microseconds, no ISR should ever block on an asychronous event flag because it could be seconds or minutes before the event occurs (during which time the entire interrupt/main system is blocked from doing anything). Of course you can "block" on a flag even that you KNOW is already set without any problem (which is what your code does) but why would you do this. Even if the while() is done only once it's one time more than you need.

You are on dodgy ground if you start writing ISRs that take longer to process than the period of the event they are reacting too as you may never "get out". But with circular ISR buffering as long as the buffer is large enough to cope with a "sudden burst of activity" (assuming there's then an interval allowing for the buffer to be processed/flushed) then you'll be OK. hobbss - Apr 05, 2011 - 06:02 PM

Post subject: RE: Adapting stream output methodology from input capture Clawson: thanks for the reply. As you may have noted, I am also involved in a ... heated... discussion about serial comms over in the other forum. This was an attempt to not get this thread offtrack (not an attempt at cross posting).

I will remove the while loops from my code. That said, is your warning about lengthy ISRs directed explicitly at this piece of code? I am unsure how to make it leaner. My handling routine (that deals with the actual message) may be slow, in which case I am fine throwing away incoming data -- which is what I think happens with the whole rxFlag1 variable (reset by the handling function when it is done). clawson - Apr 05, 2011 - 06:12 PM

Post subject: RE: Adapting stream output methodology from input capture

Quote:

That said, is your warning about lengthy ISRs directed explicitly at this piece of code? I am unsure how to make it leaner

No, by a fluke (perhaps by design) there's no problem with the while() loops you have because they check for a bit that's known to be set so don't (hardly!) delay the action. But more generally you should always be asking yourself if you are really doing the right thing if you ever put ANY kind of

Page 226: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

iterative loop in an ISR. The goal is that through whatever code path they always complete in a time measured in microseconds (on 1MHz..20MHz processors). With Serial Rx your ISR is almost always going to be identical. You pick up UDR and you put it into a circular buffer at the write pointer position that is then incremented and if it wraps then reset it to the beginning (hence "ring" or "circular"). This action is the only work that HAS to be in the ISR, any "data processing" should be handled outside the ISR with I enabled again so nothing else is being blocked from happening. Having said that some people might put a special check for '\n' in a RXC ISR if they need quick/special notification of the "end of sentence". hobbss - Apr 05, 2011 - 06:22 PM

Post subject: RE: Adapting stream output methodology from input capture Noted. Thanks for the info. I will refrain from using possibly infinite loops in ISRs in the future. anil85 - Apr 20, 2011 - 05:02 PM

Post subject: Well explained...thanks... ucupzzz - Jul 25, 2011 - 03:48 AM

Post subject: Hii... i`ve simple code that make me so confused...

i want to turn on the led from the keyboard via usart...

this is the code:

Code:

#include <avr/io.h>

#include <avr/interrupt.h>

#include <inttypes.h>

#define LED PORTA

uint8_t data;

ISR(USART_RXC_vect)

{

data=UDR;

[b]LED=data;[/b]

}

Page 227: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

void USARTinit(uint16_t ubrr_value)

{

set baudrate

UBRRL=ubrr_value;

UBRRH=(ubrr_value>>8);

UCSRC=(1<<URSEL)|(3<<UCSZ0);

//ENABLE THE RECEIVER AND TRANSMITTER

UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE); //REGISTER RXCIE YANG MENGAKTIFKAN INTERUPT NYA...

sei();

}

int main(void)

{

DDRA=0XFF;

USARTinit(71);

while(1)

{

};

}

Page 228: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

The program work well...

but if i want to make something different.. like this code :

Code:

#include <avr/io.h>

#include <avr/interrupt.h>

#include <inttypes.h>

#define LED PORTA

uint8_t data;

ISR(USART_RXC_vect)

{

data=UDR;

}

void USARTinit(uint16_t ubrr_value)

{

// set baudrate

UBRRL=ubrr_value;

//UBRRH=(ubrr_value>>8);

Page 229: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

// Asynchronous mode

// No Parity

// 1 Stop Bit

// Char size 8

UCSRC=(1<<URSEL)|(3<<UCSZ0);

//ENABLE THE RECEIVER AND TRANSMITTER

UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE); //REGISTER RXCIE YANG MENGAKTIFKAN INTERUPT NYA...

sei();

}

int main(void)

{

DDRA=0XFF;

USARTinit(71);

while(1)

{

[b]LED=data;

Page 230: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

[/b]};

}

The program cannot work like the previous program...

how to make its work in while(1){};....? larryvc - Jul 25, 2011 - 04:29 AM

Post subject:

Code:

uint8_t data;

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

Code:

volatile uint8_t data;

Also Bold characters

Code:

[b] test [/b]

do not work in code blocks. ucupzzz - Jul 25, 2011 - 04:38 AM

Post subject: great.. thank you very much...

"volatile"...... Daniel_sky - Sep 17, 2011 - 12:19 PM

Post subject: 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:

Code:

Page 231: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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

Page 232: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

/* 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 clawson - Sep 17, 2011 - 01:01 PM

Post subject:

Quote:

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

Page 233: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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. Daniel_sky - Sep 17, 2011 - 01:43 PM

Post subject:

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 JohanEkdahl - Sep 17, 2011 - 01:57 PM

Post subject:

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! Daniel_sky - Sep 17, 2011 - 02:17 PM

Post subject:

Quote:

grinding our teeth for a few minutes

What can I say? You should have a good dentist Razz.

Page 234: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

Ok, seriously thank You guys for Your patient, selflessness and so kind welcome in forum Smile. Big Bravo for AVRfreaks Team for the great job They are doing for us to make our lives easier Very Happy!!!

Greetings

Daniel JohanEkdahl - Sep 17, 2011 - 06:22 PM

Post subject:

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.) clawson - Sep 19, 2011 - 09:50 AM

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

http://www.avrfreaks.net/index.php?name ... highlight= kel31710 - Nov 09, 2011 - 01:55 AM

Post subject: ATMEGA8515 Problem 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:

Page 235: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

ISR(_VECTOR(9)){

}

while the second method isn't as nice it gets the job done indianajones11 - Nov 09, 2011 - 02:51 AM

Post subject: You would've torn out less hair if you'd paid attention to the warning about a misspelled (ISR ) handler . Wink kukacomone - Nov 21, 2011 - 03:55 PM

Post subject: Hey! Smile

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? clawson - Nov 21, 2011 - 04:05 PM

Post subject: 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. kukacomone - Nov 21, 2011 - 07:50 PM

Post subject: Alright, thanks for the answer! Smile

(I posted my issue here) sylwos - Nov 24, 2011 - 08:57 PM

Post subject: 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 ?

Code:

Page 236: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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++;

}

clawson - Nov 24, 2011 - 09:05 PM

Post subject: Use:

Code:

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. Koshchi - Nov 24, 2011 - 09:30 PM

Post subject: 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. bkbkbk - Dec 01, 2011 - 09:53 PM

Post subject: usart interrupt problem 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

Page 237: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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!

Code:

#include <avr/io.h> // Most basic include files

#include <avr/interrupt.h> // Add the necessary ones here

#include <avr/sleep.h>

#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)

Page 238: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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

Page 239: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

{

// 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)

{

}

}

sternst - Dec 01, 2011 - 10:59 PM

Post subject: RE: usart interrupt problem

Code:

/* Set frame format: 8data, 1stop bit */

UCSR0C = (1<<USBS0)|(3<<UCSZ00);

The comment does not match the code.

Quote:

When I program my ATmega328

Code:

Page 240: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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. indianajones11 - Dec 02, 2011 - 08:58 AM

Post subject:

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 . andace - Dec 17, 2011 - 08:47 PM

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

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;

Page 241: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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)

Page 242: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

{

CLOCK++;

contor =0;

if(strcmp(jumper,"clock")==0)

clock();

else

alarm();

}

}

int main( void )

{

sei();

USART_Init ( MYUBRR );

Timer_Init();

while(1)

;

}

void clock()

{

Page 243: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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 );

Page 244: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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;

}

Page 245: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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

}

clawson - Dec 17, 2011 - 08:59 PM

Post subject:

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 ""

Page 246: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

(d) this is almost totally meaningless:

Code:

UCSR1B = 0b10011000;

UCSR1C = 0b00001110;

Why don't you use symbolic names? andace - Dec 17, 2011 - 09:24 PM

Post subject:

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?

Page 247: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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(5Cool" 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 clawson - Dec 18, 2011 - 01:28 PM

Post subject:

Quote:

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

Try not to be an idiot. Koshchi - Dec 18, 2011 - 06:51 PM

Post subject:

Quote:

Let me eplain this:

UCSR1B = (1 << RXCIE1)|(1<<RXEN1)|(1<<TXEN1);

*Enable the USART Recieve Complete ,Enable receiver and transmitter

Page 248: assi…  · Web viewPost subject: I wouldn't have thought you'd have time to wait for the SPM operation of writing PROGMEM data to complete anyway

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.

All times are GMT + 1 Hour

Powered by PNphpBB2 © 2003-2006 The PNphpBB Group

Credits