UART/USB

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


Hi guys.

 

I have development kit EvB 5.1. I use USB to program my .hex code in MCU.

I use external voltage source.

 

MCU pins Rxd and Txd is connected to FT232RL.  Can i use FT232 to communication throught UART unit in MCU?

 

I write small program to use UART0 in my ATmega644p.

 

#include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdio.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <inttypes.h>

#include "MLCDFN.h"
#include "UARTcom.h"

volatile unsigned char receiveByte;

 

int main()
{

	iniMLCD();

	sei();

	InitUART0(9600,0,8,NONE,1,TRUE);

	_delay_us(100);

	while (1)
	{
		_delay_ms(1000);
		TransmitUART0('h');
	}
}
ISR(USART0_RX_vect)
{
	receiveByte = UDR0;

	printf_P(PSTR("PC"));
}

UART function:

 

void TransmitUART0(unsigned char Data)
{
	//Wait until the Transmitter is ready
	while (! (UCSR0A & (1 << UDRE0)) );

	UDR0 = Data;
}
void InitUART0(int baud, char Asynch2rychlost, char VelikostDat, char ParitaUdalost, char StopBits, char USARTPreruseni)
{
	uint16_t UBBRValue = lrint((  F_CPU / (16L * baud )) - 1);

	if(Asynch2rychlost==1) UCSR0A = (1 << U2X0); //setting the U2X bit to 1 for double speed asynchronous

	//Put the upper part of the baud number here (bits 8 to 11)
	UBRR0H = (unsigned char) (UBBRValue >> 8);

	//Put the remaining part of the baud number here
	UBRR0L = (unsigned char) UBBRValue;

	//Enable the receiver and transmitter
	UCSR0B = (1 << RXEN0) | (1 << TXEN0);

	//Enable preruseni
	if (USARTPreruseni) UCSR0B |= (1 << RXEN0);

	//Set 2 stop bits and data bit length is 8-bit
	if(StopBits == 2) UCSR0C = (1 << USBS0);

	if(ParitaUdalost == EVEN) UCSR0C |= (1 << UPM01); //Sets parity to EVEN
	if(ParitaUdalost == ODD) UCSR0C |= (3 << UPM00); //Alternative way to set parity to ODD

	//Velikost dat==0 format dat je 5
	if(VelikostDat == 6) UCSR0C |= (1 << UCSZ00); //6-bit data length
	if(VelikostDat == 7) UCSR0C |= (1 << UCSZ00); //7-bit data length
	if(VelikostDat == 8) UCSR0C |= (3 << UCSZ00); //8-bit data length
	if(VelikostDat == 9) UCSR0C |= (7 << UCSZ00); //9-bit data length
}

If i run this code, i can see blinking on my board LED diod indicating sendings data every second.

but if i look on COM port in my PC i see just :

 

 

ISR(USART0_RX_vect)
{
	receiveByte = UDR0;

	printf_P(PSTR("PC"));
}

I can send data from PC to MCU, other LED indicating receiving data, but interrupt method never is done.

 

Maybe its baud rate wrong? (9600).  I use F_CPU=18432000UL

 

uint16_t UBBRValue = lrint((  F_CPU / (16L * baud )) - 1);

 

 

Thank you for yours tips.

 

This topic has a solution.

New

Last Edited: Sun. Mar 15, 2020 - 07:34 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

AVR_Castieloo wrote:
Maybe its baud rate wrong? (9600).  I use F_CPU=18432000UL

Are you sure it's running on the external xtal?  How have you proven that?   Try to flash an LED one second on/off to test.

Most serial comms fail because the cpu is not running at the speed you think it is.

Also check that you have not left the clock/8 fuse set as that is the default, so your clock is 1/8 less then you think it is! To check set terminal to 1200 baud, does it work now?

 

Jim

 

 

Keys to wealth:

Invest for cash flow, not capital gains!

Wealth is attracted, not chased! 

Income is proportional to how many you serve!

If you want something you've never had...

...you must be willing to do something you've never done!

Lets go Brandon!

Last Edited: Fri. Mar 6, 2020 - 09:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Experience here would suggest that the thing most likely to be wrong is your assumption that the AVR is clocked at 18.432MHz

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

Another thing to check:

FT232                AVR

TXD -------------> RXD

RXD <------------  TXD

GND <---------->  GND

 

Jim

 

 

Keys to wealth:

Invest for cash flow, not capital gains!

Wealth is attracted, not chased! 

Income is proportional to how many you serve!

If you want something you've never had...

...you must be willing to do something you've never done!

Lets go Brandon!

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

