|
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: 
- 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):

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 and frequency correct PWM mode (WGM13:0=8 or 9). This PWM mode generates phase correct PWM and correct frequency because of symmetrical output:
 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:
|