Atmega8 UART running faster than set

Thread Starter

allahjane

Joined Sep 19, 2012
75
Hi there,

THIS PROBLEM IS FRUSTATING ME LIKE HELL!

I am using an atmega8 with 8Mhz internal oscillator

I have used the following formula to set UBBRH & UBBRL registers

BAUD_PRESCALE=(((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

where F_CPU is defined as 8000000

with USART_BAUDRATE =9600

but when I run the program the Uart run at a much faster speed !
I understood it when the receiver failed to understand the understand the transmission due to different baudrate and when I connected pin to speaker the A very high Pitch tone was produced

where as using the same settings on atmega16 it produced a LOW pitch tone

here's the code
Rich (BB code):
UCSRB |= (1 << TXEN );
UCSRC |=  (1 << UCSZ0 ) | (1 << UCSZ1 );

UBRRH = ( BAUD_PRESCALE >> 8); 
UBRRL = BAUD_PRESCALE ;
Is this because I used the Uart PIN as GPIO pin as output for a short time before starting the Uart by setting the TXEN bit?

I have rechecked the code and algorithm numerous times but I don't find anything regarding that error!

please help
 

tshuck

Joined Oct 18, 2012
3,534
I think you should post your whole code, otherwise it's mainly guesswork.

Check out page 155 of the datasheet, it tells you what UBRR is supposed to be in order to use the UART at 9600 baud.
 

Thread Starter

allahjane

Joined Sep 19, 2012
75
I think you should post your whole code, otherwise it's mainly guesswork.

Check out page 155 of the datasheet, it tells you what UBRR is supposed to be in order to use the UART at 9600 baud.
I posted only crucial part because the whole code is large but anyway as you said here's the whole code please help me

for ease of searching I have set all Uart related code in RED namely setTransmitter & RFstuff

/*
* SuperControllerTx.c
*
* Created: 10-01-13 12:31:31 PM
*/


#define F_CPU 8000000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/eeprom.h>
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

short state,SKflag=0,CALflag=0;

short callibrating=5,landscape=6,transmitting=1,idle=0;
int Lmax,Rmax,Umax,Dmax,Lzero,Rzero,Uzero,Dzero;
int Hreading,Vreading;

void setupIO(){
DDRB=(1<<PB4)|(1<<PB5);
DDRC=(1<<PC0)|(1<<PC1);
DDRD=(1<<PD6)|(1<<PD1);
PORTB=(1<<PB0)|(1<<PB1)|(1<<PB2);

}


void sendByte(int byte){
UDR = byte;
while (( UCSRA & (1 << TXC )) == 0) {};
}

int getADC(short key){

adc_init();
switch(key){
case 1:
ADMUX|=0x04;
break;
case 2:
ADMUX|=0x03;
break;
case 3:
ADMUX|=0x02;
break;
case 4:
ADMUX|=0x05;
break;


};


ADCSRA |= (1<<ADEN)|(1<<ADSC);
while (ADCSRA & (1<<ADSC));
ADCSRA=0;
return ADC;
}

void setTransmitter(short on){
if(on)
{


UCSRB |= (1 << TXEN );
UCSRC |= (1 << UCSZ0 ) | (1 << UCSZ1 );

UBRRH = ( BAUD_PRESCALE >> 8);
UBRRL = BAUD_PRESCALE ;
state=transmitting;
}
else
{
UCSRB = 0;
state=idle;
}

}



void POST(){
PORTD=(1<<PD6);//set key
_delay_ms(250);
PORTD=(1<<PD1);//RF
_delay_ms(250);
PORTD=0;
PORTB=(1<<PB5);//up
_delay_ms(250);
PORTC=(1<<PC1);//right
_delay_ms(250);
PORTC|=(1<<PC0);//down
_delay_ms(250);
PORTB|=(1<<PB4);//left
_delay_ms(250);
PORTB=0;
PORTC=0;
PORTD=0;
_delay_ms(200);
PORTC=0xff;
PORTB=0xff;
PORTD=0xff;
_delay_ms(500);
PORTB=0;
PORTC=0;
PORTD=0;
setupIO();
}

void adc_init()
{
ADMUX = (1<<REFS0);

ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
}


void dpadAll(short on)
{
if(on)
{
PORTC|=(1<<PC1)|(1<<PC0);//down right
PORTB|=(1<<PB4)|(1<<PB5);//left up
}
else{

PORTC&=0b11111100;
PORTB&=0b11001111;
}
}//dpadAll

void dpadSelective(short key,short on){
if(on){
switch(key){
case 1:
PORTB|=0b00100000;
break;
case 2:
PORTC|=0x01;
break;
case 3:
PORTB|=0b00010000;
break;
case 4:
PORTC|=0b00000010;
break;
};//end switch
}//on
else{

switch(key){
case 1:
PORTB&=~0b00100000;
break;
case 2:
PORTC&=~0x01;
break;
case 3:
PORTB&=~0b00010000;
break;
case 4:
PORTC&=~0b00000010;
break;
};//end switch
}
}


void callibrate(){
short counter=0;
short key=0;
short led=0;
while(1){
_delay_ms(10);
if(counter>20){
counter=0;
led=~led;
}
counter++;
if(key==0){
dpadAll(led);
}else
if(key==5){
dpadAll(1);
}else{
dpadAll(0);
dpadSelective(key,led);
}

if(~PINB&(1<<PB1)){
if(!CALflag){
CALflag=1;
switch(key){
case 0:
Uzero=getADC(1);
Dzero=getADC(2);
Lzero=getADC(3);
Rzero=getADC(4);
break;
case 1:
Umax=getADC(1);
break;

case 2:
Dmax=getADC(2);
break;

case 3:
Lmax=getADC(3);
break;

case 4:
Rmax=getADC(4);
break;
};
key++;
}
}else
CALflag=0;
if(key>5){
dpadAll(0);
break;
}
}//end while 1

}

void scanKeys(){

if(~PINB&(1<<PB1))
{
if(!CALflag&&state!=callibrating)
{
CALflag=1;
callibrate();}//Calflag
}

else{CALflag=0;}


if(~PINB&(1<<PB0)){
if(!SKflag){
SKflag=1;
if(state==idle)
setTransmitter(1);
else {
if(state==transmitting)
setTransmitter(0);}//end else
} //end skflag
}//end if
else
SKflag=0;


}//end scan key
void RFstuff(){
sendByte(0x08);
}


void keyLight(){

if(getADC(1)>((Umax+Uzero)/2))
dpadSelective(1,1);
else
dpadSelective(1,0);

if(getADC(2)>((Dmax+Dzero)/2))
dpadSelective(2,1);
else
dpadSelective(2,0);

if(getADC(3)>((Lmax+Lzero)/2))
dpadSelective(3,1);
else
dpadSelective(3,0);

if(getADC(4)>((Rmax+Rzero)/2))
dpadSelective(4,1);
else
dpadSelective(4,0);
}

int main(void)
{
setupIO();
POST();
setTransmitter(1);

adc_init();
while(1)
{
scanKeys();
if(state==transmitting)
RFstuff();
keyLight();


}

}
 

tshuck

Joined Oct 18, 2012
3,534
The red was quite nice....
This
Rich (BB code):
UCSRC |= (1 << UCSZ0 ) | (1 << UCSZ1 );
isn't actually necessary as these bits are set upon reset, though it doesn't hurt to explicitly state it...

I think the problem lies with your define. I don't think the size is guaranteed to be a 16 bit number, but you are treating as such with
Rich (BB code):
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) 
...
UBRRH = ( BAUD_PRESCALE >> 8); 
UBRRL = BAUD_PRESCALE ;
I'd say to split up the define, like:
Rich (BB code):
#define BAUD_PRESCALE_HIGH 0
#define BAUD_PRESCALE_LOW 51
or you could probably write:
Rich (BB code):
#define BAUD_PRESCALE_HIGH  (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)/256
#define BAUD_PRESCALE_LOW  (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
then:
Rich (BB code):
UBRRH = BAUD_PRESCALE_HIGH;
UBRRL = BAUD_PRESCALE_LOW ;
 

Thread Starter

allahjane

Joined Sep 19, 2012
75
Well the problem still exists ! But I'll say we're heading in right direction

using

UBRRH = BAUD_PRESCALE_HIGH;
UBRRL = BAUD_PRESCALE_LOW ;

decreased the rate but still not to set rate (I think , as receiver can respond to it, while it understands from atmega 16)
 

tshuck

Joined Oct 18, 2012
3,534
It seems like you are testing this through sound level? What makes you think the tone you heard already is correct? Why not test the Atmega16 against the Atmega8 so that the 8 will transmit to the 16 and the 16 will light a LED when a certain character is received?

You shouldn't be trying to do UART with all of the other stuff, you should make an isolated test case(just UART) and move working code into this project.
 

Thread Starter

allahjane

Joined Sep 19, 2012
75
It seems like you are testing this through sound level? What makes you think the tone you heard already is correct? Why not test the Atmega16 against the Atmega8 so that the 8 will transmit to the 16 and the 16 will light a LED when a certain character is received?

You shouldn't be trying to do UART with all of the other stuff, you should make an isolated test case(just UART) and move working code into this project.
Yes, but I'm already doing so

I have two transmitters one atmega8 and other atmega16

while receiver is atmega16

both atmega 16 work fine

but atmega8 and 16 doesn't

its like atmega16 or RF transmitters are RACIST :D

OK i'll now try with just Uart code on atmega 8
 

Thread Starter

allahjane

Joined Sep 19, 2012
75
DAMN IT :mad:


IT STILL WONT WORK

#include <avr/io.h>
#include <util/delay.h>

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


void sendByte(int byte){
UDR = byte;
while (( UCSRA & (1 << TXC )) == 0) {};
}


int main(){
DDRA=0x00;
PORTA=0xFF;

UCSRB |= (1 << TXEN );
UCSRC |= (1 << UCSZ0 ) | (1 << UCSZ1 );
UBRRH = ( BAUD_PRESCALE >> 8);
UBRRL = BAUD_PRESCALE ;

while(1){
sendByte(~(0x08));

}//while(1);
}
 

tshuck

Joined Oct 18, 2012
3,534
you should put a small delay between each transmission... also, you did what I said you should change in post #4.

...it's times like these that I'm glad I have a BusPirate... or, one of these
 

kubeek

Joined Sep 20, 2005
5,796
Or an oscilloscope.
Try changing the code to explicitly UBRRH=0 and UBRRL=51, I am sure those values are correct. Also add a delay after the sendbyte, like two chars per second. If you got a serial port on your pc, try connecting to it and play with the baudrate untill you get something, if you get more than one byte for each transmission the the pc´s baud rate is too high.
What oscillator do you use? Can you check that the atmega16 isn´t configured with the CLKDIV fuse enabled, thus transmitting at 1200baud instead of 9600? Because 9.6khz is a high pitch, and 1200hz is similar to the no signal tone on tv.
 

thatoneguy

Joined Feb 19, 2009
6,359
Rich (BB code):
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
Putting in 8Mhz and 9600 baud, prescaler calculates to 51

is that correct?

It does seem like a byte vs word interpretation of code if the same code works on a different target.
 

tshuck

Joined Oct 18, 2012
3,534
Rich (BB code):
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
Putting in 8Mhz and 9600 baud, prescaler calculates to 51

is that correct?

It does seem like a byte vs word interpretation of code if the same code works on a different target.
Yes, it is correct... both the datasheet says it explicitly(pg. 155), and the formula given(here and datasheet[pg. 132]) corroborate this value...
 
Last edited:

Thread Starter

allahjane

Joined Sep 19, 2012
75
Its clearly technical racism

I replaced atmega16 in the receiver with atmega8 with same code and BOOM

PERFECT COMMUNICATION
 

kubeek

Joined Sep 20, 2005
5,796
Its clearly technical racism I replaced atmega16 in the receiver with atmega8 with same code and BOOM PERFECT COMMUNICATION
I would blame wrong code or fuse setting in the atmega16, rather than technical racism. And even so, racism would be a pic not speaking with atmega, not atmegas not speaking with their own kin.
 
Top