0

I am trying to implement a 16-bit timer overflow interrupt on the ATMEGA168. The idea is to write a message to the UART I/O register when the timer overflows.

I've tested the UART separately and it works fine via RealTerm (baudrate of 9600 bits/s).

I created a base project from https://start.atmel.com/#dashboard where I had to set the input clock frequency to 16MHz to be compatible with the debugger (see page 5). So I would expect to see a 0x1 on my serial terminal every (16x106 / 1024)-1 x 216 = 4.194 seconds.

However, I'm not seeing anything on the terminal regardless of the prescaler I select. Can anyone please advise what could be going wrong?

I have attached the ISR and the main() below:

#include <atmel_start.h>
#include <stdio.h>
#include <usart_basic.h>
#include <atomic.h>
#include <avr/interrupt.h>
#include <avr/io.h>


// timer1 overflow
ISR(TIMER1_OVF_vect) {
    // Send 0x1 over UART
    UDR0 = 0x1;
}
 
int main(void) {
    atmel_start_init();

    // enable timer overflow interrupt for Timer1
    TIMSK1 = (1<<TOIE1); // also tried |= 
    // start 16-bit counter with /1024 prescaler
    TCCR1B = (1 << CS10) | (1 << CS12); // also tried |=
    TCCR1A = 0x0;
    // enable interrupts
    sei(); 

    while(true) {
             // more code here...
    }
}


I have tried to isolate the problem by not writing to UART in the ISR, but just incrementing a counter (declared with the volatile qualifier) and then printing its value to the screen via UART in the while(true) loop. But the counter doesn't increment either and remains stuck at 0.

11
  • But 0x01 is a non printing ASCII SOH character - what are you expecting to see on the terminal? That said, clearly in this case your interrupt us not running in any event. Commented Dec 6, 2022 at 19:46
  • There's an option on RealTerm to interpret incoming messages as uint8, hex, etc. so it doesn't necessarily need to be ASCII. I'm not sure I understand why the interrupt wouldn't run in any event? Commented Dec 6, 2022 at 20:27
  • Is this your real code? It cannot be compiled without errors, please provide a minimal reproducible example with emphasis on complete and reproducible. Are you sure that the ISR is called at all? You could for example just toggle a port pin in it. Commented Dec 6, 2022 at 20:39
  • I've updated it now, thanks. I think the issue is in the ISR as you suggest and not in the UART because I am able to test the UART separately and it works okay @thebusybee Commented Dec 6, 2022 at 21:24
  • A web search on TIMSK1 TOIE1 produces: visualmicro.com/page/Timer-Interrupts-Explained.aspx Do you need to set TCNT1, both at base level to start and within the ISR? From: stackoverflow.com/questions/59802948/… Do you need to write to TIFR1 to clear TOV1? Commented Dec 6, 2022 at 21:56

1 Answer 1

0

You have no USART initialisation code. Specifically you don't enable the transmitter or set the baud rate. I accept that you have tried it with a counter, but that is not the code shown so we can come to no conclusion about its correctness or otherwise.

Without initialisation, the transmitter will not run, and the baud rate will be 1Mbps. Your need at least:

// Set baud rate 9600
uint16_t brr = (FOSC / 16 / 9600) - 1
UBRR0H = (uint8_t)(ubrr >> 8);
UBRR0L = (uint8_t)ubrr;

// Enable transmitter
UCSR0B = (1<<TXEN0);

// Note reset state frame is N,8,1 

I am not convinced that it matters but your timer initialisation order is not idiomatic. You would normally enable the interrupt after setting the prescaler and any other configurations, and to ensure the first period is a complete period, reset the counter to zero immediately before enabling interrupts.

// set up timer with prescaler = 1024
TCCR1B = (1 << CS12) & (1 << CS11);

// initialise counter
TCNT1 = 0;

// enable overflow interrupt
TIMSK = (1 << TOIE1);

// enable global interrupts
sei();

As I said, I am not sure that will fix your problem but the elided part:

while(true) {
         // more code here...
}

may well be the code that is breaking it. You would do well to discount that possibility by disabling or removing any code there temporarily.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.