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\$
  • \$\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 Jun 25 '16 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 Jun 25 '16 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 Jun 25 '16 at 5:26
  • \$\begingroup\$ You should be able to use debugWire to debug the thing, yeah... \$\endgroup\$ – ThreePhaseEel Jun 25 '16 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\$ – Tom Carpenter Jun 25 '16 at 14:01
-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\$
  • 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 Jan 29 '17 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 Jan 29 '17 at 15:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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