3
\$\begingroup\$

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?

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

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.

\$\endgroup\$

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.