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?
Best Answer
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.
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
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.