Tx port is constantly high even after enabling serial communication

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

I'm trying enable serial transmission (UART Tx) on my AVR atmega328p embedded on an Uno board. I'm trying to do all this without any of Arduino libraries except its register header file.

 

Here is my code taken almost directly from the datasheet USART example:

#define F_CPU 16000000L

#include <util/delay.h>
#include "header/registers.h" // Just a list of registers mapped to memory.

#define BAUD 9600
#define MYUBRR (F_CPU / 8 / BAUD-1)/2

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;
}

int main(void){
  USART_Init(MYUBRR);
  while (1){
     USART_Transmit(0x1);
     _delay_ms(1000); // wait 1 second.
  }
  return 0;
}

The builtin `Tx` LED on the Uno board is flashing as expected every second BUT a connected LED to the Tx port on Uno is still constantly high.

 

Is the `Tx` port on Uno not directly attached to the chip?

 

This topic has a solution.
Last Edited: Tue. Jan 18, 2022 - 05:17 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avruser1523 wrote:
Is the `Tx` port on Uno not directly attached to the chip?

You could answer that by looking at the schematic, surely?

 

EDIT

 

 I'm trying to do all this without any of Arduino libraries except its register header file.

Are you still using the Arduino IDE, or something else?

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Tue. Jan 18, 2022 - 02:58 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
Are you still using the Arduino IDE, or something else?

No i'm only using avr-gcc, avrdude, a simple text editor and the datasheet.

 

So far everything has been working smoothly (in other cases and examples). But I'm sort of stuck here as I'm not sure why the builtin Tx LED is flashing as expected, but the Tx port isn't.

 

I have look at the schematic here: https://i.stack.imgur.com/Rm50J.jpg

 

To me it looks connected, but I could be wrong.

Last Edited: Tue. Jan 18, 2022 - 03:09 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

avruser1523 wrote:
I'm trying to do all this without any of Arduino libraries except its register header file.
I can see the possible merit in that but why:

avruser1523 wrote:

#include "header/registers.h" // Just a list of registers mapped to memory.

Why not:

#include <avr/io.h>

That has nothing to do with "Arduino". That is the set of headers that comes with AVR-LibC which is a pretty vital component of the compiler/toolchain distribution. Presumably your "registers.h" is a home-brew version sub-set? If it is did you remember to do the 0x20 offset thing on the registers in IN/OUT range?

 

Oh and why?

     USART_Transmit(0x1);

You weren't hoping this would show '1' at the other end? If so you will get more mileage with:

     USART_Transmit(0x31);

or the more usual way of writing that:

     USART_Transmit('1');

Note that '1' != 0x01 !!

Last Edited: Tue. Jan 18, 2022 - 03:14 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@clawson

 

I have actually copied that header file directly from here:

https://github.com/vancegroup-mi...

 

With some modification to include the `0x20` offset yes. It works just fine in other use cases.

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

avruser1523 wrote:
I have look at the schematic here: https://i.stack.imgur.com/Rm50J.jpg

That's not the official Arduino schematic - see: https://docs.arduino.cc/static/c1593a4c4960ff7b51d1083cb8e45812/schematics.pdf

 

You'll see that the LEDs are connected differently in the official schematic - so which board do you actually have?

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

9600 baud 11 bit character size = 0.001 seconds, can your eyes really see an LED flash for that long once a second? 

I think your issue is an unrealistic expectations of your vision system!

Rather then using an LED, use a printable ascii character and connect a pc to the USB com port and watch the character fly!

Jim

 

 

FF = PI > S.E.T

 

Last Edited: Tue. Jan 18, 2022 - 03:17 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Note that '1' != 0x01 !!

 

 

Of course. To see a `1` I goto use the ascii table. Here i'm just trying to blink an LED first.

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

avruser1523 wrote:
With some modification to include the `0x20` offset

So why not just use 

#include <avr/io.h>

as clawson suggested?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ki0bk wrote:
9600 baud 11 bit character size = 0.001 seconds

 

I think that might be my issue. Changing BUAD to:

 

#define BAUD 1

Makes a bit of a difference. Now the LED briefly turns OFF every second. So Tx port is inverted?

 

Also seems like the Tx builtin LED has nothing to do with the Tx port then as its blinking as before every second.

Last Edited: Tue. Jan 18, 2022 - 03:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avruser1523 wrote:
Here i'm just trying to blink an LED first.

So why use the UART?

 

You understand that sending 0x01 via the UART is still going to send a whole UART frame - it won't just set the line high or low.

 

As Jim suggests, you might just be able to make out a flicker on the LED - you certainly won't see a clear blink.

 

ki0bk wrote:
Rather then using an LED, use a printable ascii character and connect a pc to the USB com port and watch the character fly!

+1

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@awneil

 

I will probably start using that official header from now on.

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


avruser1523 wrote:
So Tx port is inverted?

No, Async comms idle high! 

 

Note idle time and stop bits are high!

 

Jim

 

FF = PI > S.E.T

 

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

I have actually copied that header file directly from here:

But that file IS the one in AVR-LibC. It's exactly the same content you will get if you simply use:

#include <avr/io.h>

HOWEVER io.h not only contains:

