Main Menu
Home
AVR News
Atmel AVR
AVR Development Tools
Valuable Tools
WinAVR toolset
Makefile for WinAVR
AVR Virtual Simulators
Hardware for prototyping
GCC and AVR-GCC
Short introduction to C
AVR-GCC Tutorial
Example AVR Projects
AVR-GCC articles
WinAVR Site Map
ScienceProg BLOG
Disclaimer
WinARM Tutorial
Latest comments
Measuring motor speed and...
Dear Administrator The code above...
More...

Programming AVR ADC module...
hi please send me example usart with...
More...

Measuring motor speed and...
main.c: In function...
More...

Running TX433 and RX433 RF...
(Hopefully this is not a re-post). I am...
More...

Running TX433 and RX433 RF...
I just bnought a pair of the RX/TX 433...
More...

Friendly sites

Related Items:

Recommended sites


Program 16 bit AVR timer with WinAVR PDF Print E-mail
Written by Administrator   
Monday, 16 October 2006
Last Updated ( Monday, 16 October 2006 )

AVR 16 bit timer is more advanced timer than 8 bit timer.  It has more features and this allows more accurate program execution timing. 16 bit timer is used when precise signal generation or signal timing measurement needed. As 8 bit timer counter can calculate up to 225 counts the 16 bit timer counter maximum value may reach 65535. In AVR microcontrollers 16 bit timer is Timer1. It contains a 16 bit input capture register (ICR1) and two 16 bit output compare registers (OCR1A and OCR1B). Of course the timer counters register (TCNT1) which is 16 bit long. When programming is ASM language there is special procedure for accessing it (refer to datasheet). While in C language it is done automatically we won’t get to deep into this. Timer1 is controlled by two timer counter control registers (TCCR1A/B). Signals are visible at timer interrupt flag register (TIFR) and interrupts can be individually masked in timer interrupt mask register (TIMSK).

Few words about prescaler. As timer counter is a binary counter it has a prescaler like other timers in AVR microcontrollers. Prescaler may be selected in TCCR1B with bits CS12, CS11 and CS10 like in 8 bit timers.

Lets us go through timer1 modes to clear things out.

Input capture mode

This mode is usually used for measuring of time interval between two events like measuring pulse width. This is done by capturing time event at the beginning and at the beginning of the event. They are subtracted from each other to find how long event lasted. For this task input capture register is used ICR1. Signal is captured using input capture pin (ICP). In a TCCR1B bit ICES1. Input capture mode has also noise canceling feature. Bu setting bit ICNC1 in TCCR1B register will activate this. Noise canceller helps to avoid spikes in the input. It simply waits for low or high signal for four clock cycles.

When input capture has occurred the interrupt is generated, so the interrupt service routine has to determine that was first or second capture and store ICR1 data to some memory because after second capture data will be overwritten.

Let’s say wee want to measure positive signal width using Atmega8 microcontroller.

 

#include <avr\io.h>

#include <avr\interrupt.h>

#include <avr\iom8.h>

#define ICP PINB0

//define ovrflow counter

uint16_t ov_counter;

//define times for start and end of signal

uint16_t rising, falling;

//define overall counts

uint32_t counts;

//overflow counter interrupts service routine

ISR(TIMER1_OVF_vect){

  ov_counter++;

}

//Timer1 capture interrupt service subroutine

ISR(TIMER1_CAPT_vect){

/*This subroutine checks was it start of pulse (rising edge)

or was it end (fallingedge)and performs required operations*/

if (ICP) //if high level

            {

            //save start time

            rising=ICR1;

            //set to trigger on falling edge

            TCCR1B=TCCR1B&0xBF;

            //reset overflow counter

            ov_counter=0;

   }

else

            {

            //save falling time

            falling=ICR1;

            //rising edge triggers next

            TCCR1B=TCCR1B|0x40;

            counts=(uint32_t)falling-(uint32_t)rising+(uint32_t)ov_counter;

            /*you can convert coutns to seconds and send to LCD*/

            }

}

int main(void) {

//enable overflow and input capture interrupts

TIMSK=0x24;

/*Noise canceller, without prescaler, rising edge*/

TCCR1B=0xC1;

sei();

    for (;;) {

/* loop forever timer does the job*/

 

    }

}

 

 

