2

When I transmit serial data on an ATmega2560 I sometimes get bit stretching, corrupting the characters: bit stretching in serial data I send character 0x55 twice at a baud rate of 115200; this is the yellow trace in the image. The red trace signals the start and end of the interrupt routine sending the characters.

The first character is fine. The falling edge is the start of the start bit, followed by 8 data bits (LSB to MSB) and then the stop bits (starting at the last rising edge).

The time for the 9 bits (start bit plus 8 data bits) is 78us; consistent with a bit time of 8.68us (115200 baud).

The second character is corrupted: two of the data bits are stretched. The start bit and the other data bits are fine.

This seems to happen randomly.

Is there anything that can cause this?

NZD
  • 345
  • 1
  • 9

1 Answers1

9

The problem is caused by the 'ADC Noise Reduction Mode'. I enter this mode to do ADC conversions: If the ADC is enabled, a conversion starts automatically when this mode is entered. In this mode, some clocks are halted during the ADC conversion.

One of the halted clocks is clkI/O, which is used as the basis for the u(s)art clock. This causes the bit stretching.

You set ADC Noise Reduction Mode in register SMCR (Sleep Mode Control Register). I do this using the following code:

unsigned int volatile adc_data;

// ADC interrupt service routine
ISR(ADC_vect)
{
    /* Read ADC result */
    adc_data = ADCW;
}

// Read the AD conversion result
// with noise canceling
unsigned int read_adc(unsigned char adc_input)
{
    ADMUX=adc_input|ADC_VREF_TYPE;
    /* SM0 bit set is ADC noise reduction (see datasheet) */
    set_sleep_mode(_BV(SM0));
    /* sleep until ADC interrupt */
    sleep_mode();
    return adc_data;
}

The problem went away when I changed the sleep mode call to set_sleep_mode(0);. We then enter Idle Mode instead of ADC Noise Reduction Mode. In this mode, clkI/O is not halted.

But, luckily for us, an ADC conversion also starts automatically when this mode is entered.

I found this on Serial Communication Errors Caused by Noise Reduction Analog-To-Digital Converter

NZD
  • 345
  • 1
  • 9