Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] [ATMEGA8] Very Simple USART with Atmega168 - Error

Status
Not open for further replies.

gonewiththewind1312

Newbie level 4
Newbie level 4
Joined
Nov 27, 2012
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,335
Hello Everyone

I've read some tutorial about Atmega8 USART.
I tried to write a simple program, which send a character 'a' to serial port.
I used Realterm to connect to MicroController, but received character was not direct (wrong text).
(I also tried to use Hyper Terminal, but sometime text is displayed in screen (wrong text), sometime nothing) :cry:
Realterm Text: https://i1275.photobucket.com/albums/y446/gonewiththewind1312/realtearm-config.jpg
(View in ascii mode)

Thank in advanced for anyone who help me to solve this problem.
Or, Any one can give me your code for this program (Send a character to serial port), and how can you run/test your program.

* Is there any error about character encoding ??

PHP:
#include <avr/io.h>
#include <util/delay.h>
#include <compat/twi.h>
#include <avr/interrupt.h>

#define FOSC    16000000UL
#define F_CPU   16000000
#define BAUD 9600
#define UBRR FOSC/16/BAUD-1

/* Init USART */
void init_USART0(unsigned int ubrr){
    UBRR0H = (unsigned char) (ubrr>>8);
	UBRR0L = (unsigned char) ubrr;
    UCSR0C = (3<<UCSZ00); // 8-bit data. 1 stop bit
    UCSR0B |= (1<<RXEN0) | (1<<TXEN0);
}

/*  Transmit 1 byte Data */
void transmit_1byte_USART0(unsigned char data){
    while(!(UCSR0A & (1<<UDRE0)));
    UDR0 = data;
}

/* Main Program*/
int main()
{
	init_USART0(UBRR);
	while(1){
		transmit_1byte_USART0('a');
		_delay_ms(10);
	}
    return 0;
}
 

Try this to initialize the UART baud rate

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

int main(void){
   UBRR0L = BAUD_PRESCALE;
   UBRR0H = (BAUD_PRESCALE >> 8);
  

    while(1)
    {

    }
}

- - - Updated - - -

Actually the boud rate doesn't seem to be the problem.

Have you changed the CLKDIV fuse to unprogrammed (1)?

- - - Updated - - -

You can always use the PR register instead of the fuse setting in the first line of main

CLKPR = 0x80 ;
CLKPR = 0x00 ;
 

You can always use the PR register instead of the fuse setting in the first line of main

CLKPR = 0x80 ;
CLKPR = 0x00 ;

hi alexan_e, Thanks for your help.
What do you mean when you set CLKPR in above codes, why the left hand side is the same ?
 

Have you studied the datasheet of mega168?

There is a register called CLKPR that controls the divider of the clock (from any source).
There is also a CLKDIV8 fuse that can control the default value loaded to CLKPR at startup (clk/1 or clk/8).
 

Ok, I see. Thank for your help.

Code:
CLKPR = 0x80 ;
CLKPR = 0x00 ;

I've added two line about to the first line of main().
In Realterm screen, Received character is also special character (strange) in ascii mode.
So the problem isn't solved. Can you give me another solution?

__I also try to use pyserial (python) to receive data from Atmega168, The result is very strange character, seem like Chinese character :(
 

open your pc serial properties in hardware panel and check if it set to 9600
 

Yes, I've checked it. USB Serial PORT (COM3): bits/sec: 9600, data bit: 8, parity: 0, stop bits: 1.
 

Have you connected a 16MHz crystal to the device and the fuses are set to use the crystal as clock source?

- - - Updated - - -

Are you actually using a MAX232 device between the AVR and RS232?
 

I connect Atmega168 to "FT232RL USB to Serial Adapter".
TxD -> RxD; RxD -> TxD;
This "FT232RL USB to Serial Adapter" connect to Computer via USB Port.

That is all my devices (Nothing else).
Is it not enough ?
 

Yes a FT232 can work with logic levels.

What about the chip clock?
 

I've change and F_CPU,F_OSC from 16E6 to 8000000, also add CLKPR = 0x80 ;CLKPR = 0x00 ; to the first line of main().
So it works correct :)

May be problem solved.
But I want to ask you about setting Clock Frequency.
When I learnt to use ADC converter, My program only works with F_CPU is 16E6. But this case, may be 8E6 is only one solution.
So, How can I set F_CPU or F_OSC in a direct way ?

Thank you very much for your help :)
 

What you refer to is just a define that stores the clock frequency value so that libraries that need to use it for calculation like the delay.h know what frequency to use.

This define does not change the hardware clock.
The hardware clock can either be changed by changing the divider using CLKPR or change the fuses and select from internal RC which is the default source (8MHz) to external clock , crystal etc.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top