UART atmega328p send help pls

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

First time making a post on a forum, so, guess I'll try my best.
 

Now, this is a story all about how

My Baud rate got flipped-turned upside down

And I'd like to take a minute just sit right there

I'll tell you how serial communication became my worst Night-mare.

In west California I was born and raised
In my bedroom is where I spend most of my days
Chillin' out maxin' relaxin' all cool

And all bootin' some 'duinos outside of my room (bluetooth)

When an couple of chips
They were so cool!

Started making errors in my serial network

I got one little error and my phone got scared

And said "#$U*(A*%!  @*&ÄRD!" (due to baud rate errors, I assume)
 

I begged and tweaked with her day after day

But she compiled my script and sent me an error, no way!

She gave me a " #@$(Å(! " and then she gave me a " ä^&ö# "

I put my headphones on and said "Well, fuck it"

 

My first class, yo' this is bad

Sippin' Java out of my coffee glass

Is this what the people of Comcast Living like?

Hmmmm I should make a forum post... (and one that rhymes too)

 

But wait I hear there're prissy, bourgeois and all that (Sorry forum guys, but it had to rhyme)

Is this the type I should send my script at? (Don't end a sentence with a preposition)

I don't think so

I'll see when it gets there

I hope there prepared for my worst night-mare!

 


#include <avr/io.h>

#define F_CPU 16000000
#define BAUD 9600
#define BRC ((F_CPU/16/BAUD) - 1)

int main(void)
{
	
	char ReceivedByte;
	DDRB |= (1<<PINB0); //Turn the pin on
	
	UBRR0H = (BRC >> 8));
	UBRR0L = BRC);
	UCSR0B = (1 << RXEN0) | (1 << TXEN0); //Turn on the transmission and reception circuitry
	UCSR0C = (1 << UCSZ00) | (1 << UCSZ01); // Set Frame format: 8data, 1stop bit
	
    while(1)
    {
        while ((UCSR0A & (1 << RXC0)) == 0 ) {};// Do nothing until data have been received and is ready to be read from UDR
		ReceivedByte = UDR0; 
		
		if (ReceivedByte != 0) { //blink LED if it receives a packet that is not '0'
			PORTB |= (1 << PINB0); 
		} else { //turn LED off if the packet is '0'
			PORTB &= ~(1 << PINB0);
		}
		
		while ((UCSR0A & (1 << UDRE0)) == 0) {}; 
		UDR0 = ReceivedByte; //bounce the signal back to the sender (my phone)
    }
	return 0;
}

For some reason, when I send packets of any character to the atmega328p, it returns them in random characters my phone doesn't support

pls halp

This topic has a solution.

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

Entertaining way to pose a question. :)

 

Have you verified that the uC is actually running at 16MHz?

(Did you clear the CKDIV8 fuse - 9.2.1 in datasheet?)

 

Easy way to verify the cpu frequency is to write a test program that blinks

a LED once per second and then time the blinks.

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

Alright, I'll try the LED thing. I don't have access to my computer today, but I will tomorrow.

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

Recently (last week) exactly the same problem. Did you check the Baud?

And did you check your controller connected to the mega. And did you connect rx and tx correct (if you send something to turn a led on, is the led turning on)

 

Furthermore, do you use an external crystal. What I read was that the internal one is not precise enough to do UART/USART.

 

I have a 644 which is largely equal to 328. So lateron I might copy my code here for your education.

 

I am not an expert, but I think this is wrong:

while ((UCSR0A & (1 << UDRE0)) == 0) {}; 
		UDR0 = ReceivedByte; //bounce the signal back to the sender (my phone)

It should be something like:

// This function writes the given "data" to the USART which then transmit it via TX line
void USART_Transmit(  char string[] ) // Extracted function from the datasheet
{    
    int i=0;
    //define the string to be transmitted
    while(string[i] != 0x00)
    {
        //transmit the string by putting characters into UDR one by one
        UDR0 = string[i++];
        //wait until UDR is empty to take new byte
        while(!(UCSR0A & (1<<UDRE0)));
    }    
}

