Receive byte on ATMEGA128 ?

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

Guys,

I got the code below from ATMEGA128 datasheet from ATMEL,

How can I use it in main function ?
Every suggestions or ideas will be very appreciated,

Thanky you,

is it :

main()
{
  char b;
 do
  {
    b = USART_Receive();
    lcd_string(b);
  }
 while (b="")
}

Function :

unsigned char USART_Receive( void )
{
/* Wait for data to be received */
while ( !(UCSRA & (1<<RXC)) )
;
/* Get and return received data from buffer */
return UDR;
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't think your code will compile. The register names don't look right for a mega128 as there is usually a 0 or 1 in the name to determine which usart since there are two. Secondly,
while (b="")

should be some thing like while (b==' ');
it is easy to confuse assignment = and equality == in C. Usually if you see = in a conditional statement (if,while etc) it is usually wrong. Double quotes are for strings, single quotes and for characters.
Relaise that USART_receive will wait until a character arrives, so your do while loop might not work as you want.

You have also omitted any configuration for the USART. Not much will happen without it.

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

Kartman wrote:
I don't think your code will compile. The register names don't look right for a mega128 as there is usually a 0 or 1 in the name to determine which usart since there are two. Secondly,
while (b="")

should be some thing like while (b==' ');
it is easy to confuse assignment = and equality == in C. Usually if you see = in a conditional statement (if,while etc) it is usually wrong. Double quotes are for strings, single quotes and for characters.
Relaise that USART_receive will wait until a character arrives, so your do while loop might not work as you want.

You have also omitted any configuration for the USART. Not much will happen without it.

I put the configuration:

void usart_init( unsigned int ubrr )
{
/* Set baud rate */

	UBRR0H = (unsigned char)(ubrr>>8);
	UBRR0L = (unsigned char)ubrr;
	/* Enable receiver and transmitter */
	UCSR0B = (1<<RXEN)|(1<<TXEN);
	/* Set frame format: 8data, 2stop bit */
	UCSR0C = (1<<USBS)|(3<<UCSZ0);
}

The function :

unsigned char usart_receive( void )
{
/* Wait for data to be received */
while ( !(UCSR0A & (1<<RXC)) )
;
/* Get and return received data from buffer */
return UDR0;
}

on main :

do 
	  {
		  c_byte = usart_receive();
           usart_transmit(c_byte);
          lcd_string(c_byte);
	  }
	  while (c_byte==' ');
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can see the echo, but how can I display character received in my LCD ?

do 
	  {
		  c_byte = usart_receive();
           usart_transmit(c_byte);
          
	  }
	  while (c_byte==' ');
        lcd_string(c_byte);

thanks

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

I can display 1 character with this code,
any ideas on displaying one word ( string ) ?

thanks


 do 
	  {
		  c_byte = usart_receive();
		  lcd_data(c_byte);
           usart_transmit(c_byte);

          
	  }
	  while (c_byte==' ');
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Visovian wrote:
Look at my example in
https://www.avrfreaks.net/index.p...

Thank you my friend, I'll see it..

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

How can I eliminate 0A and 0D ?
I wanna display a string with :

void usart_pstr(unsigned char *s) {

	// loop through entire string

	while (*s) {
		usart_transmit(*s);
		s++;
	}
}

but always got 0A and 0D in between of character,

How can I avoid them ?

thanks

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

What does usart_transmit do? (maybe it does what usart_pstr is meant to do)

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

usart_transmit :

void usart_transmit( unsigned char data )
{
	/* Wait for empty transmit buffer */
	while ( !( UCSR0A & (1<<UDRE)) )
	;
	/* Put data into buffer, sends the data */
	UDR0 = data;
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
but always got 0A and 0D in between of character,
These come from the terminal when you press key. Your usart_transmit() sends them back.

(I only guess without seeing the complete code.)

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

Visovian wrote:
Quote:
but always got 0A and 0D in between of character,
These come from the terminal when you press key. Your usart_transmit() sends them back.

(I only guess without seeing the complete code.)

Complete code related with USART :

void usart_init( unsigned int ubrr )
{
	/* Set baud rate */

	UBRR0H = (unsigned char)(ubrr>>8);
	UBRR0L = (unsigned char)ubrr;
	/* Enable receiver and transmitter */
	UCSR0B = (1<<RXEN)|(1<<TXEN);
	/* Set frame format: 8data, 2stop bit */
	UCSR0C = (1<<USBS)|(3<<UCSZ0);
}

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



void usart_pstr(unsigned char *s) {

	// loop through entire string

	while (*s) {
		usart_transmit(*s);
		s++;
	}
}


unsigned char usart_receive( void )
{
	/* Wait for data to be received */
	while ( !(UCSR0A & (1<<RXC)) )
	;
	/* Get and return received data from buffer */
	return UDR0;
}

on main :

if (adcA != 0)
			{
				// itoa(adcA,volts,5);
				sprintf(volts,"adc=%.6fmV",adcA);
				lcd_string(volts);
				_delay_ms(2000);
				//measure temperature
				lcd_cmd(0x80);//put the cursor into the first row
				_delay_ms (10);
				lcd_cmd(0x01);//Clear display
				adcresistance = (long)(10230000/adc_result-10000);
				
				//d = ntc_get_temp(adcresistance, (double)0.947070725e-3, (double)2.450662058e-4, (double)1.853992838e-7);
				d = ntc_get_temp(adcresistance, (double)0.947070725e-3, (double)2.450662058e-4, (double)2.159992838e-7);
				//d = ntc_get_temp(adcresistance, (double)1.129148e-3, (double)2.34125e-4, (double)1.853992838e-7);
				//Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
				sprintf(tempCelcius,"temp=%.6fC",d);
				//display temp to LCD
				lcd_string("Temp Value");
				lcd_cmd(0xC0);//goto second row
				//lcd_string("Value of PF0");
				_delay_ms(100);
				lcd_string(tempCelcius);
				usart_pstr(tempCelcius);
				_delay_ms(3000);
			}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Visovian wrote:
Quote:
but always got 0A and 0D in between of character,
These come from the terminal when you press key. Your usart_transmit() sends them back.

(I only guess without seeing the complete code.)

I didn't press enter, because the board is sending the result itself...

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

I have simplified your code and tested on my board.
Got no 0D or 0A.
See the picture.

//atmega128 (tested with m88)
#include 
#include 
#include 

#define BAUD    9600UL        
#define myubrr  (F_CPU/(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, 2stop bit */
   UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}

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

void usart_pstr(unsigned char *s) 
{
   // loop through entire string
   while (*s) {
      usart_transmit(*s);
      s++;
   }
}

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

char tempCelcius[17];
double d;

int main()
{
   usart_init(myubrr); 
   while(1)
   {
      d = 1.2345678;
      sprintf(tempCelcius,"temp=%.6fC",d);
      usart_pstr(tempCelcius);
      _delay_ms(3000);
   }
}

Attachment(s): 

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

I still got it
init :


// Define baud rate
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 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<<RXEN)|(1<<TXEN);
	/* Set frame format: 8data, 2stop bit */
	UCSR0C = (1<<USBS)|(3<<UCSZ0);
}

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



