[TUT] [SOFT] Using the USART - Serial communications

Go To Last Post
490 posts / 0 new

Pages

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

Hi all

The tutorial is very useful and will give me the start i need.
I have copied the code directly and loaded onto a Mega8515 (in an STK500) from AVRStudio 4.
The problem i have is that when i connect my serial port to the circuit and send data from hyper terminal i get nothing back.
I have tried a whole host of settings for the COM port nothing seems to return any data. I have even rebuilt the circuit.
I checked that data is being sent by setting the internal echo.
Any help would be great.

thanks in advance.

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

Which code you have load ?

Pls. Check MHz (Fuse settings)for your Chip & BAUDRATE also...

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

Thanks for getting back to me Dixit.

I have solved the problem.

I had the fuse set to ext clock.

I have now changed the STK500 clock to match the frequency of the target device and it seems to have rectified the problem.

thanks again.

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

I want to send some AT Commands to mi mobile using mi ATMEGA32.

The parameters of the protocol:
19200 bauds
8 Bits

As I've read in datasheet:

This is what I've choosen:

Now, this is my code:

// Frequency needed by the delay function.
// The chip is factory set to run on internal
// oscillator at 4 MHz so the value is 4000000UL
#define F_CPU 4000000UL
#define USART_BAUDRATE 19200
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

#include 
#include 



int main(void)
{
	UCSRB |= (1 << RXEN) | (1 << TXEN); //Habilito el circuito de transmisión y recepción  
	UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);//8 bits

	UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register  
	UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
	
	DDRA = 0xFF; // PA0-PA4 output

	while (1){
	
	_delay_ms(5000); // esperamos 5 segundos
	PORTA = 0xFF;
	while ((UCSRA & (1 << UDRE)) == 0) {};
	UDR = 'A';
	while ((UCSRA & (1 << UDRE)) == 0) {};
	UDR = 'T';
	while ((UCSRA & (1 << UDRE)) == 0) {};
	UDR = '^';
	while ((UCSRA & (1 << UDRE)) == 0) {};
	UDR = 'S';
	while ((UCSRA & (1 << UDRE)) == 0) {};
	UDR = 'M';
	while ((UCSRA & (1 << UDRE)) == 0) {};
	UDR = 'S';
	while ((UCSRA & (1 << UDRE)) == 0) {};
	UDR = 'O';
	PORTA = 0x00;}

	
	return 0;
}

The problem is that, my mobile recives some like this:

when should recive this A^TSMSO.

Other problem comes with delay, I've been choosen 15000ms, but this delay less than 1 sec.

Any idea???? Thanks.

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

Hey,nice tutorial,I was just implementing it. When I just echoed a single letter like UDR=97,it worked fine. But when I try the echo program i.e echoing the received byte back to the terminal i see nothing on the terminal. This is my code,clock is 12Mhz,Baud rate 9600 bps

//Without interrupts
#include 
typedef unsigned char U8bit;

int main (void)
{
   U8bit c;
  UCSRB =0x18 ;   // Turn on the transmission and reception circuitry
   UCSRC =0x86 ; // Use 8-bit character sizes

   UBRRL = 0x4D; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
   UBRRH = 0x00; // Load upper 8-bits of the baud rate value into the high byte of the UBRR register

   for (;;) // Loop forever
   {
      while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been recieved and is ready to be read from UDR
      c = UDR; // Fetch the recieved byte value into the variable "ByteReceived"
	  while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it
      UDR = c; // Echo back the received byte back to the computer
   }   
} 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

does anyone have any code that can show me how to echo through an ATmega8 (or possibly modifications to the code at the end of the tutorial)? the loopback on my max232 works perfectly and i do get responses when going thrugh the mega but they're just strange ascii-style characters. i assume this is a timing problem (from what i've read) but can't seem to narrow down what i need...

thanks