...
#  include <avr/iom3250p.h>
#elif defined (__AVR_ATmega3250PA__)
#  include <avr/iom3250pa.h>
#elif defined (__AVR_ATmega328P__)
#  include <avr/iom328p.h>
#elif (defined __AVR_ATmega328__)
#include <avr/iom328.h>
#elif defined (__AVR_ATmega329__)
#  include <avr/iom329.h>
...

but it also contains:

#include <avr/sfr_defs.h>

and:

#include <avr/portpins.h>

#include <avr/common.h>

#include <avr/version.h>

#if __AVR_ARCH__ >= 100
#  include <avr/xmega.h>
#endif

/* Include fuse.h after individual IO header files. */
#include <avr/fuse.h>

/* Include lock.h after individual IO header files. */
#include <avr/lock.h>

so you miss out on those others if you just include iom328p.h directly. Indeed iom328p.h even starts with:

#ifndef _AVR_IO_H_
#  error "Include <avr/io.h> instead of this file."
#endif

for this very reason.

 

Don't worry about io.h picking the right header for 328p. The fact is that when you build the command includes -mmcu=atmega328p. There is a table inside the compiler and it "knows" all the different AVRs and for "atmega32p" it then goes on and internally defines the pre-pro macro "__AVR_ATmega328P__" which is a unique symbol that leads to avr/io.h including the correct header (iom328p.h) for the device you are building.

 

All this has been thoughtfully constructed by the compiler/library developers to ensure it will always "do the right thing". I wouldn't try to "out think it" if I were you!!

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

avruser1523 wrote:
seems like the Tx builtin LED has nothing to do with the Tx port then as its blinking as before every second.

Did you miss #6 ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Take a look at the Serial Comms Tutorial linked in Tip #2 in my signature, below:

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@awneil

I have the Uno board. So what do you suggest the Builtin TX LED is for then? it for sure isn't the same as the Tx port.

I will also look at the Tutorial.

 

@

ki0bk wrote:
Note idle time and stop bits are high!

Thank your for clarifying it.

 

@clawson

I guess i'm trying to work as low level as I can, it just helps with learning. That default header file has a bunch of other headers included which I may not be familiar with yet.

So I'm trying to only use the stuff I have read about in the datasheet so far. Hence the `custom` header file.

Last Edited: Tue. Jan 18, 2022 - 03:31 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

BTW if you really want to use "home-brew" device headers then you are best off doing what Atmel and the compiler developers do and start with Atmel's XML definitions (ATDF) for their micros (which are all supplied with Studio 7, device packs and now MPLABX). All the iom328p.h and so on are (mostaly) auto-generated with scripts from the XML. With a bit of your own scripting (Python is a nice language for something like this as it can "do stuff" like XML) you can end up with something such as:

 

https://www.avrfreaks.net/forum/...

 

That is a Python script I wrote (and further developed through that thread) that reads and processes ATDF files but instead of generating defines for registers and bits just like "#define PORTB *((volatile uint8_t *)0x23)" (etc.) it effectively creates one huge struct to map the whole of the device's SFR map then allows you to cast this struct over the base address (usually 0x20) of the SFRs.

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


avruser1523 wrote:
I have the Uno board.

The question was whether it's a genuine one, or not - as those schematics are different.

 

On the genuine Arduino, you can see that the LEDs are driven by separate pins on the USB interface chip - not connected directly to the comms line.

 

See attachment 1.

 

This is exactly because, as Jim explained, you wouldn't be able to see anything (much) with the LEDs just connected to the comms lines - so the USB interface chip creates visible blinks.

 

 

ki0bk wrote:

Note idle time and stop bits are high!

 

Thank your for clarifying it.

 How was it unclear?  The datasheet clearly shows that Tx idles high.

 

See attachment 2.

 

(sorry, inserting images is currently broken).

 

 

EDIT

 

Insert images now that it's working again

 

 

Attachment(s): 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Wed. Jan 19, 2022 - 09:40 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
The question was whether it's a genuine one, or not

Yes a genuine board. I probably looked at the wrong schematic hematic then, thanks for the link.

And yes seems like this LED is related to the other AVR chip which only acts as the USB<->Serial converter.

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

@clawson Thanks for sharing the script.

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

I suspect that your baud calculation is not correct.  For the baud register values with 16MHz clock and 9600 baud, do:   9600 * 16  = 153,600

   Fclock / (baud*16)  =   16MHz / 153000 = 104.16      baud reg value =   (Fclk / (baud*16)) - 1  == 103

 

Use 103 directly as the value for  MYUBRR and see if you get something. 

 

Also try sending 0x55 continuously, instead of a single value once a second.  This number will put a square wave of frequency BAUD/2 on your TX output pin.   Check if the signal could be on the "RX" pin. Some Arduino clone makers might swap the TX and RX pins on the 8-pin header.

 

I recommend that people stop trying  to make end-runs around the Arduino IDE system.  The hardware works: the Arduino IDE works.  If you use them, then your application will work on these lowest levels.  Put your energy into making your application work better, more reliably, and easier; instead of trying to probe with what's going on on an AVR register level.   With Arduino, you can transfer your application or sketch to a completely different CPU with minimal study and learning curve.  However hard the AVR might be on a register level, the ARM and Espressif ESP CPUs are much harder on a register level.

Last Edited: Tue. Jan 18, 2022 - 06:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

/8/2 is /16

 

The equation is right.