AVR - ATmega16 - Timer config

Trying to figure out the timer setup in Atmel Studio 6 for an ATmega16 microcontroller. And I just don't get it. I am trying to create a TickCount similar to GetTickCount() Retrieves the number of milliseconds that have elapsed since the system was started, up to 49.7 days.

Code looks like this:

#define F_CPU 8000000UL                         // 8MHz - prevents default 1MHz
// *** timer code necessary for handling lost coms, use volatile when variable is accessed from interrupts
volatile unsigned long TickCountSys;            // Number of milliseconds that have elapsed since the system was started.
volatile unsigned long TickCountComs;           // TickCountForLastComs
volatile unsigned long TCNT0_overflow_count = 0;

ISR(USART_RXC_vect) {
TickCountComs = TickCountSys;               // Milliseconds since system started when received something.
//blah blah
}

void timer_init() {
TIMSK=(1<<TOIE0);                           // Enable timer overflow interrupt for timer0
TCNT0=0x00;                                 // Set timer0 counter initial value to 0
TCCR0 = (1<<CS00);                          // Start timer0 without prescaler
}

ISR(TIMER0_OVF_vect) {
TickCountSys++;
}

int main(void) {
timer_init();
DDRC = 0xff;                                // Set all pins on PORTC for output
sei();
unsigned long TickCountENQ;                 // Tick count for sending enquiry character, 05dec, ^E
char coms = 0;
char ignore_coms = 0;
while(1) {
coms = (TickCountSys < TickCountComs + 50);
if (TickCountSys > TickCountENQ + 25) {
TickCountENQ = TickCountSys;
// If not ignore coms, that is need coms, and has coms, i.e. has not lost coms, then send new Enquiry char every 25 ms
// It stops asking for coms if coms is lost, and does nothing until new command received and then starts syncing again
if (!ignore_coms && coms) USARTWriteChar(0x05);
}
if (!coms && !ignore_coms) {            // If not coms and not ignoring lost coms then stop all movement
PORTC = 0x00;
}
//blah blah...
}
}


Tools-->Device Programming-->Fuses says:

BODLEVEL    4V0
SUT_CKSEL   EXTMEDFXTALRES_16KCK_64MS


As far as I know this is the correct settings (was delivered that way). There is just something I do not understand by reading the timer tutorials.

EDIT: What do I do so that the TickCountSys increases once every milllisecond and gives the number of milliseconds that have elapsed since the system was started?

• ... What was the question again? – Ignacio Vazquez-Abrams Jul 23 '14 at 17:40
• Its not clear what you are trying to do and what you cannot do. – Treesrule14 Jul 23 '14 at 17:53

I am trying to create a TickCount.

You'll need a global variable(big enough) to hold the number of seconds(49.7*24*60*60*1000 = 32bit long value OR a ulong) elapsed, increment it inside your isr( it seems you did this part right !).

volatile uint32_t elapsed_ms;

then you'll need function that returns this value.

uint32_t TickCount(void){
return elapsed_ms;
}


Now we come to part two:
TickCountSys increases once every milli second

If you want to do it with 8MHz Xtal + Timer 0 Overflow, then you cannot achieve precise 1ms ticks. Reason being 8000 clock pulses can not overflow the timer 0. If you use no prescalar then, T0 overflows = 8000/256 = 31.25 times. if you prescale the timer clock with T/8 setting then 1000/256 = 3.90625 close to 4 Overflows.

Assuming that you chose to go ahead with the T/8 pre-scalar, then you'll need to modify the isr body to something like

      static uint8_t temp_count=0;
temp_count++;
if(temp_count >= 4){
temp_count = 0;
elapsed_ms++;
//add a method here to roll the 49.7 day completion.
}


That's it.
From your code it seems you've done the timer and interrupt settings correctly. But your code is quite fuzzy and I failed to locate any function named TickCount or similar.

I'd suggest you to start off with a simple code, like blink a led on timer0 overflow( with a HIGH PRESCALAR value like T/1024). Then gradually add on the code logic. Good Luck.