edit - small victory but new problem. data is echoing successfully through mega but i have to set my terminal baud to 2400 when i've got 9600 declared in my code... any stabs at why?

thanks

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

Quote:

2400 when i've got 9600 declared in my code... any stabs at why?

If it had been 1/8th it would almost be because of the CKDIV8 fuse. But your results suggests the AVR is running 1/4 of the speed you think it is. So what speed do you think it is and what are your CKSEL fuse settings?

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

clawson -

*hangs head in shame* i got so caught up in double-checking the math that i forgot to actually SET the fuse bits. as soon as i saw "CKSEL" in your post, the light bulb came on. haha - sometimes i dont know what's worse - a massive, general system failure or a small oversight...

indeed, the FAQ#3 in your signature is proving to be most true.

thanks for the help.

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

hey..as mentioned earlier when im only transmitting a single character from my MCU it works.so im assuming there is no CLOCK problem,its just that my echo program doesnt work.

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

Anyone can help me??

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

magarcan wrote:
Anyone can help me??

OK, fix this:

// The chip is factory set to run on internal 
// oscillator at 4 MHz so the value is 4000000UL 

A piece of quartz will only cost you about $0.50

Failing that calibrate OSCCAL

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

Price is not the problem. In my town is impossible to buy it, so I hace to buy througth Internet.

How can I calibrate OSCCAL??

Thank you very, very much.

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

Quote:

How can I calibrate OSCCAL??

Well start by searching your datasheet for that term and see what it tells you about factory calibration and the values in the signature row that you can pick up and later program into OSCCAL to make the first step towards more accuracy.

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

Hello,

First off, thanks for this wonderful tutorial. Here is the problem I'm having. I have an ADC pin reading a value and converting it to an 8 bit number. It is going in the variable ADCH I'm assuming. I'm then taking this value and using it for 8 bit PWM modulation, OCR2 = ADHC. That part of the program is working great. However, I have in my code

UDR = ADCH;

The output onto HyperTerminal is extremely precise, yet inaccurate. When the sensor seems to be reading a certain value (as I can tell from PWM output of an LED), it always outputs the same symbols to HyperTerminal, however it doesn't output a number between 1 and 255 which is what I want it to do. So I think its working correctly, I just don't know how to tell it to output an actual number instead of these ascii symbols? Anyone know? Thanks

-apc

OCR2 = ADCH; 
		if ( (UCSRA & (1 << UDRE))) // UDRE slot== 1 when the buffer is empty
		{	
			UDR = ADCH;
			
		}

Also,

I saw a great post by Clawson on page 5 I believe of this tutorial talking about how to print out characters. Just saying thanks for that post. I plan on using it for doing something like "The value of the sensor is X" in the future

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

You're trying to print out the ASCII values associated with each ADC reading. Sending "34" by loading 34 into the UDR will actually send the character associated with decimal value 34 from the ASCII table (see www.asciitable.com). You need to use the "itoa" function in the avr-libc library to convert your decimal value into it's ASCII string equivelent, and then load each of those string bytes into the UDR register in turn.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

Thanks Dean, appreciate it.

You wouldn't happen to have any good references, i.e. as good as your tutorials, would you?

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

Quote:
You wouldn't happen to have any good references, i.e. as good as your tutorials, would you?

No need for a tutorial, just use itoa().

Regards,
Steve A.

The Board helps those that help themselves.

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

Specifically:

The itoa function (Integer to ASCII) takes in three parameters; the input integer value, the output buffer and the radix (the number base - 16 for HEX and 10 for decimal). All you need to do is create a buffer large enough to hold the largest number of bytes the function will produce, plus one for the terminator.

Since you're loading only a 8-bit register into it, you've got an input range of 0 to 255. That means you'll need a buffer that can hold 4 bytes - three for the digits (up to 999) and one for the null terminator (so that you know where the end of the string is when you use the standard C string functions).

char buffer[4];

itoa(ADCH, buffer, 10); // Convert ADCH to an ASCII string, in decimal

