Rajat
Rajat

Reputation: 1

Unable to transmit a string with atmega2560

I have tried to transmit a character with my atmega2560 (it is on my Arduino board) and it works fine but when it comes to transmit a whole string it went something wrong with it. It is giving me a garbage values which I am unable to solve. I have done all the possible logic according to me but I can't make it out.

void serialSetup(void)
{
    UBRR0H = (BAUD_RATE_CALC >> 8);
    UBRR0L = BAUD_RATE_CALC;
    UCSR0B = (1 << TXEN0)  | (1 << RXEN0);
    UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // 8 bit data format
}

void USART_send(unsigned char data)
{
    while (!(UCSR0A & (1<<UDRE0)))
        /* do nothing */ ;
    UDR0 = data;
}

void USART_putstring(unsigned char* StringPtr)
{
    while (*StringPtr != '\r') {
        USART_send(*StringPtr);
        StringPtr++;
    }
}

int main(void)
{
    serialSetup();
    USART_putstring("rajat\n\r");
    while (1) {
        USART_send('a');
        _delay_ms(1000);
    }
}

Upvotes: 0

Views: 255

Answers (1)

sunriax
sunriax

Reputation: 821

Mybe this solution can help:

void serialSetup(void)
{
    UBRR0H = (BAUD_RATE_CALC >> 8);
    UBRR0L = BAUD_RATE_CALC;
    UCSR0B = (1 << TXEN0)  | (1 << RXEN0);
    UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // 8 bit data format
}

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

void USART_putstring(const char* StringPtr)
{   
    // Every string at the end has a terminator ('\0')
    while (*StringPtr) {
        USART_send((unsigned char)(*StringPtr));
        StringPtr++;
    }
}

int main(void)
{
    serialSetup();
    
    USART_putstring("rajat\n\r"); // e.g. "rajat\n\r\0" has the terminator automatically on the end!
    
    while (1) {
        USART_send((unsigned char)('a'));
        _delay_ms(1000);
    }
}

Note that a ASCII string defined as a char array has a '\0' terminator e.g.:

char string[] = "This is a test";  // contains '\0' at the end
USART_putstring("rajat\n\r");  // contains '\0' at the end

But when every ASCII character is instanciated as a single

character, there is no terminator!
char test[] = { 'T', 'E', 'S', 'T' }; // does not contain '\0' at the end

Also the baudrate can be calculated automatically:

#define F_CPU 12000000UL
#include <util/setbaud.h>

// ...
// Check which bit sampling mode should be activated
#if USE_2X
    UCSRA |= (1<<U2X);      // Setup 8 samples/bit
#else
    UCSRA &= ~(1<<U2X);     // Setup 16 samples/bit
#endif

// Calculated through setbaud.h;
UBRRH = UBRRH_VALUE;
UBRRL = UBRRL_VALUE;
//...

Upvotes: 1

Related Questions