Electrical – Timer causes UART problem

atmegaavrinterruptstimeruart

I have a problem, found on both ATMEGA1284P and ATMEGA2560.

I have set a 16-bit timer in CTC (tried both Timer1 and Timer5) to give an interrupt every 1ms so I can increment a 32-bit volatile time variable. At the same time, I am sending and receiving data using UART1 and UART2.

This works for some time, however, after exactly 1 min and 6 seconds (~65500 ms ~= 2^16 ms), my UART1 stops working. UART2 and everything else is still working as expected.
When I disable my timer, UART1 keeps working.

I would highly appreciate any help. I have posted my initialization code, let me know if I can provide anything else to find a solution.

UART1 Init code:

#define F_CPU       16000000UL
// (I have also tried disabling the 16 MHz clock and fall back
// to the 8 MHz clock, setting OCR1A to 0x03EF, with no success)

void uart1_init() {
    uint16_t baudrate = UART_BAUD_SELECT(BAUD485, F_CPU));
    UBRR1H = (uint8_t)(baudrate>>8);
    UBRR1L = (uint8_t) baudrate;

    // Clear USART Transmit complete flag, normal USART transmission speed
    UCSR1A = (1 << TXC1) | (0 << U2X1);

    // Enable receiver, transmitter and receive interrupt
    UCSR1B = (1 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1);

    // Asynchronous mode, no parity, 1 stop bit, character size = 8-bit
    UCSR1C = (1 << UCSZ11) | (1 << UCSZ10) | (0 << UCPOL1);
}

// somewhere later: sei();

Timer1 code:

volatile uint32_t time = 0;

void timer_init(void) {
    // This code sets up Timer1 for a 1ms @ 16Mhz Clock (mode 4)
    OCR1A = 0x07CF;
    // Mode 4, CTC on OCR1A
    TCCR1B |= (1 << WGM12);
    // Set interrupt on output compare match
    TIMSK1 |= (1 << OCIE1A);
    // Set prescaler to 8 and start the timer
    TCCR1B |= (1 << CS11) ;
}

ISR(TIMER1_COMPA_vect) {
    // Action to be done every 1 ms
    // Problem also occurs with empty interrupt
    // What I should have here: time++;
}

Best Answer

Check the fuse bits, in ATmega128 I was facing the same problem. For Atmega128 the fuse bits are C4, D9, FF, FF for Low fuse, High Fuse, Extended Fuse and Lock fuse respectively.