char* bufferPos = &buffer[0]; // Make a pointer to our string
while (*bufferPos != 0x00) // Loop until null terminator found
{
    while(!(UCSRA & (1 << UDRE))); // Wait until buffer empty
    UDR = *bufferPos; // Load next string byte into the USART data register

    bufferPos++; // Advance pointer to next string byte
}

That's not the best way of doing things (since the code blocks while the string is being sent) -- a better way would be to load the converted string bytes into a ring buffer, so that you can send them in order later as the USART becomes ready for each new byte. Still, that'll get you started.

- Dean :twisted:

}

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

hello everybody, im working in serial transmision using a keyboard 4x4, i have this code and i have proved it in proteus but it doesnt work, it compiles perfectly in avrstudio 4. I still dont know what the problem is, if someone can help me to figure out. the keyboard routine works perfectly using a LCD, but it doesnt work using serial transmision...What is happening?.....im working with atmega 16
[code]
#include
#include

#define USART_BAUDRATE 2400
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
#define F_CPU 1000000
#define teclado_PORT_OUT PORTB
#define teclado_PORT_IN PINB
#include

void USART_Init( unsigned int baud )
{
/* Set baud rate */
UBRRH = (unsigned char)(baud>>8 );
UBRRL = (unsigned char)baud;
/* Enable receiver and transmitter */
UCSRB = (1<<RXEN)|(1<<TXEN);
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

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

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

int main(void)
{
USART_Init(BAUD_PRESCALE);
unsigned char upperNibble, codigotecla, Tecla, i;
while(1)
{
upperNibble = 0xff;

for(i=0; i<4; i++)
{
_delay_ms(1);
teclado_PORT_OUT = ~(0x01 << i);
_delay_ms(1); //delay for port o/p settling
upperNibble = teclado_PORT_IN | 0x0f;

if (upperNibble != 0xff)
{
_delay_ms(20); //key debouncing delay
upperNibble = teclado_PORT_IN | 0x0f;
if(upperNibble == 0xff) goto OUT;

codigotecla = (upperNibble & 0xf0) | (0x0f & ~(0x01 << i));

while (upperNibble != 0xff)
upperNibble = teclado_PORT_IN | 0x0f;

_delay_ms(20); //key debouncing delay

switch (codigotecla)
{
case (0xee): Tecla = '0';
break;
case (0xed): Tecla = '1';
break;
case (0xeb): Tecla = '2';
break;
case (0xe7): Tecla = '3';
break;
case (0xde): Tecla = '4';
break;
case (0xdd): Tecla = '5';
break;
case (0xdb): Tecla = '6';
break;
case (0xd7): Tecla = '7';
break;
case (0xbe): Tecla = '8';
break;
case (0xbd): Tecla = '9';
break;
case (0xbb): Tecla = 'A';
break;
case (0xb7): Tecla = 'B';
break;
case (0x7e): Tecla = 'C';
break;
case (0x7d): Tecla = 'D';
break;
case (0x7b): Tecla = 'E';
break;
case (0x77): Tecla = 'F';
break;
default : Tecla = 'X';
}
USART_Transmit(Tecla);
OUT:;
}
}
}
}

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

hi there, i copied the program to make the eco with the PC, i had to do some changes 'cause i was using the MEGA168, and when i compile the file , show me the next error:

avr-gcc -mmcu=atmega128 -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT first.o -MF dep/first.o.d -c ../first.c
../first.c: In function 'main':
../first.c:27: error: 'ReceivedByte' undeclared (first use in this function)
../first.c:27: error: (Each undeclared identifier is reported only once
../first.c:27: error: for each function it appears in.)
make: *** [first.o] Error 1
Build failed with 3 errors and 0 warnings...

someone now what it means, i have to declare something ???

Atte.
Mánuel.

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

Plop, i get the problem seeing another tutorial about interrupts XD!!! I just put below int main ... char ReceivedByte, but i don't get why wasn't working???
Atte.
Mánuel.

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

Hello everyone,

I am able to send characters from AVR to Terminal but I have a problem sending it from PC to AVR when I try to echo the character. I don't know what's going wrong. Please can someone help me.


#include 


void USART_Init(unsigned int baudrate) // UBRR Value not baudrate
{
    // Set baud rate
    UBRR0H = (unsigned char)(baudrate>>8);
    UBRR0L = (unsigned char)baudrate;

   
    // Enable receiver and transmitter
    UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(0<<RXCIE0)|(0<<UDRIE0);

    
}


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

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

int main(void)
{    
	char c;

    
    
	USART_Init(51);             // Baud rate = 9600bps, 8MHZ, u2x=0

    for (;;)            // Main loop
    {
		c=Usart_Rx();
		Usart_Tx(c);
    } //End Main loop
	
	return 0; 
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Also I am using ATmega1281 AVR to communicate with the PC. So the register configurations are done accordingly.

Thanks in advance.

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

I have an oscillator that is 7.128Mhz. I am using an AtMega8. The table of baud rates and UBRR settings does not have an entry for this frequency. However, if I use the formula in the ATMega8 data sheet for determining error calculation:

Quote:

% Error = [(Baud Rate that matches most closely/Baud Rate) - 1] * 100

For 7.128Mz, closest matching baud rate is 9684.78 - I found this value on this site.

Plugging the values into the error calculation formula, I get a percentage error of approx 0.88%. It seems like that would be within the 2 -3% margin of error noted in this thread - given that my purpose it to experiment with Dean's tutorial.

Am I doing this calculation correctly?

Russ

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

I agree with your result. The calculation according to the datasheet is:

UBRR = ((fosc/(16 * baud)) - 1 ; for U2X=0
UBRR = ((fosc/(8 * baud)) - 1 ; for U2X=1

I make this:

(7128000/(16 * 9600)) - 1
(7180000/153600) - 1
45.40625 (U2X=0)

(7128000/(8 * 9600)) - 1
(7180000/76800) - 1
91.8125 (U2X=1)

So the closest you get is UBRR=45 (and the error comes from .40625) or UBRR=92 (and error comes from 0.1875)

Now work those values backwards through:

baud = fosc/(16or8 * (UBRR + 1))

baud = 7128000/(16 * (45 + 1))
or
baud = 7128000/(8 * (92 + 1))

baud = 7128000/736
baud = 7128000/744

baud = 9684.78 ; U2X=0
baud = 9580.65 ; U2X=1

So your 9684.78 calculated result is correct. To work out the error percentage the datasheet also gives the formula:

Err% = (close_baud/desired_baud - 1) * 100%

So:

Err% = (9685/9600 - 1) * 100% = 0.89% ; U2X=0
Err% = (9581/9600 - 1) * 100% = -0.20% ; U2X=1

Cliff

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

To follow up, I am not sure that I follow the error calculation discussed by microcarl above:

microcarl wrote:
The only thing I would like to add is that, unless the microcontroller XTAL1, XTAL2 frequency is one of those "Magic Numbers", the final BaudValue will be a mixed number and be rounded down as, the final value of BaudValue must be an integer - the remainder will be lost.

If an XTAL value is used that produces a value of say, 48.1, the error produced by the trunkation of the fractional part, I.E. 0.1, will produce a Baud rate error just slightly greater then 2%. This error may well work without USART timing issues.

But, an XTAL frequency producing a final BaudValue of say, 48.2 or greater, will produce a BAUD rate timing error of more then 4%, which is outside of the +/-3% error margin specified by Atmel.


If 48.1 is rounded down to 48, doesn't that result in an % error of 0.2% rather than 2%? Similarly, wouldn't 48.2 -> 48 yield a 0.4% error, rather than 4%?

Russ

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

Yes, it would be 0.2%, not 2%.

Regards,
Steve A.

The Board helps those that help themselves.

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

I have followed this thread from page 1. It's been a great learning experience to see the potential pitfalls before I actually started to try using the USART feature of my AVR. I do have a problem that I haven't figured out yet. Maybe someone might see something that I am not seeing. Transmitting one character results in a different character being received. The received character does not change unless the transmitted character is changed. I'm sure this has to be a timing issue of some sort.

My board uses a 16.000MHz crystal. This AVR has no internal oscillator. Pages 36-44 in the ATMega128 reference manual describe clock divisors and such, but none are programmed in my case. The JTAG connector is removed after programming so as not to interfere with the USART operation.

All I am attempting to do is get my AVR to communicate like a loopback connector to HyperTerminal in Windows. I am using an ATMega128 (MAVRIC IIb board) with an Atmel JTAGICE MKII programmer. The code used is based on the examples provided in this thread. I believe the registers are correctly adjusted for the ATMega128.

There is a DB9 connector attached to the AVR as follows:
DB9 Pinout
Pin 2 (RD) to TX0 of AVR
Pin 3 (TD) to RX0 of AVR
Pins 4-6 (DTR-DSR)
Pin 5 (GND) to GND of AVR
Pins 7-8 (RTS-CTS)

HyperTerminal and the USB COM Port of my PC are configured to 38400 baud, 8N1 (8 bits / No Parity / 1 Stop bit).

When pin 2 and 3 of the USB COM Port are connected together in a loop-back fashion, the characters typed do echo back.

From HyperTerminal, in a full loopback form using the AVR as the loopback:
When 'f' is sent, '6' is looped back.

Then if I program the AVR as transmit only to HyperTerminal:
When '0' (zero) is sent, the omega character is returned.

The code shown has the receive section removed for now until I know I can reliably transmit a character from the AVR to HyperTerminal.

// Includes to make the code work
#include 

// Defines / Declarations
#define F_CPU 16000000UL
#define USART_BAUDRATE 38400UL
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) 

int main (void)
{
//	char ReceivedByte; 

	// Turn on the transmission and reception
	UCSR0B |= (1 << RXEN0) | (1 << TXEN0); 
	UCSR0C |= (1 << UCSZ00) | (1 << UCSZ01); 

	UBRR0L = BAUD_PRESCALE; 
	UBRR0H = (BAUD_PRESCALE >> 8); 

	for (;;) // Loop forever
	{
//		while ((UCSR0A & (1 << RXC0)) == 0) 
//		{
//		}; 
//		ReceivedByte = UDR0; 

		while ((UCSR0A & (1 << UDRE0)) == 0) 
		{		
		}; 
		
		UDR0 = '0'; // This is hard coded for now
	}    
} 

This should be very straight-forward. Any ideas on what I am overlooking?

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

Although it is not necessary (usually), if you are trying to initialize something like a USART, you should always do:

   // Turn on the transmission and reception
   UCSR0B = (1 << RXEN0) | (1 << TXEN0);
   UCSR0C = (1 << UCSZ00) | (1 << UCSZ01);

instead of your

   // Turn on the transmission and reception
   UCSR0B |= (1 << RXEN0) | (1 << TXEN0);
   UCSR0C |= (1 << UCSZ00) | (1 << UCSZ01);

My way guarantees that the "unset" bits are all 0. Once you have done the first initialization, it makes more sense to do changes your way.

I also would do

      UDR0 = 'U'; // This is hard coded for now

If you happen to have a scope, then this generates a square wave with the width of a half-wave equal to your baud rate.

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

You have already done some of the things below, but I will give you the standard "how to debug a UART" lecture:

1 - Check to be sure you have the right clock running. Run a simple "blink the LED" program where you have an expected delay - does the LED blink at the rate that you expect? If not, check the crystal and Clock fuses to be sure they are set correctly. This is the most common failure!

1.5: If you are running on the internal clock, you will have serious baud rate problems. The internal oscillator has a 10% accuracy (meaning it can be off by as much as 10%), while RS-232 must be under 2%. Not that the baud rate des not matter - if the internal oscillator is off, it is off and a slower baud rate won't help.

At anything over 38400 baud, you should use a crystal with a "magic" frequency (14.7456 MHZ, ...) that is evenly divisible by 2 to your baud rate. You cannot run 57600 baud with a 16 MHz crystal, at least not reliably.

2 - Check your output connections. Run a simple UART output program (no interrupts!) that sets up 8-bits, no parity, 1 stop bit, and sends a constant string of "U"s. A string of ASCII "U" will give you a square wave output with the bit width equal to your baud rate. Check the square wave with a scope - is it right? If you have an RS-232 converter, check both the inputs and outputs of the converter. If you can tie the output to a terminal emulator and you see the string of U's coming out, you're good.

3 - Check your input connections. Send a string of characters to the processor and run a simple program that simply toggles an LED when a character is received. Again, check the signal at the input to the processor - is it there? After that works, do another simple program that simply echoes characters back.

By the time you are through this procedure, you have gotten rid of 95% of the teething problems with UARTs.

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

Thanks Stu.

I'll give my stuff the 'once' over as per your advice and let you know how I make out. It's gotta be something exceedingly simple (yet a major headache)!

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

I'm still checking things out. The only thing noticeable so far is that 'U' does transmit out successfully. It is however the only character to do this.

Still on it ... lol

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

Here's a quick sampling of what I send, and what comes back.

Key Dec Hex Binary
Send: a 97 61h 0110 0001
Retn: X 88 58h 0101 1000

Send: b 98 62h 0110 0010
Retn: l 108 6Ch 0110 1100

Send: c 99 63h 0110 0011
Retn: , 44 2Ch 0010 1100

Send: d 100 64h 0110 0100
Retn: v 118 76h 0111 0110

Send: e 101 65h 0110 0101
Retn: Y 121 79h 0111 1001

Send: U 85 55h 0101 0101
Retn: U 85 55h 0101 0101

The BBS interface has stripped the tabs in these columns, but the information is in the correct order.

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

I wrote a quick program to send a character from UART0 back to UART0. Tx and Rx are connected together. This works. The same works for UART1. I know this because the receiving routine puts the character on my LCD screen and it matches what was sent by the transmitting routine.

Things are pointing to a definite communication issue between the AVR and the computer on the software end.

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

I've tried many code variations, all come up with the same results. I even adapted a used laptop to perform as a logic analyzer, nothing seemed to be wrong - at least on the AVR side of the circuit anyway.

I finally resorted to connecting my circuit to another PC with a built-in COM port, everything works as intended, and in Windows Vista to boot! All the problems are pointing to the "Generic" USB<->Serial converter I was using.

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

hey, I've experimented a bit with my USART transmission on a Atmega168 , everything is working fine if i just catch a character and then echo it back to the terminal, so the Tx/Rx works fine.
The problem is when i want to send something else like my own string or a different char.

char c='1';
if (UCSR0A & 0x80) //verify incoming data
 {      while(!(UCSR0A & (1<<UDR0))){};
	UDR0=c;
	while (!(UCSR0A & (1<<TXC0))) {};

	UCSR0A=UCSR0A|(1<<TXC0);
 }

For example if i try to send the char '1' after i recieve a random char, I get "´ÿ"

Any ideas why this happens?

Sry guys, found out were the problem was, didn't set the baud correctly , as it seems my ext osc. wasn't at 4Mhz but at 6Mhz.
Tho very odd that using it for direct transmitions worked.

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

I picked up a Radio Shack 261-3297 USB-Serial converter. This works beautifully. Funny thing is, it uses the same "Prolific" driver as my last unit. Except this one works. ;-)

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

Hi can anyone help me with some questions?

Quote:
If the system clock cannot be precisely divided down to a "magic" frequency for perfect communications, it will have a percentage error (where a byte fails to be read or written inside designated time frame). System clocks for perfect USART communications should be multiples of 1.8432MHz which when used will give a 0.00% error.

How do you acheive this multiple of 1.8432MHz frequency? Do you need to use an external crystal oscillator, or do you just set a register in the AVR somewhere? If you need a crystal oscillator, then where and how do you connect it?

Also, if the baud rates of two devices communicating via usart must be the same, then when connecting with the rs232 port of a computer, what is the baud rate of the computer, in order for me to match that of the avr?

Thanks alot

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

Quote:

Do you need to use an external crystal oscillator, or do you just set a register in the AVR somewhere? If you need a crystal oscillator, then where and how do you connect it?

It's all explained in the datasheet - there are various clock options - a common one is a metal canned crystal and two capacitors connected to the XTAL1 and XTAL2 pins of the AVR.

Another possibility is to use the inaccurate internal oscillator but to use an external, accurate timing reference to calibrate it (often a 32.768kHz crystal clocking timer2) - the code then adjust OSCCAL and can, for example derate an 8MHz internal oscillator back to a UART friendly 7.3728MHz UART friendly speed (like 1.8432MHz it too is a multiple of 300Hz)

With one of these magic crystals you can pick any common baud rate (2400, 9600, 38400, 57600, 115,200, etc) it doesn't really matter which you choose as long as both the AVR and the PC use the same. Though obviously if you have lot of data to shift in a short time (high "bandwidth") then a faster speed made suit your purposes better. So when using magic crystals you might as well make it 115,200

Cliff

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

[quote="clawson
it doesn't really matter which you choose as long as both the AVR and the PC use the same.

Thanks, I think I can hadle it now, but what about the PC baud rate? If they must match, then how can I configure or at least find out what baud rate the PC is using in order for me to match it with the avr?

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

On the PC end you are going to use a terminal program. It used to be the case that Windows came with an awful program called Hyperterminal so if you have XP or previous Windows I guess the temptation will be to use that and under connection properties you get to set details such as baud rate, parity, stop bits and flow control (make sure hardware flow control is OFF!).

Since Vista M$ (presumably because of anti-competitve business rulings?) have not included a terminal program as a matter of course so you now have a free choice to pick any of the good ones like Brays, RealTerm, TeraTerm, etc all of which have their own serial port setting dialogs where you can specify baud,bits,parity etc. Generally always use 8 data bits and no parity and as I said above you MUST ensure that "hardware flow control" is switched off (because the (simple) AVR end won't be doing it)

The following threads give various suggestions of terminal software to use:

http://www.avrfreaks.net/index.p...
http://www.avrfreaks.net/index.p...
http://www.avrfreaks.net/index.p...

Cliff

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

Thanks alot, Im going to use a ftdi device now, which uses a VCP, so I can interface with USB instead of directly with RS232. I think the configuration is done on the actual ftdi device.

How can I send a uint16_t variable via USART when it is configured to send 8bit bytes? I guess I need to split it into 2 uint8_t variables and send them seperately, but how can I do this?

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

Quote:

How can I send a uint16_t variable via USART when it is configured to send 8bit bytes? I guess I need to split it into 2 uint8_t variables and send them seperately, but how can I do this?

UART_send(var16 & 0xFF); // low byte
UART_send(var16 >> 8); // high byte

or

union {
 uint16_t word;
 uint8_t bytes[2];
} both;
both.word = var16;
UART_send(both.bytes[0]);
UART_send(both.bytes[1]);
//or (if other endian)
UART_send(both.bytes[1]);
UART_send(both.bytes[0]);

or

uint8_t *byte_ptr = (uint8_t *)&var16;
UART_send(byte_ptr++);
UART_send(byte_ptr);
// or (if other endian)
UART_send(++byte_ptr);
UART_send(--byte_ptr);

Take your pick - that &/>> solution does not care about how the var16 is held in memory (endianness) so is usually the chosen solution.

Of course the other way is:

itoa(var16, buffer, 10);
for (i=0; i

Sure it sends more that 2 bytes but has the advantage of being human readable so is probably easier to debug.

Cliff

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

Thanks thats a great help, I'll probably go with the first option

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

Thanks for such a nice post. Good for begginer like me.
I never used hyper terminal before so i dont have much idea how that works.I tried use it but nothing happens but when i used Bray's terminal code works fine. this could be something stupid but i dont have ant idea. :idea: .Any suggestion please..

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

hello,
I need ur help in my college avr project, I want to communicate with atmega32 via serial port such that the uc will control a stepper motor depending on the packet it receives via serial port.the packet contain 1.preamble[64bit], 2.identity[16bit], 3. download PDU, 4. end PDU .
if it receives FF [hex] as identity the ucontroller must burn the new data received in the download packet.
if it receives 01 [hex] as identity the uc must rotate the motor in clockwise direction.
if it receives 02 [hex] as identity the uc must rotate the motor in anticlockwise direction.
-------
I TRIED to program the bootloader,but after the burning, the hardware is not detecting the atmega uc. i don't know c programming well.So I want ur help to do the project.i want the c program(plz write it for me),makefile,hardware schematic, want to know which software to use for the communication (hyper terminal is not working in my pc) .i am new in uc programming .plz, reply as soon as possible.
--- PARTHA CHOWDHURY [ urpal.partha@gmail.com ]

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

Quote:
I need ur help in my college avr project

Quote:
i want the c program(plz write it for me),makefile,hardware schematic

It seems more like you want someone to do your project for you.

You have hijacked someone else's thread, posted in the wrong forum, and asked for help in cheating in order to get your degree. Expect no help here.

Regards,
Steve A.

The Board helps those that help themselves.

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

I expected these type of response. its true i am asking for a lot, but believe me i have no choice. btw, i am not cheating, i will happily mention names with proper credit in my report,i have already done that as I have used Sajid Choudhury's [http://sajiduc.blogspot.com/2008...
] hardware to program my chip.but my atmega16 chip got locked.bought a new atmega32.
i used another programmer & code- 'http://www.captain.at/electronic...' -- but can't find a way to communicate with the chip, ponyprog didn't detect the hardware,hyper terminal not working, can't reach the author. as I don't have much time left & can't spend more money on new hardware/chip, I am asking for straight fwd solution.the info on the last post is a part of my project, not complete in itself. i never run after marks. i am asking for complete help to keep my promise to me & my teacher that i will demonstrate the hardware before leaving college.
i am trying to do this part of my project for 2 months. but failed many times. i want someone to write the program bcz i don't know the syntax & c program ebook download failed thrice today ,from rapidshare. its obvious that i have to understand everything before including it in my project.
still u think i didn't help myself?

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

Let's see, you have someone design it for you and provide you with the schematic, program it for you, and instruct you how to use it. About the only thing left for you to do is put it together. So unless you are going for a degree in electronic equipment assembly, I would call that cheating.

Quote:
i am trying to do this part of my project for 2 months. but failed many times.

Then perhaps you should be looking for a different career.

Regards,
Steve A.

The Board helps those that help themselves.

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

partha88 wrote:
i want the c program(plz write it for me),makefile,hardware schematic, want to know which software to use for the communication.

Put your pockets full of money (>10k$) and hire a developer.

Peter

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

say whatever u guys want to say.
in my present satate, I rebuild the hardware and performing communication successfully via serial port. now I want to change the communication algorithm, I don't know the programming well, so I need a good book on microcontroller UART communication programming in C. atleaset this much help u can do.
any link to ebook of microcontroller c programming will help a lot. i have downloaded 2 ebooks but they r not useful.

Pages

Topic locked