ATmega-644P loop execution and USART timing issues

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

Hello everyone,

It looks like that there are some hardware issues on my setup that confuses me. Therefore discussing here and getting some advises from experienced specialists would be very helpful to see thing that I might be missing.

 

I'm employing atmega644p clocked via crystal at 20Mhz. I placed an LED on PB0 and toggle it inside the event loop to measure the loop execution time on scope, which is 2.60 MHz. So atmega 644P clocked at 20 MHz yields a loop execution of 2.60 MHz.

 

As soon as I add a small statement with USART0, just printing a small string of characters inside the loop.

printString("Data transmission [ADC] = ");

The loop execution time drops to 70 Hz or even less 8Hz sometimes. The actual code which AVR executes is below. It would very helpful is to know what is done wrong on my side here. Is it due to USART peripheral wrong initialization?, or maybe other bugs which I can't see.

 

//----------------- Preamble ----------------- //
#include <avr/io.h>
#include <util/delay.h>
#include <avr/power.h>
#include <Hardware_Connections_Bay.h>
#include <In_Lining_Functions.h>
#include <USART.h>
#include <stdio.h>
#include <stdlib.h>

uint8_t ADC_lowbyte, ADC_highbyte;
uint16_t ADC_data;
//----------------- Initializations ----------------- //
int main (void){

    initUSART(); // start USART-0
    printString("USART-0 Hardware >>> initialized");
    printString("\r\n\n");
    initTimer0(); // start Timer-0
    printString("Timer-0 Hardware >>> initialized");
    printString("\r\n\n");
    _delay_ms(1700);
    printString("\r\n\n\n\n");
    printString("//-----------=( xxxxxxxxxxxxxx )=-----------//");
    printString("\r\n\n");
    printString("------------------------------------------------");
    printString("\r\n\n");
    printString("//--------=( Firmware version 1.0a )=-------//");
    printString("\r\n\n");
    _delay_ms(2000);

    SAMPLE_ADC_CONTROL_DDR |= (1 << STATUS_LED);// LED setup for loop execution timing checks
    SAMPLE_ADC_CONTROL_DDR &= ~ (1 << DATA_READY_ADC);// DRDY data-ready/PB2 setup input mode
    SAMPLE_ADC_CONTROL_DDR |= (1 << CLOCK_IN_ADC);// setup PB3/OC0A in output mode for ADC clocking via Timer-0

    SAMPLE_ADC_LOW_DDR = 0x00;// ADC low byte data direction register setup in input mode BANK(A)
    SAMPLE_ADC_LOW_PORT = 0x00;// ADC Low byte port pull-up enabled, BANK(A)

    SAMPLE_ADC_HIGH_DDR = 0x00;// ADC high byte data direction register setup in input mode BANK(C)
    SAMPLE_ADC_HIGH_PORT = 0x00;// ADC high byte port pull-up enabled, BANK(C)
    OCR0A = 10;// Timer-0 output frequency  setup for ADC(CLKIN) pin ~ 1.0 MHz

//----------------- Event loop ----------------- //
 while(1){

     SAMPLE_ADC_CONTROL_PORT ^= (1 << STATUS_LED); // helps to read the loop execution (with function get_ADC_data() time which is 3.2 MHz
     getDataADC(); // collects low and high bytes from ADC and combines them
     printString("Data transmission [ADC] = ");
     printWord(ADC_data);
     printString("\r\n");
 }
 return(0);
}

 

work in progress...

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

 

Let's assume printString() is a blocking function. I.e. It doesn't return until all characters are transmitted.

Let's assume printString() writes out characters to USART0.

Let's also assume initUSART(); configures USART0 to 9600bps.

 

In that case, this code:

     printString("Data transmission [ADC] = ");
     printWord(ADC_data);
     printString("\r\n");

in printing about 33 characters would take at least 33ms to run. This corresponds to about 30Hz.

 

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

Dave_Zeb. wrote:
As soon as I add a small statement with USART0

The one important piece of info you left out was, what is the baud rate of your USART?

At 9600 baud, it takes ~1ms per character, so your 38-40 char string will slow your main loop to less then 40 Hz rate, why does that surprise you?

Also the ADC requires approx 100us to do its conversion and you also block waiting for completion as well.

If you need a faster main loop operation, you need to use non-blocking operations and then test for completion of these types of operations and then act as needed.

Check out the tutorial on task scheduling for examples of how to do this.

 

Jim

 

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

the USART Baud rate is 9600, I just found it configured in makefile. What is strange to me, even if I try to set faster baud rates, it still runs at 9600.

