0
\$\begingroup\$

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++;
}
\$\endgroup\$
9
  • \$\begingroup\$ Do you have a debugger that you can use to pull the register values of the UART before and after the error state? \$\endgroup\$
    – Daniel
    Commented Jun 25, 2016 at 5:11
  • \$\begingroup\$ Unfortunately not with my hardware no. Both are custom built PCBs with ISP only. (or is that possible with ISP and I'm unaware of it?) I might be able to transmit the values over the working USART2. I will try that later and report back. \$\endgroup\$
    – Johis
    Commented Jun 25, 2016 at 5:16
  • \$\begingroup\$ Possibly/probably? I haven't used AVR in a while, but the one-wire debug was always a big bonus. \$\endgroup\$
    – Daniel
    Commented Jun 25, 2016 at 5:26
  • \$\begingroup\$ You should be able to use debugWire to debug the thing, yeah... \$\endgroup\$ Commented Jun 25, 2016 at 6:09
  • 1
    \$\begingroup\$ Probably more like it stops after exactly 65535ms, which implies something is overflowing somewhere. We need to see the rest of your code - the problem does not lie with what you have shown us. \$\endgroup\$ Commented Jun 25, 2016 at 14:01

1 Answer 1

-1
\$\begingroup\$

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.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ How do these fuse settings relate to the problem at hand? Without an explanation, this is little more than a comment. \$\endgroup\$
    – Dave Tweed
    Commented Jan 29, 2017 at 12:59
  • \$\begingroup\$ I can also not see how the fuses should have been the problem. As you can see above, I "solved" the problem by changing to another (identical) ATMEGA chip. However, I still have no idea what caused the problem. The fuses I have changed from non stock are: remove CKDIV8, BOD to 4.3V, enable external crystal and disable JTAG. \$\endgroup\$
    – Johis
    Commented Jan 29, 2017 at 15:18

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.