Timer output compare mode

Output compare mode is like anti-input capture mode. This mode is able to generate varying frequency and symmetry signals. This may be used to generate music sounds and so on.

Output compare mode is controlled by TCCR1A register. It can control two pins of microcontroller OC1A and OC1B. They may be left unaffected, toggled, set or cleared. Regarding to bits settings in TCCR1A register. Output compare mode on compare match can generate an interrupt. Interrupt service routine may be used to calculate the OCR1A value.

There are several of output compare modes (selecting bits WGM13:0 in TCCR1A register):

  • Normal mode (WGM13:0=0). Is used to generate interrupts as some given time also as overflow interrupts.
  • Clear timer on compare match (WGM13:0=4 or 12). The OCR1A or ICR1 Register are used to control counter resolution. In CTC mode the counter is cleared to zero when the counter value (TCNT1) matches either the OCR1A (WGM13:0 = 4) or the ICR1 (WGM13:0 = 12). The OCR1A or ICR1 define the top value for the counter, hence also its resolution. This mode allows greater control of the Compare Match output frequency.

 

#include <avr\io.h>

#include <avr\interrupt.h>

#include <avr\iom8.h>

#define OCP PINB1

/*This example demonstrates how 1kHz signal

can be generated using timer and compare match interrupt

if F_CPU=1MHz, then 1 clk is 1us. For 1kHz signal

there is 1000clk=1000us. For toggling ponts = 500clk

*/

//Output compare ISR

ISR(TIMER1_COMPA_vect){

  OCR1A+=500;

}

int main(void) {

//Set PORTB1 pin as output

DDRB=(1<<OCP);

//Output compare toggles OC1A pin

TCCR1A=0x40;

//start timer without prescaler

TCCR1B=0x01;

//enable output compare interrupt for OCR1A

TIMSK=0x10;

 

sei();

    for (;;) {

/* loop forever timer does the job*/

 

    }

}

 

results:

Output compare signal generation

 

  • Fast PWM mode (WGM13:0=5, 6, 7, 14 or 15). This mode is used to provide high frequency PWM. It’s a single slope generation. The PWM resolution for fast PWM can be fixed to 8-, 9-, or 10-bit, or defined by either ICR1 or OCR1A. The minimum resolution allowed is 2-bit (ICR1 or OCR1A set to 0x0003), and the maximum resolution is 16-bit (ICR1 or OCR1A set to MAX):

Fast PWM

 Phase correct PWM mode (WGM13:0=1, 2, 3, 10 or 11). It is dual slope mode. Resolution can be selected between 8, 9, 10 bits or defined by ICR1 or OCR1A. The output is phase correct, but unsymmetrical:

Phase Correct PWM

 

  • Phase and frequency correct PWM mode (WGM13:0=8 or 9). This PWM mode generates phase correct PWM and correct frequency because of symmetrical output:
Phase and Frequency correct PWM

Example bellow shows how correct phase and frequency PWM duty cycle can be controlled using two buttons connected to PIND0 and PIND1:

 

#include <avr\io.h>

#include <avr\iom8.h>

int main(void) {

//Port D pins as input

DDRD=0x00;

//Enable internal pull ups

PORTD=0xFF;

//Set PORTB1 pin as output

DDRB=0xFF;

//

OCR1A=76;

//Output compare OC1A 8 bit non inverted PWM

TCCR1A=0x91;

//start timer without prescaler

TCCR1B=0x01;

    for (;;) {

if(bit_is_clear(PIND, 0))           {

//increase duty cycle

             OCR1A+=10;

loop_until_bit_is_set(PIND, 0);

            }

if(bit_is_clear(PIND, 1))           {

//decease duty cycle

            OCR1A-=10;

loop_until_bit_is_set(PIND, 1);

            }

    }

}

Download example projects ready to run with VMLAB simulation tools from here


Related Items:

   

Users' Comments  
 

Average user rating

 


Add your comment
Only registered users can comment an article. Please login or register.

No comment posted



mXcomment 1.0.6 © 2007-2010 - visualclinic.fr
License Creative Commons - Some rights reserved
< Prev   Next >

© 2010 WinAVR AVR-GCC Tutorial
Joomla! is Free Software released under the GNU/GPL License.