As I understand if I change the defined baud rate in this makefile to 250K ,  then it should then run the USART at according to new defined baud rate, which is not the case here.

 

##########------------------------------------------------------##########
##########              Project-specific Details                ##########
##########    Check these every time you start a new project    ##########
##########------------------------------------------------------##########

MCU   = atmega644p
F_CPU = 2000000UL
BAUD  = 9600UL
## Also try BAUD = 19200 or 38400 if you're feeling lucky.

## A directory for common include files and the simple USART library.
## If you move either the current folder or the Library folder, you'll
##  need to change this path to match.
LIBDIR = ../../AVR-Programming-Library

##########------------------------------------------------------##########
##########                 Programmer Defaults                  ##########
##########          Set up once, then forget about it           ##########
##########        (Can override.  See bottom of file.)          ##########
##########------------------------------------------------------##########

PROGRAMMER_TYPE = avrisp
# extra arguments to avrdude: baud rate, chip type, -F flag, etc.
PROGRAMMER_ARGS = -P com6 -b 19200

##########------------------------------------------------------##########
##########                  Program Locations                   ##########
##########     Won't need to change if they're in your PATH     ##########
##########------------------------------------------------------##########

CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = avrdude

##########------------------------------------------------------##########
##########                   Makefile Magic!                    ##########
##########         Summary:                                     ##########
##########             We want a .hex file                      ##########
##########        Compile source files into .elf                ##########
##########        Convert .elf file into .hex                   ##########
##########        You shouldn't need to edit below.             ##########
##########------------------------------------------------------##########

## The name of your project (without the .c)
# TARGET = blinkLED
## Or name it automatically after the enclosing directory
TARGET = $(lastword $(subst /, ,$(CURDIR)))

this is the initUSART.h  file where I also change the baud rate to faster one, but as mentioned it still runs at 9600 rate.

 

/* Functions to initialize, send, receive over USART

   initUSART requires BAUD to be defined in order to calculate
     the bit-rate multiplier.
 */

#ifndef BAUD                          /* if not defined in Makefile... */
#define BAUD  9600                     /* set a safe default baud rate */
#endif

                                  /* These are defined for convenience */
#define   USART_HAS_DATA   bit_is_set(UCSR0A, RXC0)
#define   USART_READY      bit_is_set(UCSR0A, UDRE0)

/* Takes the defined BAUD and F_CPU,
   calculates the bit-clock multiplier,
   and configures the hardware USART                   */
void initUSART(void);

/* Blocking transmit and receive functions.
   When you call receiveByte() your program will hang until
   data comes through.  We'll improve on this later. */
void transmitByte(uint8_t data);
uint8_t receiveByte(void);

void printString(const char myString[]);
             /* Utility function to transmit an entire string from RAM */
void readString(char myString[], uint8_t maxLength);
/* Define a string variable, pass it to this function
   The string will contain whatever you typed over serial */

void printByte(uint8_t byte);
                  /* Prints a byte out as its 3-digit ascii equivalent */
void printWord(uint16_t word);
        /* Prints a word (16-bits) out as its 5-digit ascii equivalent */

void printBinaryByte(uint8_t byte);
                                     /* Prints a byte out in 1s and 0s */
char nibbleToHex(uint8_t nibble);
char nibbleToHexCharacter(uint8_t nibble);
void printHexByte(uint8_t byte);
                                   /* Prints a byte out in hexadecimal */
uint8_t getNumber(void);
/* takes in up to three ascii digits,
 converts them to a byte when press enter */

 this is the source file with the working functions which I use.

 

#include <avr/io.h>
#include "USART.h"
#include <util/setbaud.h>

void initUSART(void) {                                /* requires BAUD */
  UBRR0H = UBRRH_VALUE;                        /* defined in setbaud.h */
  UBRR0L = UBRRL_VALUE;
#if USE_2X
  UCSR0A |= (1 << U2X0);
#else
  UCSR0A &= ~(1 << U2X0);
#endif
                                  /* Enable USART transmitter/receiver */
  UCSR0B = (1 << TXEN0) | (1 << RXEN0);
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);   /* 8 data bits, 1 stop bit */
}


void transmitByte(uint8_t data) {
                                     /* Wait for empty transmit buffer */
  loop_until_bit_is_set(UCSR0A, UDRE0);
  UDR0 = data;                                            /* send data */
}

uint8_t receiveByte(void) {
  loop_until_bit_is_set(UCSR0A, RXC0);       /* Wait for incoming data */
  return UDR0;                                /* return register value */
}


                       /* Here are a bunch of useful printing commands */