Do not set the U2X to 1 for double speed asynchronous.  Keep the UART at single speed asynch.    To test if this is causing the problem, change the baud rate of the PC terminal program to 19200 (try 4800 as well).  If the chars are clear, then turn off double speed asynchronous mode.   And change FCPU to 1843200.   This is a standard baud rate crystal.   Do you have this crystal value on your development board, or is this just one more "magic number" that was in the code that you got from someone who passed this course last term?

Last Edited: Fri. Mar 6, 2020 - 09:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

UBRR = (20 000 000 / (16 * 9600)) - 1 = 129

 

Fbr = (20 000 000 / (16 * (129+1)) = 9615 Bd

 

I set F_CPU 20 MHz but still getting ??? on PC.

 

For F_CPU 10 000 000

with this code

int main()
{
	DDRB |= 1 << PINB0;
	while (1)
	{
		
		PORTB ^= 1 << PINB0;
		_delay_ms(1000);
		
		
	}
}

Led blinks every second.

So prescaler is turn off right?

New

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

Google suggests that a EvB 5.1 with ATmega644p has a 16MHz crystal, so try with F_CPU=16000000UL.

Letting the smoke out since 1978

 

 

 

 

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

Changing F_CPU number does nothing to the actual frequency. YOU need to set that to match what the real MCU frequency is. If it is using an external 16MHz crystal (really running on that crystal, not the internal oscillator), then use F_CPU 16000000UL

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

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

Thank you guys.

 

Its running on external Oscilator, my fault.

 

I have one question about data i want send. If i wanna send 14 bits int number, should i change sending data to 7 bit?

 

After 2 data sends i will have full number on PC .

 

It´s the most elegant way?

 

New

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

It´s the most elegant way?

 

I do not think so.

A common way is to send the high byte, then the lower one (or vice versa).

On the receive side you put them together.

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

I have one question about data i want send. If i wanna send 14 bits int number, should i change sending data to 7 bit?

 

No, you want to convert your number to ASCII digits & send those (if you want to view them).

 

ex:     the base 10 (decimal) number 1598 is  011000111110  in base 2 (binary)

 

you convert that binary number to 1's ten's 100's thousands...this is the "hardest" part

and is often done by repeated subtraction (starting with the biggest, like 10000's or 1000's) or other clever means

1598 -1000 leaves 598

598-100-100-100-100-100 leaves 98

90-10-10-10-10...you get the idea

-------------------------------------------

1 thousand  0000 0001

5 hundreds  0000 0101

9 tens         0000 1001

8 ones        0000 1000

 

convert each of these digits to ASCII (for numbers this means just add 0x30)

 

"1"  character  is sent to terminal as single byte 00110001

"5"  character  is sent to terminal as single byte 00110101

"9"  character  is sent to terminal as single byte 00111001

"8"  character  is sent to terminal as single byte 00111000    on the screen, you then see  "1598"  !!!

 

If you don't want to SEE it directly on a terminal none of this is needed  (but you often DO want to see it, makes life simple) ...you can send as 16 bits (2 8 bit bytes) & do what you wish with them in your program.

But sending that directly to the terminal will show garbage.  the terminal REQUIRES ASCII (well, some are starting to use things like unicode, which is being ignored here).

 

 

 

 

 

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Sat. Mar 7, 2020 - 06:07 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

AVR_Castieloo wrote:
If i wanna send 14 bits int number, should i change sending data to 7 bit?

It's still two bytes either way, but if your sending it to a PC, it will not be viewable when sent as binary, so convert it to ascii, or better into ascii Comma Separated Values (CSV)

which can be read by any spread sheet directly or easily parsed by a program on the PC side.

 

Use itoa() or printf() to convert your integer into ascii numbers.

 

Jim

 

 

Keys to wealth:

Invest for cash flow, not capital gains!

Wealth is attracted, not chased! 

Income is proportional to how many you serve!

If you want something you've never had...

...you must be willing to do something you've never done!

Lets go Brandon!

Last Edited: Mon. Mar 9, 2020 - 02:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ki0bk wrote:
if your sending it to a PC, it will not be viewable when sent as binary

That is, it won't be viewable without some specific PC app which can interpret the binary and display it to you in a human-readable form.

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...
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

You convert & send it in ASCII , then any terminal program or various serial monitor apps will show it, without any effort on your part.  This also makes debugging your work easier, since at least half the link (the terminal) is known working.  If you write both halves & things don't work, it can be a pain to figure out which piece is the problem (or sometimes each has a differing flaw, giving even stranger headaches).

 

If you want to send using a different format, then you must find a compatible app, or write your own (that's why ascii is extremely common).  However, ASCII is much less efficient...so if you are transmitting gigabytes info around a serial line, you probably will avoid ASCII.

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

Definitely a frequently-recurring issue!

 

https://www.avrfreaks.net/commen...

 

 

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...