USART Communication problem between ATmega128 and ATSAM3U4E

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

Hello,

 

I am trying to make USART communication between the ATmega128 and ATSAM3U4E.

 

I am sending 10 bytes to ATmega128 from ATSAM3U4E but It receives  8-byte perfectly and then 9th byte is erroneous and It can't receive 10th byte. If I use debug mode with breakpoints, It runs well. It receives all ten bits but when I remove breakpoints, It doesn't receive perfectly. 

 

I could not find out the exact problem with this communication. Please help me to understand this problem better and to find out a solution for this problem.

 

Thank you.

 

* Moved. Ross. *

This topic has a solution.

Dinesh Jinjala

Last Edited: Mon. Jan 9, 2017 - 01:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why did you put this in the Xmega forum?  The "megaAVR and tinyAVR" would be more appropriate.

 

Please post your code for the ATmega128.

 

 

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

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

#define FOSC 16000000// Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1
#define RX_ENABLE	PD5
#define TX_ENABLE	PD4

#define sbi(port, bit) (port) |= (1 << (bit))
#define cbi(port, bit) (port) &= ~(1 << (bit))

void USART_Init( unsigned int ubrr );

void USART_String_receive(void);

unsigned char	USART_Transmit( unsigned char c);
unsigned char USART_Receive( void );
void usart_write_line(volatile const char *string);
volatile unsigned int counter=0;
const char receive_length=10;
unsigned char redata[12];

int main( void )
{

	unsigned char str[7] = "SILICON";

	unsigned char string1[26] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

	unsigned char str2[10] = "Concentrat";
	unsigned char str3[10] = "ABCDEFGHIJ";
	//LED Configuration
	sbi(DDRB, PB6 );
	cbi(PORTB,PB6);

	// Test pin 2
	sbi(DDRC, PC3);
	sbi(PORTC, PC3);
	cbi(PORTC, PC3);
	// RTS AND CTS Configuration

	sbi(DDRD, RX_ENABLE);
	sbi(PORTD,RX_ENABLE);//disable Receive

	sbi(DDRD, TX_ENABLE);
	cbi(PORTD, TX_ENABLE);//disable transmit

	USART_Init ( MYUBRR );

//	sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed

	wdt_disable();

	USART_String_receive();

	usart_write_line(str3);

	USART_String_receive();

	usart_write_line(str2);

	cbi(PORTB,PB6);
	return(0);
}

void USART_Init( unsigned int ubrr )
{
	/* Set baud rate */
	UBRR1H = (unsigned char)(ubrr>>8);
	UBRR1L = (unsigned char)ubrr;
	/* Enable receiver and transmitter */
	UCSR1B = (1<<RXEN)|(1<<TXEN);
	/* Set frame format: 8data, 1stop bit */
	UCSR1C = (0<<USBS)|(3<<UCSZ0);
}

unsigned char	USART_Transmit( unsigned char c)
{
	// Wait for empty transmit buffer
	while ( !( UCSR1A & (1<<UDRE)) )
	;
	// Put data into buffer, sends the data
	UDR1 = c;

	return 0;
}

void usart_write_line(volatile const char *string)
{
	//---------------For Transmit-------------
	sbi(PORTD,RX_ENABLE);
	sbi(PORTD, TX_ENABLE);
	while (*string != '\0')
	{
		USART_Transmit( *string++);
	}

	sbi(PORTD,RX_ENABLE);//disable receive
	cbi(PORTD, TX_ENABLE);//disable transmit

}

void USART_String_receive(void)
{
	int i;

	/*---------------For Receive-------------*/
	cbi(PORTD,RX_ENABLE);
	cbi(PORTD,TX_ENABLE);
	cbi(PORTB, PB6);

	for (i=0; i<10; i++)
	{
		redata[i] = USART_Receive();

	}
	if (redata[0]='W' && redata[1]=='i' && redata[2]=='n' && redata[3]=='n' && redata[4]=='e' && redata[5]=='r' && redata[6]=='T' && redata[7]=='e')
	{
		sbi(PORTB, PB6);
	}
}

unsigned char USART_Receive( void )
{
	// Wait for data to be received
	while ( !(UCSR1A & (1<<RXC)) )
	;
	//Get and return received data from buffer
	return UDR1;
}

