Attiny414 UART wrong character

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

All settings are correct. Still the characters are wrong.

 

#define F_CPU 20000000UL
#define BAUD_RATE 9600
#define BAUD_PRESCALE ((64UL * F_CPU)/(16UL * BAUD_RATE))

 

#include <avr/io.h>
#include <atmel_start.h>
#include <main.h>
#include <avr/wdt.h>
#include <string.h>

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

 

Usart Usart_;

 

Usart::Usart(){
    PORTMUX.CTRLB = PORTMUX_USART0_ALTERNATE_gc;     
    USART_TX_set_dir(PORT_DIR_OUT);    
    USART_TX_set_level(HIGH);
    TRIGGER_set_dir(PORT_DIR_IN);
    
    USART0.BAUD  = (uint16_t)BAUD_PRESCALE;               
    USART0.CTRLC = USART_CMODE_ASYNCHRONOUS_gc |      
                    USART_CHSIZE_8BIT_gc |               
                    USART_SBMODE_1BIT_gc |            
                    USART_PMODE_DISABLED_gc;              
    USART0.CTRLB = USART_RXEN_bm | USART_TXEN_bm;      
    USART0.CTRLA = 0;
}

 

void Usart::Transmit(unsigned char Tx_Data){
    while(!(USART0.STATUS & USART_DREIF_bm)){;};
    USART0.TXDATAL = Tx_Data;
}

 

unsigned char Usart::Receive(void){
    while(!(USART0.STATUS & USART_RXCIF_bm)){;};
    return USART0.RXDATAL;
}
   

int main(){
    atmel_start_init();     // Initializes MCU, drivers and middleware
    
    Usart();
  
    while(1){  
        Usart_.Transmit('A');
        _delay_ms(500);
    
    }

    return 0;
}

Attachment(s): 

This topic has a solution.
Last Edited: Wed. Sep 21, 2022 - 10:56 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How do you know that your AVR is running at 20MHz?

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

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

Following the datasheet ATtiny214/414/814 CPU is running 20 MHz

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

I'm going to go way out on a limb here and assume (without downloading and studying hours of documentation on the Tiny414) that    USART0.BAUD  =  is the way to program the baud rate and that to get 9600 baud, you would use:    USART0.BAUD  = 9600;     If this is not the case, please let me know.

 

  If it is true then you have a wrong formula because I get about 8000 every time that I work the unusual formula (i.e.  64* Fosc ect...) that the code is using.  This is close enough to 9600 to give the observed problem behavior: constant wrong chars on UART input.

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


With 9600, it doesn't work either.If I want 9600 baud rate, you have to calculate it for the register.

 

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


MrKrypton wrote:

Following the datasheet ATtiny214/414/814 CPU is running 20 MHz

 

So, somewhere, you've turned off the divide by 6 prescaler?

 

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

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

Try adding this line.
If this helps, you have your clock settings wrong.

 

    Usart();

    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, 0);  // ADD LINE

    while(1){  
        Usart_.Transmit('A');
        _delay_ms(500);

 

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

MrKrypton wrote:

Following the datasheet ATtiny214/414/814 CPU is running 20 MHz

Yes F_CPU by default is 20MHz. By default F_PER is divided by a factor of 6 i.e 20MHz/6=3.3MHz. So add one more line and correct the baud rate formula as highlighted, in you program as below

 

#define F_PER 3333333UL

#define BAUD_PRESCALE (((64UL * F_PER)/(16UL * BAUD_RATE))+0.5)

Last Edited: Tue. Sep 20, 2022 - 02:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

With these settings, it doesn't work either

 

#define F_PER 3333333UL

#define BAUD_PRESCALE (((64UL * F_PER)/(16UL * BAUD_RATE))+0.5)

Last Edited: Tue. Sep 20, 2022 - 02:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why do so many simple mistakes happen?

#define F_PER 3333333UL // wrong

#define F_CPU 3333333UL // correct

 

good bye

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

#define F_CPU 3333333UL also wrong

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

This is working code for my ATmega328p. For the Attiny414 I followed the same principles with the datasheet.

#define F_CPU 16000000UL // Default clock speed
#define BAUD 9600
#define MYUBRR (F_CPU/16/BAUD-1)

 

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

 

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

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

void USART_Init(unsigned int ubrr){
    UBRR0H = (unsigned char)(ubrr>>8);
    UBRR0L = (unsigned char)ubrr;
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);
    UCSR0C = (3<<UCSZ00);
}

 

int main(void){
    USART_Init(MYUBRR);
    sei();

 

        while(1){
            unsigned char Rx_data;

            Rx_data = USART_Receive();
            USART_Transmit(Rx_data);  //echo
    }
}

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

https://ww1.microchip.com/downlo...
 

 

#define F_CPU 3333333
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>

void USART0_sendString(const char *str)
{
  for(size_t i = 0; i < strlen(str); i++)
  {
    while(!(USART0.STATUS & USART_DREIF_bm))
    { }
    USART0.TXDATAL = str[i];
  }
}

int main(void)
{
  PORTB.DIRSET = PIN2_bm;            // USART TxD pin
  USART0.BAUD = 1389;                // 9600 @ 3.33MHz
  USART0.CTRLB = USART_TXEN_bm;      // enable Transmitter

  while(1)
  {
    USART0_sendString("Hello World!\r\n");
    _delay_ms(1000);
  }
}

 

The truth is more important than the facts. (Frank Lloyd Wright / Unsourced)

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

It's probably the terminal. I get the correct character with the oscilloscope 

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

It's probably the terminal. I get the correct character with the oscilloscope 

Timing errors hardly seem likely, if it is on the PC--the timebase should be on the money.  Of course, it could be cabling/connections, or are the terminal setting suspect?  Obviously the correct baush/start/stop needs set properly.

The terminal might have some trouble keeping up if you are pumping out chars with no time gap whatsoever.  Bray's gulps a bit if you set it to stream hex values in addition to the 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

AVR USART TxD

The truth is more important than the facts. (Frank Lloyd Wright / Unsourced)

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

Are you saying the answer in #7 did NOT work? 

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

What’s the interface to the pc?  A USB to ttl cable (w/ leads for TX,RX, GND)?  or a USB to RS232 (w/ DE9 connector)?

hint the DE9 connector will not work without  RS-232 converter on your AVR RX/TX pins!

 

jim

 

 

FF = PI > S.E.T

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DE9 connector cable was defect. That was the problem