1

MCU: Atmega2560 IDE: Microchip Studio v7.0.2594 Toolchain: WinAVR (also tried with Native)

I am trying communicate with my MCU over UART. I have written two very basic functions over UART to transmit bytes and strings and observing the output on Serial terminal. The project compiles successfully but the string function doesn't work. Someone please help!!

UART_TxString(MOD_UART1,"\nHello");  //This causes MCU to transmit all 0s over the UART port

UART_TxByte(MOD_UART1,'\n');     //This works fine
UART_TxByte(MOD_UART1,'H');     //This works fine
UART_TxByte(MOD_UART1,'e');     //This works fine
UART_TxByte(MOD_UART1,'y');     //This works fine

//Function definitions
void UART_TxByte(sys_module module, uint8_t byte)
{
    switch(module)
    {
        case MOD_UART0:
        {
            while (( UCSR0A & (1<<UDRE0)) == 0) ; // Do nothing until UDR is ready
            UDR0 = byte;
            break;
        }
        case MOD_UART1:
        {
            while (( UCSR1A & (1<<UDRE1)) == 0) ; // Do nothing until UDR is ready
            UDR1 = byte;
            break;
        }
        default:
            break;
    }
    
}

void UART_TxString(sys_module module, char* string)
{
    while(*string)  
    {
        UART_TxByte(module, *string);
        string++;
    }
}

I have worked with Atmega series many times, but this has never happened before. Passing strings to functions (UART/LCD/Wireless Modules) have always worked.

I have also tried to make a global array and put the string contents into it and then pass it to the string function, still it caused same issue.

Update: I figured out a work around for now as given below,

void UART_TxString(sys_module module, char string[])
{
    uint16_t    i=0;
    for(i=0 ; string[i]!=0 ; i++)
    {
        UART_TxByte(module, string[i]);
    }
}

However, with above workaround, I need to load string into the array using sprintf. But if I do this:

char string[] = "hello\r"
UART_TxString(MOD_UART1, string); //  It doesn't work...

Still not able to find out why while(*string) did not work.

5
  • 1
    Is the string pointer pointing to flash memory or to SRAM? Standard pointer dereferences work for pointers to RAM. For reading from flash, you need to run special MCU instructions, and you need to call special functions for those instructions instead of just dereferencing a pointer. Checking the disassembly of the final binary calling UART_TxString() vs the map file should give you the sram vs ram information. Commented Apr 5, 2024 at 2:43
  • @ndim I am declaring normal SRAM arrays, but this has never happened before. I have older projects in Atmel studio with the same code format and it has always worked fine in the same way. Maybe there is some IDE/compiler related setting that has changed and I am not able to figure it out. Commented Apr 5, 2024 at 3:56
  • 1
    char *x has the same semantic like char [] as a function argument btw. fwiw you would rather use const char *x. Maybe you ran out of RAM/stack. WinAVR is v4.3 or older, maybe it's a bug. Cross check the generated assembly. Commented Apr 5, 2024 at 19:16
  • Time to dig into the generated assembly or the disassembly and check which instructions with which address and what is located at that address. Older avr-gcc did have bugs, I ran into one related to uint8_t values in a switch in an endless loop being used to compose a uint16_t but the generated code always set one half of the uint16_t to 0. Might be something similar, just dropping the value altogether. Commented Apr 7, 2024 at 11:59
  • Maybe there is some sort of compiler issue. You use uint8_t for UART_TxByte function but put in a char at the UART_TxString function. Normaly there should be no problem because they are both of the same size (8 bits). This it the only problem i see with the code. Commented Nov 1, 2024 at 20:05

1 Answer 1

0

The only thing in your code where it may run into problems is the datatype char at the UART_TxString function. To check if there is no problem with the type conversion from char to uint8_t you can try the following:

void UART_TxString(sys_module module, char* string)
{
    while(*string)  
    {
        uint8_t temp = (uint8_t)(*string);
        UART_TxByte(module, temp);

        string++;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.