Atmega8 UART running faster than set

Discussion in 'Embedded Systems and Microcontrollers' started by allahjane, Jan 10, 2013.

  1. allahjane

    Thread Starter Member

    Sep 19, 2012
    75
    1
    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
    Code ( (Unknown Language)):
    1.  
    2. UCSRB |= (1 << TXEN );
    3. UCSRC |=  (1 << UCSZ0 ) | (1 << UCSZ1 );
    4.  
    5. UBRRH = ( BAUD_PRESCALE >> 8);
    6. UBRRL = BAUD_PRESCALE ;
    7.  
    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
     
  2. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    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.
     
  3. allahjane

    Thread Starter Member

    Sep 19, 2012
    75
    1
    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

     
  4. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    The red was quite nice....
    This
    Code ( (Unknown Language)):
    1. 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
    Code ( (Unknown Language)):
    1. #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
    2. ...
    3. UBRRH = ( BAUD_PRESCALE >> 8);
    4. UBRRL = BAUD_PRESCALE ;
    5.  
    I'd say to split up the define, like:
    Code ( (Unknown Language)):
    1. #define BAUD_PRESCALE_HIGH 0
    2. #define BAUD_PRESCALE_LOW 51
    or you could probably write:
    Code ( (Unknown Language)):
    1. #define BAUD_PRESCALE_HIGH  (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)/256
    2. #define BAUD_PRESCALE_LOW  (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
    then:
    Code ( (Unknown Language)):
    1. UBRRH = BAUD_PRESCALE_HIGH;
    2. UBRRL = BAUD_PRESCALE_LOW ;
    3.  
     
  5. allahjane

    Thread Starter Member

    Sep 19, 2012
    75
    1
    OK the circuit is at my disposal !
    just a minute I'll try and repost
     
  6. allahjane

    Thread Starter Member

    Sep 19, 2012
    75
    1
    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)
     
  7. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    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.
     
  8. allahjane

    Thread Starter Member

    Sep 19, 2012
    75
    1
    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
     
  9. allahjane

    Thread Starter Member

    Sep 19, 2012
    75
    1
    DAMN IT :mad:


    IT STILL WONT WORK

     
  10. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    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
     
  11. kubeek

    AAC Fanatic!

    Sep 20, 2005
    4,670
    804
    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.
     
  12. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    Code ( (Unknown Language)):
    1.  
    2. #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
    3.  
    4.  
    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.
     
  13. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    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: Jan 10, 2013
  14. allahjane

    Thread Starter Member

    Sep 19, 2012
    75
    1
    Its clearly technical racism

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

    PERFECT COMMUNICATION
     
  15. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    To be clear, you've set CKSEL<3:0> to 0b0100, right?
     
  16. kubeek

    AAC Fanatic!

    Sep 20, 2005
    4,670
    804
    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.
     
    tshuck likes this.
Loading...