| Author |
Message |
|
|
Posted: Jan 07, 2010 - 09:18 PM |
|


Joined: Mar 27, 2002
Posts: 18543
Location: Lund, Sweden
|
|
Ha! My suspicions about bad grounding was well grounded!
Happy that it worked out for you! |
|
|
| |
|
|
|
|
|
Posted: Feb 28, 2010 - 05:01 AM |
|


Joined: Nov 05, 2009
Posts: 15
|
|
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 |
|
|
| |
|
|
|
|
|
Posted: Mar 01, 2010 - 10:38 AM |
|

Joined: Mar 01, 2010
Posts: 2
|
|
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!
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
#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)
{
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;
}
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();
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;
}
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++;
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;
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;
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;
}
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;
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;
}
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;
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! |
|
|
| |
|
|
|
|
|
Posted: Mar 01, 2010 - 11:00 AM |
|


Joined: Jul 18, 2005
Posts: 62270
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
Forget the interrupts and the GPS parsing to start with. Are the basics working? If you simply:
Code:
int main(void) {
init_uart();
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 |
_________________
|
| |
|
|
|
|
|
Posted: Mar 01, 2010 - 03:04 PM |
|

Joined: Mar 01, 2010
Posts: 2
|
|
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..
 |
|
|
| |
|
|
|
|
|
Posted: Mar 01, 2010 - 03:06 PM |
|


Joined: Jul 18, 2005
Posts: 62270
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Quote:
but after inserting the parsing routine, it seems stopped working..
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. |
_________________
|
| |
|
|
|
|
|
Posted: Mar 23, 2010 - 10:55 AM |
|

Joined: Mar 04, 2010
Posts: 5
|
|
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 ? |
|
|
| |
|
|
|
|
|
Posted: Mar 23, 2010 - 11:10 AM |
|


Joined: Jul 18, 2005
Posts: 62270
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
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) |
_________________
|
| |
|
|
|
|
|
Posted: Mar 23, 2010 - 05:19 PM |
|

Joined: Mar 04, 2010
Posts: 5
|
|
How i should convert it ? i never worked with Arduino :\
Any other suggestions in c language ? |
|
|
| |
|
|
|
|
|
Posted: Mar 23, 2010 - 05:57 PM |
|


Joined: Jul 18, 2005
Posts: 62270
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
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. |
_________________
|
| |
|
|
|
|
|
Posted: Mar 23, 2010 - 07:26 PM |
|

Joined: Mar 04, 2010
Posts: 5
|
|
Need some TUTorials about avr interfacing with gps, like TUT using usart..  |
|
|
| |
|
|
|
|
|
Posted: Mar 24, 2010 - 09:59 AM |
|


Joined: Jul 18, 2005
Posts: 62270
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Quote:
Need some TUTorials about avr interfacing with gps, like TUT using usart..
Surely it's the same thing. They almost all use a 4800 baud UART link so this thread applies. |
_________________
|
| |
|
|
|
|
|
Posted: Mar 24, 2010 - 07:12 PM |
|

Joined: Mar 04, 2010
Posts: 5
|
|
|
rnable wrote:
Need some TUTorials about avr interfacing with gps, like TUT using usart..
whoops, I meant parsing gps data with avr..  |
|
|
| |
|
|
|
|
|
Posted: Mar 24, 2010 - 07:51 PM |
|


Joined: Mar 27, 2002
Posts: 18543
Location: Lund, Sweden
|
|
|
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..
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. |
|
|
| |
|
|
|
|
|
Posted: May 21, 2010 - 03:03 AM |
|

Joined: May 21, 2010
Posts: 3
|
|
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. |
|
|
| |
|
|
|
|
|
Posted: May 21, 2010 - 06:30 AM |
|

Joined: Nov 29, 2007
Posts: 3219
|
|
|
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. |
|
|
| |
|
|
|
|
|
Posted: May 21, 2010 - 10:09 AM |
|


Joined: Jul 18, 2005
Posts: 62270
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
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?
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. |
_________________
|
| |
|
|
|
|
|
Posted: Jul 29, 2010 - 06:39 PM |
|

Joined: Apr 11, 2009
Posts: 16
Location: Pittsburgh,PA
|
|
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.
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 )
{
if ( str[i] == '\n' )
{
str[i] = '\0';
return; /* we're done, exit function */
}
}
/* if exit here, must not have been any newline! */
}
//-----------------------------------------------
|
|
|
| |
|
|
|
|
|
Posted: Aug 17, 2010 - 04:40 PM |
|

Joined: Jul 20, 2010
Posts: 36
Location: South Africa
|
|
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
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
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;
//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;
//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;
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? |
|
|
| |
|
|
|
|
|
Posted: Aug 17, 2010 - 04:46 PM |
|


Joined: Jul 18, 2005
Posts: 62270
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Quote:
Why is that?
FAQ#1 |
_________________
|
| |
|
|
|
|
|