void printString(const char myString[]) {
  uint8_t i = 0;
  while (myString[i]) {
    transmitByte(myString[i]);
    i++;
  }
}

void readString(char myString[], uint8_t maxLength) {
  char response;
  uint8_t i;
  i = 0;
  while (i < (maxLength - 1)) {                   /* prevent over-runs */
    response = receiveByte();
    transmitByte(response);                                    /* echo */
    if (response == '\r') {                     /* enter marks the end */
      break;
    }
    else {
      myString[i] = response;                       /* add in a letter */
      i++;
    }
  }
  myString[i] = 0;                          /* terminal NULL character */
}

void printByte(uint8_t byte) {
              /* Converts a byte to a string of decimal text, sends it */
  transmitByte('0' + (byte / 100));                        /* Hundreds */
  transmitByte('0' + ((byte / 10) % 10));                      /* Tens */
  transmitByte('0' + (byte % 10));                             /* Ones */
}

void printWord(uint16_t word) {
  transmitByte('0' + (word / 10000));                 /* Ten-thousands */
  transmitByte('0' + ((word / 1000) % 10));               /* Thousands */
  transmitByte('0' + ((word / 100) % 10));                 /* Hundreds */
  transmitByte('0' + ((word / 10) % 10));                      /* Tens */
  transmitByte('0' + (word % 10));                             /* Ones */
}

void printBinaryByte(uint8_t byte) {
                       /* Prints out a byte as a series of 1's and 0's */
  uint8_t bit;
  for (bit = 7; bit < 255; bit--) {
    if (bit_is_set(byte, bit))
      transmitByte('1');
    else
      transmitByte('0');
  }
}

char nibbleToHexCharacter(uint8_t nibble) {
                                   /* Converts 4 bits into hexadecimal */
  if (nibble < 10) {
    return ('0' + nibble);
  }
  else {
    return ('A' + nibble - 10);
  }
}

void printHexByte(uint8_t byte) {
                        /* Prints a byte as its hexadecimal equivalent */
  uint8_t nibble;
  nibble = (byte & 0b11110000) >> 4;
  transmitByte(nibbleToHexCharacter(nibble));
  nibble = byte & 0b00001111;
  transmitByte(nibbleToHexCharacter(nibble));
}

uint8_t getNumber(void) {
  // Gets a numerical 0-255 from the serial port.
  // Converts from string to number.
  char hundreds = '0';
  char tens = '0';
  char ones = '0';
  char thisChar = '0';
  do {                                                   /* shift over */
    hundreds = tens;
    tens = ones;
    ones = thisChar;
    thisChar = receiveByte();                   /* get a new character */
    transmitByte(thisChar);                                    /* echo */
  } while (thisChar != '\r');                     /* until type return */
  return (100 * (hundreds - '0') + 10 * (tens - '0') + ones - '0');
}

besides the makefile what else I should change to get the AVR running at faster rates say, 250K for example

 

work in progress...

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

If you don't want the UART to block the main loop then use TX interrupts and a ring buffer.

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