One last tip: in the manual of the 328 are normally example codes, for UART they included a transmit and receive piece, you only need to make the init and loop. It is great to start with especially if you were like me banging your head.

Last Edited: Mon. Mar 23, 2015 - 06:24 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am not an expert, but I think this is wrong:

In what way? You mean blocking on UDRE0 before rather than after writing UDR0? There's no problem with doing that. In fact waiting before is probably the more common choice.

 

In fact I would question your USART_Transmit() all together. When it comes to sending strings you should surely already have a USART_Sendchar() or something? So your send string becomes:

void USART_Transmit(  char string[] ) // Extracted function from the datasheet
{    
    int i=0;
    //define the string to be transmitted
    while(string[i] != 0x00)
    {
        USART_Sendchar(string[i++]);
    }    
}

No sign of any UDRE or UDR in that as you only touch those in one place (within the sendchar() routine). What's more your routine does not need to use array indexing (and the use of "int" limits it to a max possible 32767 characters). You can just:

void USART_Transmit(  char string[] ) // Extracted function from the datasheet
{    
    while(*string)
    {
        USART_Sendchar(*string++);
    }    
}

No need for "i".

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

I am sorry clawson, this was kinda project I struggled with as well and wanted to give some help.

But the responses here are really professional, so I keep it for now by asking questions myself, a lot to learn... smiley

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

I have managed to get an LED to turn on when a packet is received. It just doesn't send back the right characters. I will order some crystals for this use and see if that helps.

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

Baudacity, better to wait for an answer from 1 of the more advanced programmers.

Since you apprently have a connection.

 

I would love to help, but there are better suited members here.

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

And while your signature is funny AT FIRST it does become boring and distracting for EVERY post.

 

Of course the moderators can delete it but it may be best if you choose something more sensible or smaller. wink

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

I did actually manage to clear the CKDIV8 fuse (I think) by putting in " avrdude -p m328p -c usbtiny -U lfuse:w:0xE2:m -U hfuse:w:0xD9:m " . And now I have progressed from receiving random non-ascii characters to random ascii characters, mostly dashes and question marks. 14.7456 mhz oscillators are on the way to help with the serial coms (don't know if I actually needed them, but they were cheap and should help).

Last Edited: Tue. Mar 24, 2015 - 05:29 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

BAUDacity wrote:

I did actually manage to clear the CKDIV8 fuse (I think) by putting in " avrdude -p m328p -c usbtiny -U lfuse:w:0xE2:m -U hfuse:w:0xD9:m " .

Even though you have a 16MHz crystal connected to the uC, it is still running at 8MHz using the internal RC oscillator. (lfuse=0xE2, see Table 28-9 in datasheet.)

 

Look at Table 9-3 and Table 9-4 to select values for CKSEL3:0 for using a 16MHz crystal.

 

Run the Blinking LED test program (timing the blinks) to verify that uC is actually running at 16MHz.

 

 

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well... uh
Chuck99 came out 

And stated that I might have a fuse out

I ain't tryin to facepalm yet

I just got here

I sprang with the quickness like lightning, disappeared

 

I jumped on my computer and when it booted up.

I booted Atmel studio and thought "I couldn't have @@@@@## up!"

if anything I could say that the datasheet was incorrect.

But I thought "nah forget it, I just failed to double check"

 

I thought the chip was about 16 mhz

I was facepalming so hard I thought "Man... this hurts"

I looked at my 'mega

I was finally there!

I could control this LED without leaving my chair.

 

tl;dr : I misread the datasheet and thought atmega's ran at 16 mhz, as opposed to 8

 

Thanks everybody (and The Fresh Prince) that helped, later!

Last Edited: Thu. Mar 26, 2015 - 02:43 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please try and keep the language clean. Edit text above.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Will it ever stop? Yo, i don't know.
Turn on the led, i'll glow
To the extreme, i work the code like a vandal
Light up the stage and wax a bug like a candle

This scratch is makin me itch........