Here it is RS485 communication using MAX485. 

Dinesh Jinjala

Last Edited: Tue. Jan 3, 2017 - 09:18 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry for that, I am new to this. I have posted the code for ATmega128.

Dinesh Jinjala

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

I haven't been over all the code but I'm seeing something that doesn't appear correct to me here:

 

void USART_Init( unsigned int ubrr )
{
	/* Set baud rate */
	UBRR1H = (unsigned char)(ubrr>>8);
	UBRR1L = (unsigned char)ubrr;
	/* Enable receiver and transmitter */
	UCSR1B = (1<<RXEN)|(1<<TXEN);
	/* Set frame format: 8data, 1stop bit */
	UCSR1C = (0<<USBS)|(3<<UCSZ0);
}

 

This would be my version:

 

void USART_Init( unsigned int ubrr )
{
	/* Set baud rate */
	UBRR1H = (unsigned char)(ubrr>>8);
	UBRR1L = (unsigned char)(ubrr & 0x00FF);
	/* Enable receiver and transmitter */
	UCSR1B = (1<<RXEN1)|(1<<TXEN1);
	/* Set frame format: 8data, 1stop bit */
	UCSR1C = (0<<USBS1)|(3<<UCSZ10);
}

 

Notice I'm putting the number "1" in places for certain register bits, e.g. RXEN, I've changed to RXEN1 as per the data sheet. Taken from the data sheet there is UCSRnB, where the "n" is the number of the USART used, and in that register there is RXENn, again the "n" is the number of the USART.

 

And what are you using for your clock source. You need accurate timing so a crystal clock source is generally accurate whereas the internal oscillator is not.

 

Keith.

Last Edited: Tue. Jan 3, 2017 - 10:38 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

 

unsigned char str2[10] = "Concentrat";
unsigned char str3[10] = "ABCDEFGHIJ";

       The two strings each have 10 characters.  You need to add space for the string terminating '\0' which is automatically added.

 

