ATmega328PB 8-Bit Timer TC0 – Normal Mode

Posted

in

by

The simplest mode of operation is the Normal mode (WGM0[2:0] = 0x0). In this mode, the counting direction is always up (incrementing), and no counter clear is performed. The counter simply overruns when it passes its maximum 8-bit value (TOP=0xFF) and then restarts from the bottom (0x00). In Normal mode operation, the Timer/Counter Overflow flag (TOV0) will be set in the same clock cycle in which the TCNT0 becomes zero. In this case, the TOV0 flag behaves like a ninth bit, except that it is only set, not cleared. However, combined with the timer overflow interrupt that automatically clears the TOV0 flag, the timer resolution can be increased by software. There are no special cases to consider in the Normal
mode, a new counter value can be written any time.

The output compare unit can be used to generate interrupts at some given time. Using the output compare to generate waveforms in Normal mode is not recommended since this will occupy too much of the CPU time.

The counter will always count from 0 to 255 and then after 255 it will set the overflow bit and start the counting from 0.

Without Interrupt

We can use this to generate delays. But This is a type of blocking code.

/*
 * main.c
 *
 * Created: 7/9/2023 12:47:23 AM
 *  Author: abhay
 */ 
#define F_CPU 16000000UL
#include <xc.h>

#include <util/delay.h>
void T0delay();
int main(void)
{
	DDRB |= (1<<5);
	PORTB |= (1<<5);
    while(1)
    {
		PORTB |= (1<<PINB5);
		T0delay();
		PORTB &= ~(1<<PINB5);
                T0delay();
		//TODO:: Please write your application code 
		
    }
}
void T0delay()
{
	/*
	F_CPU/prescaler = clock for timer
	1/clock for timer = timer step time
	for 1 second the timer will take : 1/timer step time
	
	16000000/1024 = 15625 clock
	1/15625 = 0.000064 = 64us	(counter step size)
	64us x 256 = 0.016384 sec (0verflow time)
	64us x 255 - tcnt +1 = 0.016384 sec (0verflow time)
		64us x (255 - tcnt +1 )= x
		tcnt = x / 64us ) -256
		
	for 1 sec Delay
	=> 1/0.016384 sec = 61.03515625
	Taking only integer 
	so 61 overflows needs to occur for 0.999424 Seconds
	1-0.999424 = 0.000576 seconds
	0.000576/ (counter step size) = required steps 
	0.000576/0.00064 = 9 steps
	Note: this will be close to 1 second. but it will be longer due to overhead added by the instructions.
	*/
	for(int i = 0; i< 61;i++){
	TCNT0 = 0;
	TCCR0A = 0;
	TCCR0B |= (1<<CS00)|(1<<CS02);	//prescaler 1024
	while( (TIFR0 & 0x1) == 0);	// Wait for overflow flag
	TCCR0B = 0;
	TIFR0 = 0x1;
	}
	//9 steps timer code
	TCNT0 = 255-9;
	TCCR0A = 0;
	TCCR0B |= (1<<CS00)|(1<<CS02);	//prescaler 1024
	while( (TIFR0 & 0x1) == 0);	// Wait for overflow flag
	TCCR0B = 0;
	TIFR0 = 0x1;
}

Normal Mode with Interrupt

#define F_CPU 16000000UL
#include <xc.h>
#include <avr/interrupt.h>
ISR(TIMER0_OVF_vect){
	PORTB ^= (1<<PINB5);   // Toggle the GPIO
}
int main(void)
{
	
	DDRB |= (1<<5);	// set Data direction to output for PB5
	PORTB |= (1<<5);    // set output to high
	
	TCNT0 = 0;
	TCCR0A = 0;     // Normal Mode
	TCCR0B |= (1<<CS00)|(1<<CS02);	//prescaler 1024
	TIMSK0 |= (1 << TOIE0);	// Overflow Interrupt Enable Bit
	
	sei();	// Enable Global Interrupt
	while(1)
	{
		//TODO:: Please write your application code
		
	}
}

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *