Noob: UART comm problem

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

Hello, 

 

I am using Nano 3.0 clone with CH340G USB-UART chip. Programming it with Atmel Studio and flashing with AVRDUDE. I have made the LED blink :)

 

I took the UART_EXAMPLE code from Atmel Studio(?) and tried my best to get the UART to talk to PC/Win 10 serial terminal (Putty, Termite). When I flash the .hex into the 328P, the TX and RX leds blink rapidly. After my code runs, the TX won't blink anymore. The RX led blinks if I send characters from serial terminal (as expected). But there's some disconnect in-between (my code)=>CH340G=>TX led.

 

Any ideas what I could check? Below are my functions to initialize the UART, send, receive bytes.

 

/* Initialize UART */

void InitUART(unsigned char ubrr_val)

{

/* Set the baud rate */

/* Set baud rate */

UBRR0H = (unsigned char)(ubrr_val>>8);

UBRR0L = (unsigned char)ubrr_val;

/* Enable receiver and transmitter */

UCSR0B = (0<<UCSZ02)|(1<<RXEN0)|(1<<TXEN0);

/* Set frame format: 8data, 2stop bit */

// UCSR0C = (1<<USBS0)|(3<<UCSZ00);

UCSR0C = 0

| (0<<UMSEL01) | (0<<UMSEL00)   // Asynchronous USART

| (0<<UPM01) | (0<<UPM00)       // Parity Disabled

| (0<<USBS0)                    // 1 stop bit

| (1<<UCSZ01) | (1<<UCSZ00)     // 8-bit character size

| (0<<UCPOL0)                    // Rising TX, falling RX

;

 

}

 

unsigned char ReceiveByte(void)

{

/* Wait for data to be received */

while ( !(UCSR0A & (1<<RXC0)) )

;

/* Get and return received data from buffer */

return UDR0;

}

 

void TransmitByte( unsigned char data )

{

/* Wait for empty transmit buffer */

while ( !( UCSR0A & (1<<UDRE0)) )

;

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

UDR0 = data;      

}

This topic has a solution.
Last Edited: Sun. Oct 1, 2017 - 05:58 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please use the "<>" code button to post code, it makes it easier to read.

 

I don't see anything glaringly wrong with your code, but a couple of suggestions.

/* Set baud rate */

UBRR0H = (unsigned char)(ubrr_val>>8);

UBRR0L = (unsigned char)ubrr_val;

can be done simpler with

/* Set baud rate */
UBRR0 = ubrr_val;

the compiler knows how to split the value to register in the correct order!

 

Also the USART defaults to 8N1, so no need need to touch UCSR0C register at all.

 

Best to post a small complete program that demos the problem and that we can compile in order to test.

 

Jim

 

Last Edited: Thu. Sep 28, 2017 - 07:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What frequency is the uC running?

How have you verified that it REALLY is running at that frequency?

What BAUD rate are you trying to use?

David (aka frog_jr)

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

As Jim points out above, much of your fiddling with registers is unnecessary as USART defaults to 8-N-1.  This is all you need:

void InitUART(unsigned int ubrr_val)
{
    UBRR0 = ubrr_val;
    UCSR0B = (1<<RXEN0) | (1<<TXEN0);
}

unsigned char ReceiveByte(void)
{
    while ( !(UCSR0A & (1<<RXC0)) );
    return UDR0;
}

void TransmitByte( unsigned char data )
{
    while ( !( UCSR0A & (1<<UDRE0)) );
    UDR0 = data;
}

Where is the code that actually sends/receives data?

 

EDIT: and welcome to the forum!

 

Greg Muth

Portland, OR, US

Atmel Studio 7.0 on Windows 10

Xplained/Pro/Mini Boards mostly

 

 

Last Edited: Thu. Sep 28, 2017 - 08:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try making ubrr_val a 16-bit integer in the USART init function instead of having it be an 8-bit unsigned char.

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

Awesome support you guys! Thank you!

 

I have taken the ideas above and implemented them into the code. The full code is below. 

 

W.r.t. to board frequency, there's an XTAL with marking "12.000" on the package. So I figured it to be 12 MHz XTAL. I have no easy means to check this atm. Even tried to pick it up with a SDR radio but the emission is too low to detected. 

 

The board frequency is defined as this

#define F_CPU 12000000UL

 

However, the wrong baud rate would not stop RX/TX led from blinking?

 

 

1) The expected behaviour of the code would be:

 

- RX & TX leds blinking, typed characters returned to PC terminal. 

 

2) Observed behaviour:

 

- The RX & TX leds blink while flashing, so no faulty leds. Also RX led blinks on application run when characters are send from PC terminal. But no TX on application, no returned chars. 

 

 

The fuse values are lfuse = 0, hfuse = 0, efuse = 0. I used http://www.engbedded.com/fusecalc to decode these. Didn't understand all though, seem to be using EXTCLK and DIV-BY-8. 

 

Here's the full AVRDUDE log 

 

avrdude.exe: Version 5.11, compiled on Sep  2 2011 at 19:38:36
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2009 Joerg Wunsch

             System wide configuration file is "C:\Users\tapio\Projects\Electronics\LoadCell\avrdude\avrdude.conf"

             Using Port                    : COM6
             Using Programmer              : arduino
             Overriding Baud Rate          : 57600
             AVR Part                      : ATMEGA328P
             Chip Erase delay              : 9000 us
             PAGEL                         : PD7
             BS2                           : PC2
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 200
             StabDelay                     : 100
             CmdexeDelay                   : 25
             SyncLoops                     : 32
             ByteDelay                     : 0
             PollIndex                     : 3
             PollValue                     : 0x53
             Memory Detail                 :

                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
               flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
               lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
               signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

             Programmer Type : Arduino
             Description     : Arduino
             Hardware Version: 2
             Firmware Version: 1.16
             Vtarget         : 0.0 V
             Varef           : 0.0 V
             Oscillator      : Off
             SCK period      : 0.1 us

avrdude.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude.exe: Device signature = 0x1e950f
avrdude.exe: safemode: lfuse reads as 0
avrdude.exe: safemode: hfuse reads as 0
avrdude.exe: safemode: efuse reads as 0
avrdude.exe: reading input file "C:\Users\tapio\Projects\Electronics\LoadCell\AStudio\UART\AVR306\UART_Example\Debug\UART_Example.hex"
avrdude.exe: writing flash (542 bytes):

Writing | ################################################## | 100% 0.16s

avrdude.exe: 542 bytes of flash written
avrdude.exe: verifying flash memory against C:\Users\tapio\Projects\Electronics\LoadCell\AStudio\UART\AVR306\UART_Example\Debug\UART_Example.hex:
avrdude.exe: load data flash data from input file C:\Users\tapio\Projects\Electronics\LoadCell\AStudio\UART\AVR306\UART_Example\Debug\UART_Example.hex:
avrdude.exe: input file C:\Users\tapio\Projects\Electronics\LoadCell\AStudio\UART\AVR306\UART_Example\Debug\UART_Example.hex contains 542 bytes
avrdude.exe: reading on-chip flash data:

Reading | ################################################## | 100% 0.12s

avrdude.exe: verifying ...
avrdude.exe: 542 bytes of flash verified

avrdude.exe: safemode: lfuse reads as 0
avrdude.exe: safemode: hfuse reads as 0
avrdude.exe: safemode: efuse reads as 0
avrdude.exe: safemode: Fuses OK

avrdude.exe done.  Thank you.

 

And here is the code, updated with changes and tested after that.

 

#if __GNUC__
#include "avr/io.h"
#else
#include "ioavr.h"
#endif

#include "atmel_start.h"

#include <util/delay.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <time.h>

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

/* Prototypes */

void InitUART(long int ubrr_val);
unsigned char ReceiveByte(void);
void TransmitByte(unsigned char data);

int main(void)
{
	system_init();
	
	/* Set the baudrate to 9600 bps using internal 8MHz RC Oscillator */
	InitUART(BAUD_PRESCALE);
	
	while (1) {
		PORTB |= (1<<PORTB5); // Turn ON LED
		TransmitByte(ReceiveByte());
	}

	return 0;
}

/* Initialize UART */
//void InitUART(unsigned char ubrr_val)
void InitUART(long int ubrr_val)
{
	 /* Set the baud rate */
	 UBRR0 = ubrr_val;
	 /* Enable receiver and transmitter */
	 UCSR0B = (0<<UCSZ02)|(1<<RXEN0)|(1<<TXEN0);	 	 
}

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

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

 

 

 

 

 

 

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

The fuse values are lfuse = 0, hfuse = 0, efuse = 0

Unlikely.

 

Show the avrdude command line, not just the output.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

I don't see in the code above where F_CPU gets set?  so it will default to a value that will not match the actual cpu speed and produce a baud rate setting that is incorrect.

Fuse settings can not be right, as it would use external clock, and if not supplied, would not talk to the programmer at all!

 

Jim

 

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

Hello,

 

The AVRDUDE is set through the Atmel Studio as external tool as:

 

Command: C:\Users\tapio\Projects\Electronics\LoadCell\avrdude\avrdude.exe

Parameters: -F -v -patmega328p -carduino -PCOM6 -b57600 -D -Uflash:w:"$(ProjectDir)Debug\$(ItemFileName).hex":i -CC:\Users\tapio\Projects\Electronics\LoadCell\avrdude\avrdude.conf

 

The .conf file is the default, no edits there. I've attached it as it is rather long (due to forum limitation on attachments, renamed it to .txt). 

 

The flashing procedure appears to work ok. 

 

The fuse values are picked from the AVRDUDE output; I have understood that the EXTCLK is the XTAL on board. Is this incorrect?

 

The F_CPU gets set in clock_config.h, part of the Atmel start init:

/* Auto-generated config file clock_config.h */
#ifndef CLOCK_CONFIG_H
#define CLOCK_CONFIG_H

// <<< Use Configuration Wizard in Context Menu >>>

#ifndef F_CPU
#define F_CPU 12000000UL
#endif
// <h> ADC Clock Settings
// <y> ADC Clock source
// <CLKadc"> CLKadc
// <i> This defines the clock source for the ADC module
// <id> adc_clock_source
#define CONF_ADC_SRC CLKadc

// </h>

// <h> TC1 Clock Settings
// <y> TC1 Clock source
// <CLKio"> CLKio
// <i> This defines the clock source for the TC1 module
// <id> tc16_clock_source
#define CONF_TC1_SRC CLKio

// </h>

// <<< end of configuration section >>>

#endif // CLOCK_CONFIG_H

 

For completeness, I've packed up the project directory as UART_Example.zip. The main is in uart_polling.c.

 

Thank you for your help, very much appreciated.

 

Attachment(s): 

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

Command: C:\Users\tapio\Projects\Electronics\LoadCell\avrdude\avrdude.exe

Parameters: -F -v -patmega328p -carduino -PCOM6 -b57600 -D -Uflash:w:"$(ProjectDir)Debug\$(ItemFileName).hex":i -CC:\Users\tapio\Projects\Electronics\LoadCell\avrdude\avrdude.conf

The yellow-highlighted argument means AS is talking to the bootloader on your Nano clone, not to an ISP programmer.  The default bootloader on a Nano does not correctly report fuse values.  Most bootloaders don't.  >>No<< bootloaders are able the >>change<< fuses at all.

 

W.r.t. to board frequency, there's an XTAL with marking "12.000" on the package. So I figured it to be 12 MHz XTAL. I have no easy means to check this atm. Even tried to pick it up with a SDR radio but the emission is too low to detected. 

 

The board frequency is defined as this

#define F_CPU 12000000UL

A genuine Nano runs at 16 MHz, not 12 MHz.  So that's a bit peculiar.

 

I have made the LED blink :)

When you did, was the speed >>exactly<< as you expected it?  How did you make it flash?

 

I would upload this:

#define F_CPU 12000000UL
#include <avr/io.h>
#include <util/delay.h>

int main(void) {

  DDRB = 0x3F;

  while(1) {
    PINB = 0x3F;
    _delay_ms(1000);
  }   

}

Forget about Atmel start and anything else for now.  Confirm that an LED on port B (any pin) flashes >>exactly<< one second on and one second off.  If it is flashing faster, then your board is probably running at 16 MHz.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Fri. Sep 29, 2017 - 04:38 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello, 

 

Excellent idea. I increased the time to 10 000 ms to improve measurement accuracy. The led on/off full cycle (i.e. led on => led on) take about 15.5 s, not 10 s as expected.

 

Next I changed the 

 

#define F_CPU 16000000UL

Now the full cycle takes 20 s. Does this mean that the CPU runs on internal 8 MHz RC oscillator or on the external 16 MHz crystal osc? 

 

How does 

PINB = 0x3F;

 

achieves complementing the led state?

 

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

Found out about pin toggling:

 

Bits 7:0 – PINBn: Port B Input Pins Address [n = 7:0] Writing to the pin register provides toggle functionality for IO. Refer to Toggling the Pin.

 

18.2.2. Toggling the Pin Writing a '1' to PINxn toggles the value of PORTxn, independent on the value of DDRxn. The SBI instruction can be used to toggle one single bit in a port.

 

 

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

Does this mean that the CPU runs on internal 8 MHz RC oscillator or on the external 16 MHz crystal osc? 

It means it's running at about 8 MHz.  It tells us nothing about the clock source.  However, we can probably infer that it's running from the RC oscillator, since an 8 MHz crystal should have resulted in exactly 15 seconds, not 15.5.  The difference is likely a consequence of the inherently poor accuracy of the internal RC oscillator (although it can be calibrated).

 

You can read fuses in software, (although as mentioned few bootloaders are written to do this themselves).  In this way you can be certain what the fuse values are.

 

How does 

PINB = 0x3F;

achieves complementing the led state?

The datasheet is your friend.

 

Modern (i.e anything in the last ten years) have a toggle feature:

 

To read fuses, and display them in turn, on 8 LEDs connected to PORTD:

 

#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/boot.h>

int main(void) {

  DDRB = 0x0F;
  DDRD = 0xFF;

  while (1) {
    PORTB = 0x01;
    PORTD = boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS);
    _delay_ms(10000);
    PORTB = 0x02;
    PORTD = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
    _delay_ms(10000);
    PORTB = 0x04;
    PORTD = boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS);
    _delay_ms(10000);
    PORTB = 0x08;
    PORTD = boot_lock_fuse_bits_get(GET_LOCK_BITS);
    _delay_ms(10000);
  }

}

Untested.

 

Connect LEDs (with resistors) to Arduino pins 0 through 11.

 

Pins 8-11 will light depending on which byte is being displayed:

  • 8 => low fuse
  • 9 => high fuse
  • 10 => extended fuse
  • 11 => lock bits

 

Pins 0-7 will represent the fuse bits, with bit 0 on pin 0, etc.  Lit means '1', off means '0'.

 

Be sure to wire up the LEDs with their cathodes GND and their anodes to the Arduino's pins (via resistor) rather than the other way (anodes to VCC, cathodes to Arduino's pins [via resistor]).

 

However, none if this is truly necessary.  You now know what your F_CPU should be set to: 8000000UL.  I haven't looked at your code, but provided it handles the USART correctly, this should get you up and running.

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Fri. Sep 29, 2017 - 07:05 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
You now know what your F_CPU should be set to: 8000000UL. I haven't looked at your code, but provided it handles the USART correctly, this should get you up and running.

With an asterisk...IF the chosen baud rate is 8.0MHz-friendly, and IF the internal oscillator is close to nominal.

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

tapiov wrote:
The led on/off full cycle (i.e. led on => led on)

tapiov wrote:
 I increased the time to 10 000 ms ...Now the full cycle takes 20 s. Does this mean that the CPU runs on internal 8 MHz RC oscillator or on the external 16 MHz crystal osc? 

 

The LED is 10 sec ON. 10 sec OFF.

The CPU runs on 16 MHz. (if you defined F_CPU = 16 MHz)

 