void usart_pstr(unsigned char *s) {

	// loop through entire string

	while (*s) {
		usart_transmit(*s);
		s++;
	}
}

main :

usart_init ( BAUD_PRESCALE );
	if (adcA != 0)
			{
				// itoa(adcA,volts,5);
				sprintf(volts,"adc=%.6fmV",adcA);
				lcd_string(volts);
				_delay_ms(2000);
				//measure temperature
				lcd_cmd(0x80);//put the cursor into the first row
				_delay_ms (10);
				lcd_cmd(0x01);//Clear display
				adcresistance = (long)(10230000/adc_result-10000);
				
				//d = ntc_get_temp(adcresistance, (double)0.947070725e-3, (double)2.450662058e-4, (double)1.853992838e-7);
				d = ntc_get_temp(adcresistance, (double)0.947070725e-3, (double)2.450662058e-4, (double)2.159992838e-7);
				//d = ntc_get_temp(adcresistance, (double)1.129148e-3, (double)2.34125e-4, (double)1.853992838e-7);
				//Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
				sprintf(tempCelcius,"temp=%.6fC",d);
				//display temp to LCD
				lcd_string("Temp Value");
				lcd_cmd(0xC0);//goto second row
				//lcd_string("Value of PF0");
				_delay_ms(100);
				lcd_string(tempCelcius);
				usart_pstr(tempCelcius);
				_delay_ms(3000);
			}

Attachment(s): 

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

And I told you many many posts ago that this almost certainly was nothing to do with the AVR (it cannot magically decide to insert 0D/0A where they don't exist) and almost certainly something to do with your PC or the software you are using to receive UART on it. Did you actually investigate that or simply ignore it as you seem to do with most advice you are given here? No one will be interested in making suggestions if you are simply going to ignore the advice given. If you are given an answer you don't understand then ask about it - don't just ignore it.

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

You have pressed "Add CR/LF" button !!!
No wonder then.

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

And in your code you have set 2 stop bits.
Did you set 2 stop bits in the terminal?

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

I don't think two stop bits is a show stopper. It just gives one extra bit of space between chars. But there is one item that might foster better communication between the seven continents... Mr Bianchi77, perhaps you will add your city and country to your profile so we can tell where you live? Talking to folks around the world is fun. Ask any Ham Radio dude.

Imagecraft compiler user

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

Visovian wrote:
And in your code you have set 2 stop bits.
Did you set 2 stop bits in the terminal?

Can you tell me in which line I do that ?
What can I do to fix ?

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

bobgardner wrote:
I don't think two stop bits is a show stopper. It just gives one extra bit of space between chars. But there is one item that might foster better communication between the seven continents... Mr Bianchi77, perhaps you will add your city and country to your profile so we can tell where you live? Talking to folks around the world is fun. Ask any Ham Radio dude.

I tried to update my location but I can't

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

Visovian wrote:
You have pressed "Add CR/LF" button !!!
No wonder then.

How can you know ?? I didn't realize it ??
I didn't press any buttons on the board ...

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

Quote:
You have pressed "Add CR/LF" button !!!

How can you know ?? I didn't realize it ??
I didn't press any buttons on the board ...

I meant the buton in the terminal. See the picture.
Quote:
Did you set 2 stop bits in the terminal?

Can you tell me in which line I do that ?
What can I do to fix ?

In terminal-Menu-Tools-Configuration set Stop bits: 2

Attachment(s): 

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

No I didn't push the button and it's 1 stop bit

Attachment(s): 

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

Ok, I got it...fixed, thank you

Attachment(s): 

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

Make both ends 1 stop bit and avoid the issue. I've rarely seen 2 stop bits used in the field.