I'm assuming you didn't actually write this code and are struggling to find out how it works (or doesn't work as the case may be) !

 

Where did that Makefile come from ? It's pretty sparse or you didn't post all of it.

 

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

The code laid in "main.c" is written by me. What I am struggling is related to the USART, to make it run maximum speeds possible on my setup. Unfortunately when I edit the makefile and type a new baud rate for example 250K, after saving and running it on AVR, it still runs on 9600, although in makefile its marked to be 250K. Why is that happening. How can I make the USART transfer with speeds 250k or higher. I posted half of the makefile earlier, full version below.

 


##########------------------------------------------------------##########
##########              Project-specific Details                ##########
##########    Check these every time you start a new project    ##########
##########------------------------------------------------------##########

MCU   = atmega644p
F_CPU = 22000000UL
BAUD  = 9600UL
## Also try BAUD = 19200 or 38400 if you're feeling lucky.

## A directory for common include files and the simple USART library.
## If you move either the current folder or the Library folder, you'll
##  need to change this path to match.
LIBDIR = ../../AVR-Programming-Library

##########------------------------------------------------------##########
##########                 Programmer Defaults                  ##########
##########          Set up once, then forget about it           ##########
##########        (Can override.  See bottom of file.)          ##########
##########------------------------------------------------------##########

PROGRAMMER_TYPE = avrisp
# extra arguments to avrdude: baud rate, chip type, -F flag, etc.
PROGRAMMER_ARGS = -P com6 -b 19200

##########------------------------------------------------------##########
##########                  Program Locations                   ##########
##########     Won't need to change if they're in your PATH     ##########
##########------------------------------------------------------##########

CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = avrdude

##########------------------------------------------------------##########
##########                   Makefile Magic!                    ##########
##########         Summary:                                     ##########
##########             We want a .hex file                      ##########
##########        Compile source files into .elf                ##########
##########        Convert .elf file into .hex                   ##########
##########        You shouldn't need to edit below.             ##########
##########------------------------------------------------------##########

## The name of your project (without the .c)
# TARGET = blinkLED
## Or name it automatically after the enclosing directory
TARGET = $(lastword $(subst /, ,$(CURDIR)))

# Object files: will find all .c/.h files in current directory
#  and in LIBDIR.  If you have any other (sub-)directories with code,
#  you can add them in to SOURCES below in the wildcard statement.
SOURCES=$(wildcard *.c $(LIBDIR)/*.c)
OBJECTS=$(SOURCES:.c=.o)
HEADERS=$(SOURCES:.c=.h)

## Compilation options, type man avr-gcc if you're curious.
CPPFLAGS = -DF_CPU=$(F_CPU) -DBAUD=$(BAUD) -I. -I$(LIBDIR)
CFLAGS = -Os -g -std=gnu99 -Wall
## Use short (8-bit) data types
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
## Splits up object files per function
CFLAGS += -ffunction-sections -fdata-sections
LDFLAGS = -Wl,-Map,$(TARGET).map
## Optional, but often ends up with smaller code
LDFLAGS += -Wl,--gc-sections
## Relax shrinks code even more, but makes disassembly messy
## LDFLAGS += -Wl,--relax
## LDFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm  ## for floating-point printf
## LDFLAGS += -Wl,-u,vfprintf -lprintf_min      ## for smaller printf
TARGET_ARCH = -mmcu=$(MCU)

## Explicit pattern rules:
##  To make .o files from .c files
%.o: %.c $(HEADERS) Makefile
	 $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $<;

$(TARGET).elf: $(OBJECTS)
	$(CC) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@

%.hex: %.elf
	 $(OBJCOPY) -j .text -j .data -O ihex $< $@

%.eeprom: %.elf
	$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@

%.lst: %.elf
	$(OBJDUMP) -S $< > $@

## These targets don't have files named after them
.PHONY: all disassemble disasm eeprom size clean squeaky_clean flash fuses

all: $(TARGET).hex

debug:
	@echo
	@echo "Source files:"   $(SOURCES)
	@echo "MCU, F_CPU, BAUD:"  $(MCU), $(F_CPU), $(BAUD)
	@echo

# Optionally create listing file from .elf
# This creates approximate assembly-language equivalent of your code.
# Useful for debugging time-sensitive bits,
# or making sure the compiler does what you want.
disassemble: $(TARGET).lst

disasm: disassemble

# Optionally show how big the resulting program is
size:  $(TARGET).elf
	$(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf

clean:
	rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
	$(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
	$(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
	$(TARGET).eeprom

squeaky_clean:
	rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~ *.eeprom

##########------------------------------------------------------##########
##########              Programmer-specific details             ##########
##########           Flashing code to AVR using avrdude         ##########
##########------------------------------------------------------##########

flash: $(TARGET).hex
	$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<

## An alias
program: flash

flash_eeprom: $(TARGET).eeprom
	$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<

avrdude_terminal:
	$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt

## If you've got multiple programmers that you use,
## you can define them here so that it's easy to switch.
## To invoke, use something like `make flash_arduinoISP`
flash_usbtiny: PROGRAMMER_TYPE = usbtiny
flash_usbtiny: PROGRAMMER_ARGS =  # USBTiny works with no further arguments
flash_usbtiny: flash

flash_usbasp: PROGRAMMER_TYPE = usbasp
flash_usbasp: PROGRAMMER_ARGS =  # USBasp works with no further arguments
flash_usbasp: flash

flash_arduinoISP: PROGRAMMER_TYPE = avrisp
flash_arduinoISP: PROGRAMMER_ARGS = -b 19200 -P /dev/ttyACM0
## (for windows) flash_arduinoISP: PROGRAMMER_ARGS = -b 19200 -P com5
flash_arduinoISP: flash

flash_109: PROGRAMMER_TYPE = avr109
flash_109: PROGRAMMER_ARGS = -b 9600 -P /dev/ttyUSB0
flash_109: flash

#flash_AVR_ISP_MK_II: PROGRAMMER_TYPE = avrisp_mk2
#flash_AVR_ISP_MK_II: PROGRAMMER_ARGS = -b 19200 -P USB

##########------------------------------------------------------##########
##########       Fuse settings and suitable defaults            ##########
##########------------------------------------------------------##########

## Mega 48, 88, 168, 328 default values
LFUSE = 0x62
HFUSE = 0xdf
EFUSE = 0x00

## Generic
FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m

fuses:
	$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \
	           $(PROGRAMMER_ARGS) $(FUSE_STRING)
show_fuses:
	$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv

## Called with no extra definitions, sets to defaults
set_default_fuses:  FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
set_default_fuses:  fuses

## Set the fuse byte for full-speed mode
## Note: can also be set in firmware for modern chips
set_fast_fuse: LFUSE = 0xE2
set_fast_fuse: FUSE_STRING = -U lfuse:w:$(LFUSE):m
set_fast_fuse: fuses

## Set the EESAVE fuse byte to preserve EEPROM across flashes
set_eeprom_save_fuse: HFUSE = 0xD7
set_eeprom_save_fuse: FUSE_STRING = -U hfuse:w:$(HFUSE):m
set_eeprom_save_fuse: fuses

## Clear the EESAVE fuse byte
clear_eeprom_save_fuse: FUSE_STRING = -U hfuse:w:$(HFUSE):m
clear_eeprom_save_fuse: fuses

 

work in progress...

Last Edited: Tue. Apr 23, 2019 - 04:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What happened when you googled "ring buffer"? (I deliberately included the right keywords for your googling).
.
BTW the essence of a ring buffer and a TX interrupt is that it's like a "holding tank". When you print() the string instead of that taking ages slowly sending character by character instead all the characters are immediately absorbed into the buffer taking almost no time at all. Then slowly but surely, in the "background" those characters are sent out one by one as soon as each of the previous has gone. While doing that absorbs a small amount of CPU time it's only very quick bursts of activity well spaced out that hardly impacts your main loop operation.

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

it looks complicated to me, I'm not familiar with C structures and their usages. Is there any other easy solution for my skills level maybe?

 

work in progress...

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

Now that you've posted the entire Makefile, I see nothing wrong with it

 

I edited BAUD as you say you've done with the following results from setbaud.h:

With BAUD = 9600UL

UBRRH_VALUE = 0x0
UBRRL_VALUE =0x8e

 

With BAUD = 115200UL

UBRRH_VALUE = 0x0
UBRRL_VALUE = 0xb
 

There definitely should be a difference in baudrate. i wonder if you are programming the correct HEX ?

 

Here's a tip: In one of your initial prints do something like this:

    printString("//--------=( Firmware version 1.0a )=-------//");
    printString("\r\n\n");
    printString("//-=( Compiled on: " __DATE__ " " __TIME__ " )=-------//");
    printString("\r\n\n");

You will know at once if you haven't programmed the up-to-date HEX.

 

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

That’s why there is Arduino. The tricky stuff has been done for you.

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

thanks for the information. I've commented out the setbaud.h file and manually added the values inside the initUSART() initialization function.

 

#include <avr/io.h>
#include "USART.h"
//#include <util/setbaud.h>

void initUSART(void) {                                /* requires BAUD */
  UBRR0H = 0x0;//UBRRH_VALUE;                        /* defined in setbaud.h */
  UBRR0L = 0xb;//UBRRL_VALUE;
#if USE_2X
  UCSR0A |= (1 << U2X0);
#else
  UCSR0A &= ~(1 << U2X0);
#endif
                                  /* Enable USART transmitter/receiver */
  UCSR0B = (1 << TXEN0) | (1 << RXEN0);
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);   /* 8 data bits, 1 stop bit */
}

With BAUD = 115200UL, UBRRH_VALUE = 0x0, UBRRL_VALUE = 0xb. With Fosc = 20MHz now it runs 115200 Baud. Which is pretty amazing.

 

 

- It looks like when I'm editing my source code in code editor and then saving it and uploading it via avrdude does not update the intel HEX files and object files. I should manually delete them and rebuild them to make sense the new changes. Wondering about possible reasons  for such a glitch. Before it never occurred.

 

- so coming back to my USART and Loop execution issue, what could be the highest possible Baud rate aka transmission speed with my specs of Fosc  = 20 MHz besides the implementation of "ringbuffer with Tx interrupt" in order to maintain the loop

execution in 2-3.0 Mhz range.

work in progress...

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

The fastest UART rate is when UBRR=0.