Last Edited: Sat. Sep 30, 2017 - 04:32 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Again, many thanks for the help.

The F_CPU is indeed 16 MHz. The toggling happens every 10 s as would be expected. I need to double check this still.

If it's 16 MHz, it would point to ext clocking as the internal RC osc would be 8 MHz.

I will also use the above code and leds to read the real fuse values. I will get back with more information in couple of days.

Edit: Would you know suitable JTAG programmers that would work with Win 10 and AS 7? The cheap ebay ones seem to be limited to AS versions below 5. If needed I will get ATJTAGICE from Microchip but getting something a little cheaper would be preferred.

Last Edited: Sat. Sep 30, 2017 - 05:54 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The LED is 10 sec ON. 10 sec OFF.

The CPU runs on 16 MHz. (if you defined F_CPU = 16 MHz)

Ah yes, I misread what the OP was saying.

 

And 16 Mhz makes more sense because that's what the Nano is meant to run at.

 

Dunno why he's seeing a crystal labelled 12.000 though...

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

I checked the CH340G datasheet, it needs a 12M crystal. So that's why.

I took pictures of front and back of the board, they are attached. In front.png, you can see the large can type crystal, the marking is not visible but it clearly reads "12.000". It's the crystal for CH340G. Next to AT328, there's a smaller metal package which is the 16M crystal. It has marking but it is not readable even with a lit loupe. This 16M crystal is connected between pin 2 (XCK) and pin 7 (XTAL1).

Next I will proceed to read the fuses. Also interested on your recommendations on programmers (see my previous post)

Attachment(s): 

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

The 328p has no JTAG interface. It has only a debugWire single-wire interface for debugging, and the normal ISP interface for programming.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

tapiov wrote:
getting something a little cheaper would be preferred.

Look at an XPlained Pro or Mini - with the debugger on-board.

 

But, that quote again:

 

 

js wrote:
[not having a debugger is] like a mechanic not having any spanners.

 

See: http://www.avrfreaks.net/comment...

 

And: http://www.avrfreaks.net/comment...

 

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

So we have established 16M to be the F_CPU. Back to the original question: http://www.avrfreaks.net/comment...

 

- Regardless of baud rate, why the TX/RX leds are not blinking, besides when flashing (expected, confirms that both leds are working) and when sending data from PC terminal (RX blinks, as expected, confirms USB-UART function).

 

I found this schematic of CH340G based Nano 3.0 clone. http://actrl.cz/blog/wp-content/...

 

Made a lot of tests, finally driving the pins directly. Measured them with DMM and zeroed in on the root cause using the schematic and AT328 manual. 

 

 

Finally, it turned around that REMOVING ALL ATMEL START INIT JUNK and just using plain code:

 

/*
 * PLAIN_UART.c
 *
 * Created: 2017-10-01 20:44:46
 * Author : tapio
 */ 

#define F_CPU 16000000UL

#include <avr/io.h>
#include <util/delay.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <time.h>

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

/* Prototypes */

void InitUART(long int ubrr_val);
unsigned char ReceiveByte(void);
void TransmitByte(unsigned char data);

int main(void)
{	
	/* Set the baudrate to 9600 bps using internal 8MHz RC Oscillator */
	InitUART(BAUD_PRESCALE);
	
	while (1) {
		PORTB |= (1<<PORTB5); // Turn ON LED
		TransmitByte(ReceiveByte());
	}

	return 0;
}


void InitUART(long int ubrr_val)
{
	UBRR0 = ubrr_val;
	UCSR0B = (1<<RXEN0) | (1<<TXEN0);
}

unsigned char ReceiveByte(void)
{
	while ( !(UCSR0A & (1<<RXC0)) );
	return UDR0;
}

void TransmitByte( unsigned char data )
{
	while ( !( UCSR0A & (1<<UDRE0)) );
	UDR0 = data;
}

 

WORKS! The characters are echoed back just as expected. Lesson: beware of pre-written code especially if you don't know what it does. Assuming things are ok is the root of all evil :)

 

Thank you all for your great help and patience!

 

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

Today's avr compilers do not need this line.