if (redata[0]='W'

       The = should be ==

 

 

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

Thank all of you for your corrections. But the problem is not solved.

 

Can anyone suggest me the forum for ATsam3U4E?

Dinesh Jinjala

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

Please answer the question about the clock source used! ???

 

 

 

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

16MHz Crystal.

Dinesh Jinjala

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

The reason it was asked, is an accurate clock is a must for successful serial comms. 

Now we will need the fuse settings to verify this external xtal is actually being used, please.

 

 

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

Dineshro wrote:
I am sending 10 bytes to ATmega128 from ATSAM3U4E...

 

Tell the interface between the two processors...

 

Dineshro wrote:
#define RX_ENABLE PD5 #define TX_ENABLE PD4

I'm guessing RS485.  [lol--scrolling down to make the quote I see that now...]

 

I don't know what toolchain and such you are using on the SAM side.  If it is an AVR8, then the usual cause of your problem is that the sender is turning off TX when UDRE fires and all bytes have been given to the USART.

 

But you are not yet done -- the USART has that last byte or two buffered up and they are not yet sent.  One needs to wait for TXC before turing off TX.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

You have a return(0) at the end of main. Where does it return to? The answer is nowhere. Put a dead loop at the end - before the return.
As Lee suggests, not waiting for the usart to complete means you lose the last character. You can use your soundcard in the PC as an oscilloscope so you can observe what is really happening. Google soundcard oscilloscope.

Last Edited: Tue. Jan 3, 2017 - 09:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, I am using RS485 communication. This is a code for ATSAM3U4E side. When I put a breakpoint at  USART_Receieve_SYNC(10); in the main function and after I run this code then this works well. If I put a delay before  USART_Receieve_SYNC(10); about 1ms(millisecond) then also it works well. 

If I remove breakpoint and remove delay also then ATmega128 still will be in Receive mode.

#include "RS485Controller.h"
#include "usart.h"
#include "pdc.h"
#include "sysclk.h"
#include "gpio.h"
#include "delay.h"

/** State of the USART. */
typedef enum st_usart_state {
    INITIALIZED,
    TRANSMITTING,
    RECEIVING,
    RECEIVED,
    TRANSMITTED
} usart_state_t;

/** Global usart state. */
volatile usart_state_t g_state = INITIALIZED;

uint8_t txBuffer[9]= "EinsteinD";
uint8_t rxBuffer[50];
uint8_t SYNC_CHAR[14]="WinnerTechnolo";
uint8_t ACK_CHAR='%';
uint8_t RECEIVED_char[50];

/**
 *  \brief Handler for USART interrupt.
 *
 */

void USART_Handler(void)
{

    uint32_t ul_status;

     // Read USART status.
    ul_status = usart_get_status(BOARD_RS486_USART);

     // Receiving interrupt.
    if ((ul_status & US_CSR_ENDRX) && (g_state == RECEIVING))
    {
        // Indicate receiving finished.
        g_state = RECEIVED;
        usart_disable_interrupt(BOARD_RS486_USART, US_IDR_ENDRX);
    }
    //  Transmitting interrupt.
    else if ((ul_status & US_CSR_ENDTX) && g_state == TRANSMITTING)
    {
        // Transmit continuously.
        usart_disable_interrupt(BOARD_RS486_USART, US_IDR_ENDTX);
        g_state = TRANSMITTED;
    }

}

/** Initilize the BLDC controller RS485 interface  **/
void InitRS485Controller(void)
{

   // USART RS485 mode configuration.
   // Configure USART in RS485 mode, asynchronous, 8 bits, 2 stop bit,
   // no parity, 19200 bauds and enable its transmitter and receiver.
   const sam_usart_opt_t usart_console_settings = {
        BOARD_RS485_BAUDRATE,
        US_MR_CHRL_8_BIT,
        US_MR_PAR_NO,
        US_MR_NBSTOP_1_BIT,
        US_MR_CHMODE_NORMAL,
        /* This field is only used in IrDA mode. */
        0
    };

    /* Enable the peripheral clock in the PMC. */
    sysclk_enable_peripheral_clock(BOARD_RS485_ID_USART);

    /* Configure USART in RS485 mode. */
    usart_init_rs485(BOARD_RS486_USART, &usart_console_settings,sysclk_get_cpu_hz());

    /* Disable all the interrupts. */
    usart_disable_interrupt(BOARD_RS486_USART, ALL_INTERRUPT_MASK);

    /* Enable TX & RX function. */
    usart_enable_tx(BOARD_RS486_USART);
    usart_enable_rx(BOARD_RS486_USART);

    /* Configure and enable interrupt of USART. */
    NVIC_EnableIRQ(RS485_USART_IRQn);

    /** Default mode is sleep mode for MAX485 **/
    gpio_set_pin_low(PIN_USART3_RTS_IDX);//Receive enable pin of 485 IC
    gpio_set_pin_high(PIN_USART3_CTS_IDX);//Transmit enable pin of 485 IC

}

void USART_Send_SYNC(unsigned int char_length)
{
    unsigned int i_index;
    unsigned int success[char_length];

    // make changes in RTS and CTS pins for transmit
    gpio_set_pin_high(PIN_USART3_RTS_IDX);
    gpio_set_pin_high(PIN_USART3_CTS_IDX);

    // Enable tx and disable rx
    usart_enable_tx(BOARD_RS486_USART);
    usart_disable_rx(BOARD_RS486_USART);

    for (i_index=0; i_index < char_length; i_index++)
    {

        success[i_index]=usart_putchar(BOARD_RS486_USART, SYNC_CHAR[i_index]);		

    }

}

void USART_Receieve_SYNC(uint32_t strlength )
{
    unsigned char strl;

    // make changes in RTS and CTS pins for transmit
    gpio_set_pin_low(PIN_USART3_RTS_IDX);
    gpio_set_pin_low(PIN_USART3_CTS_IDX);

    // disable tx and enable rx

    usart_disable_tx(BOARD_RS486_USART);
    usart_enable_rx(BOARD_RS486_USART);

    for(strl=0;strl<strlength;strl++)
    {

        while(!(usart_is_rx_ready(BOARD_RS486_USART)))
        {
        }
        usart_read(BOARD_RS486_USART, &RECEIVED_char[strl]);
    }

    gpio_set_pin_high(LED0_GPIO);
    gpio_set_pin_high(LED1_GPIO);

}

/*********************************main.c***************************************/
#include <asf.h>
#include "RS485Controller.h"

int main (void)
{

        /* Initialize the SAM system */
    sysclk_init();

    /* Insert system clock initialization code here (sysclk_init()). */
    board_init();

    /* Insert application code here, after the board has been initialized. */
    InitRS485Controller();

    gpio_set_pin_low(LED0_GPIO);
    gpio_set_pin_low(LED1_GPIO);

    USART_Send_SYNC(14);

    USART_Receieve_SYNC(10);

        while(1)
        {
            gpio_set_pin_high(LED1_GPIO);
            gpio_set_pin_low(LED0_GPIO);
        }

}

 

    USART_Receieve_SYNC(10);

Dinesh Jinjala

Last Edited: Thu. Jan 5, 2017 - 02:06 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Concentrate on getting one end to work first. Have you made the suggested changes on the AVR end and validated the result?

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

Yes , I have those changes but still problem is same. 

Dinesh Jinjala

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
void usart_write_line(volatile const char *string)
{
	//---------------For Transmit-------------
	sbi(PORTD,RX_ENABLE);
	sbi(PORTD, TX_ENABLE);
	while (*string != '\0')
	{
		USART_Transmit( *string++);
	}

	sbi(PORTD,RX_ENABLE);//disable receive
	cbi(PORTD, TX_ENABLE);//disable transmit

}

TX is disabled 2 bytes too early (UDR still holds previously written characters).

 

You have to also flush transmit buffer before entering `USART_Receive_SYNC()`

Last Edited: Thu. Jan 5, 2017 - 08:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have similar errors in the SAM code, so that suggests you haven't corrected the problems.

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

I didn't understand what you want to say so, please elaborate what you want to say.

void usart_write_line(volatile const char *string)
{
	unsigned int i_index;
	//---------------For Transmit-------------
	sbi(PORTD,RX_ENABLE);
	sbi(PORTD, TX_ENABLE);
	for (i_index=0; i_index < 10;i_index++)
	{
		USART_Transmit( string[i_index]);	
	}
		
	
	
//	sbi(PORTD,RX_ENABLE);//disable receive
//	cbi(PORTD, TX_ENABLE);//disable transmit
	
}

 

Dinesh Jinjala

Last Edited: Fri. Jan 6, 2017 - 04:38 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please, Can you point out the errors?

 

Thank you in advance.

Dinesh Jinjala

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

jnk0le and Kartman are telling you that your code for both the ATSAM3U4E and the ATmega128, when

transmitting, is setting the RS485 transceiver to receive before the last two characters have been transmitted.

 

This is because the USART in both chips is "double buffered":  There is the transmit buffer which then feeds the

transmit register.

 

The following is from the main() for the SAM chip:

    USART_Send_SYNC(14);

    USART_Receieve_SYNC(10);

USART_Send_SYNC(14) sets the RS485 to transmit, writes 14 characters to the USAART transmit buffer and immediately terminates.

 

USART_Receieve_SYNC(10) immediately sets the RS485 to receive - while the last two characters are still in the transmit buffer and transmit register.

 

This is the error!

 

You need to add code at the end of USART_Send_SYNC(...) to wait until the transmit register is empty.

 

You need to do the same with the code in the ATmega128.

 

 

Last Edited: Fri. Jan 6, 2017 - 05:28 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
uint8_t txBuffer[9]= "EinsteinD";
uint8_t rxBuffer[50];
uint8_t SYNC_CHAR[14]="WinnerTechnolo";

should be

uint8_t txBuffer[]= "EinsteinD";
uint8_t rxBuffer[50];
uint8_t SYNC_CHAR[]="WinnerTechnolo";

C terminates strings with a 0 value so it can find the end of the string. You didn't allow for this when you declared your arrays.

If you use your sound card as I suggested, you would be able to see the data that is being sent and verify that it is correct.

 

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

Thank you, sir. The problem is solved. But can you please tell me how you come to know that exactly 2 bytes are still in transmit buffer? 

I want to know the logic for that. Please tell me, I new student to this type of programming. 

Thank you all of you. 

 

 

 

Best Regards,

Dinesh Jinjala

Dinesh Jinjala

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

Dineshro wrote:
Thank you, sir. The problem is solved. But can you please tell me how you come to know that exactly 2 bytes are still in transmit buffer? I want to know the logic for that. Please tell me, I new student to this type of programming.

Have you looked at the datasheet?

 

For the AVR, look for UDRE and TXC, along with the diagram(s) and description of transmitting.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Yes, Now I understand everything well. 

 

Thank you. It is a great fun to learn in this way. Thank you for sharing your knowledge. 

 

 

Best regards,

 

Dinesh Jinjala

Dinesh Jinjala

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

Now I have changed my code for ATmega128. Here, communication between ATSAM3U4E and ATmega128 is perfect for the first time. If I switch on both boards then communication is successful but when I keep the switch on ATmega128 board and only switch off ATSAM3U4E then problem arise in the receiving of the ATSAM3U4E when I switch it on. That board receive only 8 bit,  But when I put a delay in usart_write_line(), it works well.

 Can anyone tell me the reason for that?

 

#include <avr/io.h>
#include <string.h>
#include <avr/wdt.h>
#ifndef F_CPU
# define F_CPU 16000000UL
#endif

#include <util/delay.h>

#define FOSC 16000000// Clock Speed
#define BAUD 19200
#define MYUBRR FOSC/16/BAUD-1

#define RX_ENABLE	PD5
#define TX_ENABLE	PD4

#define sbi(port, bit) (port) |= (1 << (bit))
#define cbi(port, bit) (port) &= ~(1 << (bit))

#define IDLE 1
#define RS_485 2
#define TCS_ERROR 3

void USART_Init( unsigned int ubrr );
//void USART_Transmit( unsigned char data );
void USART_String_receive(void);
//void usart_write_line(unsigned char array[],unsigned char num_cha);
void processcommand(void);

unsigned char	USART_Transmit( unsigned char c);
unsigned char USART_Receive( void );
void usart_write_line(volatile const char *string);
volatile unsigned int counter=0;
const char receive_length=10;
unsigned char redata[20];
unsigned char RS_485_Data[20];
static unsigned char Command_status;

unsigned char str[7] = "SILICON";

unsigned char string1[26] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

unsigned char str2[10] = "Concentrat";
unsigned char str3[10] = "ABCDEFGHIJ";
int main( void )
{

    //LED Configuration
    sbi(DDRB, PB6 );
    cbi(PORTB,PB6);

    // Test pin 2
    sbi(DDRC, PC3);
    sbi(PORTC, PC3);
    cbi(PORTC, PC3);
    // RTS AND CTS Configuration

    sbi(DDRD, RX_ENABLE);
    sbi(PORTD,RX_ENABLE);//disable Receive

    sbi(DDRD, TX_ENABLE);
    cbi(PORTD, TX_ENABLE);//disable transmit

    USART_Init ( MYUBRR );

//	sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed

    wdt_disable();
// Enable Receive mode
    cbi(PORTD,RX_ENABLE);
    cbi(PORTD,TX_ENABLE);

    //STARTED ADDED PORTION
    while(1)
    {
        processcommand();
    }
    //ENDED ADDED PORTION
    cbi(PORTB,PB6);
    return(0);

}

void USART_Init( unsigned int ubrr )
{
    /* Set baud rate */
    UBRR1H = (unsigned char)(ubrr>>8);
    UBRR1L = (unsigned char)(ubrr & 0x00FF);
    /* Enable receiver and transmitter */
    UCSR1B = (1<<RXEN1)|(1<<TXEN1);
    /* Set frame format: 8data, 1stop bit */
    UCSR1C = (0<<USBS1)|(3<<UCSZ10);

    Command_status=IDLE;
}

unsigned char	USART_Transmit( unsigned char c)
{
    // Wait for empty transmit buffer
    while ( !( UCSR1A & (1<<UDRE1)) )
    ;
    // Put data into buffer, sends the data
    UDR1 = c;

    return 0;
}

void usart_write_line(volatile const char *string)
{
    unsigned int i_index;
    //---------------For Transmit-------------
    sbi(PORTD,RX_ENABLE);
    sbi(PORTD, TX_ENABLE);
    for (i_index=0; i_index < 10;i_index++)
    {
        USART_Transmit( string[i_index]);

    }

    while ( !( UCSR1A & (1<<TXC1)) )
    {

    }
    _delay_us(1000);
}

void USART_String_receive(void)
{
    int i;

    /*---------------For Receive-------------*/
    cbi(PORTD,RX_ENABLE);
    cbi(PORTD,TX_ENABLE);

    for (i=0; i<14; i++)
    {
        redata[i] = USART_Receive();

    }

}

unsigned char USART_Receive( void )
{
	// Wait for data to be received 
	while ( !(UCSR1A & (1<<RXC1)) )
	;
	//Get and return received data from buffer 
	return UDR1;
}


void processcommand(void)
{
    if (Command_status==RS_485)
    {
        usart_write_line(str2);
        //Enable receive mode
        cbi(PORTD,RX_ENABLE);
        cbi(PORTD,TX_ENABLE);
    }
    else if (Command_status==TCS_ERROR)
    {
        usart_write_line(str3);
        //Enable receive mode
        cbi(PORTD,RX_ENABLE);
        cbi(PORTD,TX_ENABLE);
    }
    Command_status=IDLE;
    if ((UCSR1A & (1<<RXC)))
    {
        RS_485_Data[counter]=USART_Receive();
        counter++;
        if (counter==14)
        {
            counter=0;
            if (RS_485_Data[0]=='W' && RS_485_Data[1]=='i' && RS_485_Data[2]=='n' && RS_485_Data[3]=='n' && RS_485_Data[4]=='e' && RS_485_Data[5]=='r' && RS_485_Data[13]=='o' )
            {
                Command_status=RS_485;
            }
            else
            {
                Command_status=TCS_ERROR;
            }
        }
    }

    if (Command_status != TCS_ERROR && Command_status != IDLE)
    {
        _delay_us(1000);
    }
} 

 

Dinesh Jinjala

Last Edited: Mon. Jan 9, 2017 - 04:43 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I repeat for the third time:

You can use your soundcard in the PC as an oscilloscope so you can observe what is really happening. Google soundcard oscilloscope.

If you have a real oscilloscope - use that, or a logic analyser like a Saleae Logic.

 

Your code needs a means to synchronise the data - don't expect that you'll get 14 bytes properly aligned each time. What happens if you get an error? Which is probably what is happening when you start the other board up.

You need a means of determining the start of your string and the end. You probably also what a means of detecting errors.

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

Yellow graph is the TXD line and Blue is for TX ENABLE Line. 

This graph is without _delay_us(1000);.

 

Dinesh Jinjala

Last Edited: Mon. Jan 9, 2017 - 08:34 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This graph is with using _delay_us(1000);

Dinesh Jinjala

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

It's pretty obvious what the problem is - what we told you earlier on. You're not waiting until all the characters have been sent. You shouldn't need to use a delay if you write the code correctly.

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

But I have waited by this loop.

    while ( !( UCSR1A & (1<<TXC1)) )
    {

    }

 

Dinesh Jinjala

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1
how many times do we have to tell you this is not correct:
unsigned char str[7] = "SILICON";

 

 

Well something is not quite right then is it? Since you have a real oscilloscope, why not toggle some port pins in patterns at various points in the code so you can locate where the problem is. I'd probably toggle one port pin when each character is sent.

 

Last Edited: Mon. Jan 9, 2017 - 10:07 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

TXC flag have to be cleared by writing logical '1' before starting transmission.

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

Well, if you have intitialized strings, and are sure their length will be kept smaller than the initial one , best -as counting is tedious and can lead to overflows if omitting the necessary \0 - is to be lazy :

char str[]="Compiler will manage to find out its size ";

is very comfortable (and you have to change once, without efforts, if you want to change strings -translations, say-)

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

Thanks, a problem is solved.

 

Dinesh Jinjala

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

Yes, You are right but my posted code is practice code. I really wanted to send commands to ATmega8 to run, to stop, to measure a current of BLDC or many other functions. So through USART I have to send fixed amount of data.  

Dinesh Jinjala