Xmega Application Note


TC_example.c File Reference


Detailed Description

XMEGA Timer/Counter example source file.

This file contains an example application that demonstrates the Timer/ Counter driver.

Application note:
AVR1306: Using the XMEGA Timer/Counter
Documentation
For comprehensive code documentation, supported compilers, compiler settings and supported devices see readme.html
Author:
Atmel Corporation: http://www.atmel.com
Support email: avr@atmel.com
Revision
1569
Date
2008-04-22 13:03:43 +0200 (ti, 22 apr 2008)

Copyright (c) 2008, Atmel Corporation All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. The name of ATMEL may not be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Definition in file TC_example.c.

#include "avr_compiler.h"
#include "TC_driver.h"

Include dependency graph for TC_example.c:

Go to the source code of this file.

Defines

#define CPU_PRESCALER   1
#define F_CPU   2000000UL

Functions

void Example1 (void)
 This example shows how to configure TCC0 for basic timer operation.
void Example2 (void)
 This function shows how to use the Input Capture functionality.
void Example3 (void)
 This example shows how to configure TCC0 for measurement of Frequency and Duty cycle of a signal applied to PC0.
void Example4 (void)
 This example shows how to configure TCC0 for pulse width modulation output with varying duty cycle on channel A.
void Example5 (void)
 This example shows how to configure TCC0 to count events.
void Example6 (void)
 This example shows how to configure Timer/Counter for 32-bit counting with input capture.
 ISR (TCC0_OVF_vect)
 ISR (TCC0_CCA_vect)
int main (void)


Define Documentation

#define CPU_PRESCALER   1

Definition at line 52 of file TC_example.c.

Referenced by ISR().

#define F_CPU   2000000UL

Definition at line 51 of file TC_example.c.


Function Documentation

void Example1 ( void   ) 

This example shows how to configure TCC0 for basic timer operation.

This function implements example 1, "Basic Timer/Counter Operation" from the "Getting Started" section of application note AVR1306.

Definition at line 86 of file TC_example.c.

References TC0_ConfigClockSource(), and TC_SetPeriod.

Referenced by main().

00087 {
00088         /* Set period/TOP value. */
00089         TC_SetPeriod( &TCC0, 0x1000 );
00090 
00091         /* Select clock source. */
00092         TC0_ConfigClockSource( &TCC0, TC_CLKSEL_DIV1_gc );
00093 
00094         do {
00095                 /* Wait while the timer counts. */
00096         } while (1);
00097 }

Here is the call graph for this function:

void Example2 ( void   ) 

This function shows how to use the Input Capture functionality.

This function implements example 2, "Using the Input Capture Functionality" from the "Getting Started" section of application note AVR1306.

Definition at line 106 of file TC_example.c.

References TC0_ConfigClockSource(), TC0_ConfigInputCapture(), TC0_EnableCCChannels(), TC_GetCaptureA, and TC_GetCCAFlag.

00107 {
00108         uint16_t inputCaptureTime;
00109 
00110         /* Configure PC0 for input, triggered on falling edge. */
00111         PORTC.PIN0CTRL = PORT_ISC_FALLING_gc;
00112         PORTC.DIRCLR = 0x01;
00113 
00114         /* Configure Port D for output. */
00115         PORTD.DIRSET = 0xFF;
00116 
00117         /* Select PC0 as input to event channel 2. */
00118         EVSYS.CH2MUX = EVSYS_CHMUX_PORTC_PIN0_gc;
00119 
00120         /* Configure TCC0 for Input Capture using event channel 2. */
00121         TC0_ConfigInputCapture( &TCC0, TC_EVSEL_CH2_gc );
00122 
00123         /* Enable Input Capture channel A. */
00124         TC0_EnableCCChannels( &TCC0, TC0_CCAEN_bm );
00125 
00126         /* Start timer by selecting a clock source. */
00127         TC0_ConfigClockSource( &TCC0, TC_CLKSEL_DIV1_gc );
00128 
00129          do {
00130                 do {
00131                         /* Wait for Input Capture. */
00132                 } while ( TC_GetCCAFlag( &TCC0 ) == 0 );
00133 
00134                 inputCaptureTime = TC_GetCaptureA( &TCC0 );
00135                 PORTD.OUT = (uint8_t) (inputCaptureTime >> 8);
00136         } while (1);
00137 }

Here is the call graph for this function:

void Example3 ( void   ) 

This example shows how to configure TCC0 for measurement of Frequency and Duty cycle of a signal applied to PC0.

This function implements example 3, "Using Input Capture to Calculate Frequency and Duty Cycle of a Signal" from the "Getting Started" section of application note AVR1306.

Definition at line 147 of file TC_example.c.

References TC0_ConfigClockSource(), TC0_ConfigInputCapture(), TC0_EnableCCChannels(), TC0_SetCCAIntLevel(), and TC_SetPeriod.

00148 {
00149         /* Configure PC0 for input, triggered on both edges. */
00150         PORTC.PIN0CTRL = PORT_ISC_BOTHEDGES_gc;
00151         PORTC.DIRCLR = 0x01;
00152 
00153         /* Select PC0 as input to event channel 0. */
00154         EVSYS.CH0MUX = EVSYS_CHMUX_PORTC_PIN0_gc;
00155 
00156         /* Configure TCC0 for Input Capture using event channel 2. */
00157         TC0_ConfigInputCapture( &TCC0, TC_EVSEL_CH0_gc );
00158 
00159         /* Enable Input "Capture or Compare" channel A. */
00160         TC0_EnableCCChannels( &TCC0, TC0_CCAEN_bm );
00161 
00162         /* Clear MSB of PER[H:L] to allow for propagation of edge polarity. */
00163         TC_SetPeriod( &TCC0, 0x7FFF );
00164 
00165         /* Start timer by selecting a clock source. */
00166         TC0_ConfigClockSource( &TCC0, TC_CLKSEL_DIV1_gc );
00167 
00168         /* Enable CCA interrupt. */
00169         TC0_SetCCAIntLevel( &TCC0, TC_CCAINTLVL_LO_gc );
00170         PMIC.CTRL |= PMIC_LOLVLEN_bm;
00171 
00172         sei();
00173 
00174         do {
00175                 /* Wait while interrupt measure Frequency and Duty cycle. */
00176         } while (1);
00177 }

Here is the call graph for this function:

void Example4 ( void   ) 

This example shows how to configure TCC0 for pulse width modulation output with varying duty cycle on channel A.

This function implements example 4, "Using a Timer/Counter for PWM Generation" from the "Getting Started" section of application note AVR1306.

Definition at line 210 of file TC_example.c.

References TC0_ConfigClockSource(), TC0_ConfigWGM(), TC0_EnableCCChannels(), TC_ClearOverflowFlag, TC_GetOverflowFlag, TC_SetCompareA, and TC_SetPeriod.

00211 {
00212         uint16_t compareValue = 0x0000;
00213 
00214         /* Enable output on PC0. */
00215         PORTC.DIR = 0x01;
00216 
00217         /* Set the TC period. */
00218         TC_SetPeriod( &TCC0, 0xFFFF );
00219 
00220         /* Configure the TC for single slope mode. */
00221         TC0_ConfigWGM( &TCC0, TC_WGMODE_SS_gc );
00222 
00223         /* Enable Compare channel A. */
00224         TC0_EnableCCChannels( &TCC0, TC0_CCAEN_bm );
00225 
00226         /* Start timer by selecting a clock source. */
00227         TC0_ConfigClockSource( &TCC0, TC_CLKSEL_DIV1_gc );
00228 
00229         do {
00230                 /* Calculate new compare value. */
00231                 compareValue += 32;
00232 
00233                 /* Output new compare value. */
00234                 TC_SetCompareA( &TCC0, compareValue );
00235 
00236                 do {
00237                         /*  Wait for the new compare value to be latched
00238                          *  from CCABUF[H:L] to CCA[H:L]. This happens at
00239                          *  TC overflow (UPDATE ).
00240                          */
00241                 } while( TC_GetOverflowFlag( &TCC0 ) == 0 );
00242 
00243                 /* Clear overflow flag. */
00244                 TC_ClearOverflowFlag( &TCC0 );
00245 
00246         } while (1);
00247 }

Here is the call graph for this function:

void Example5 ( void   ) 

This example shows how to configure TCC0 to count events.

This function implements example 5, "Event Counting" from the "Getting Started" section of application note AVR1306.

This example shows how to configure TCC0 to count the number of switch presses for a switch connected to PC0. PD0 is used as output and will be toggled for every 5 switch presses on PC0.

Definition at line 259 of file TC_example.c.

References TC0_ConfigClockSource(), TC0_SetOverflowIntLevel(), and TC_SetPeriod.

00260 {
00261         /* Configure PORTC as input on PC0, sense on falling edge. */
00262         PORTC.PIN0CTRL = PORT_ISC_RISING_gc;
00263         PORTC.DIRCLR = 0x01;
00264 
00265         /* Configure PORTD as output on PD0. */
00266         PORTD.DIRSET = 0x01;
00267 
00268         /* Select PC0 as input to event channel 0, enable filtering. */
00269         EVSYS.CH0MUX = EVSYS_CHMUX_PORTC_PIN0_gc;
00270         EVSYS.CH0CTRL = EVSYS_DIGFILT_8SAMPLES_gc;
00271 
00272         /* Set period ( TOP value ). */
00273         TC_SetPeriod( &TCC0, 4 );
00274 
00275         /* Enable overflow interrupt at low level */
00276         TC0_SetOverflowIntLevel( &TCC0, TC_OVFINTLVL_LO_gc );
00277         PMIC.CTRL |= PMIC_LOLVLEN_bm;
00278 
00279         sei();
00280 
00281         /* Start Timer/Counter. */
00282         TC0_ConfigClockSource( &TCC0, TC_CLKSEL_EVCH0_gc );
00283 
00284         do {
00285                 /* Wait for user input. */
00286         } while (1);
00287 }

Here is the call graph for this function:

void Example6 ( void   ) 

This example shows how to configure Timer/Counter for 32-bit counting with input capture.

This function implements example 6, "Setting up a 32-bit Timer/Counter With Input Capture" from the "Getting Started" section of application note AVR1306.

This example shows how to configure TCC0 and TCC1 for 32-bit Timer/Counter operation with input capture. The overflow from TCC0 is routed through event channel 0 to TCC1. An input capture is triggered by a falling edge on PC0, routed through event channel 1.

Definition at line 309 of file TC_example.c.

References TC0_ConfigClockSource(), TC0_ConfigInputCapture(), TC0_EnableCCChannels(), TC1_ConfigClockSource(), TC1_ConfigInputCapture(), TC1_EnableCCChannels(), TC_EnableEventDelay, TC_GetCaptureA, and TC_GetCCAFlag.

00310 {
00311         uint32_t inputCaptureTime;
00312 
00313         /* Configure PC0 for input, triggered on falling edge. */
00314         PORTC.PIN0CTRL = PORT_ISC_FALLING_gc;
00315         PORTC.DIRCLR = 0x01;
00316 
00317         /* Configure PORTD as output. */
00318         PORTD.DIRSET = 0xFF;
00319 
00320         /* Use PC0 as multiplexer input for event channel 1. */
00321         EVSYS.CH1MUX = EVSYS_CHMUX_PORTC_PIN0_gc;
00322 
00323         /* Use TCC0 overflow as input for event channel 0. */
00324         EVSYS.CH0MUX = EVSYS_CHMUX_TCC0_OVF_gc;
00325 
00326         /*  Configure TCC0 and TCC1 for input capture with event channel 1 as
00327          *  trigger source.
00328          */
00329         TC0_ConfigInputCapture( &TCC0, TC_EVSEL_CH1_gc );
00330         TC1_ConfigInputCapture( &TCC1, TC_EVSEL_CH1_gc );
00331 
00332         /* Enable event delay on TCC1. */
00333         TC_EnableEventDelay( &TCC1 );
00334 
00335         /* Enable input capture channel A on TCC0 and TCC1 */
00336         TC0_EnableCCChannels( &TCC0, TC0_CCAEN_bm );
00337         TC1_EnableCCChannels( &TCC1, TC1_CCAEN_bm );
00338 
00339         /* Use event channel 0 as clock source for TCC1. */
00340         TC1_ConfigClockSource( &TCC1, TC_CLKSEL_EVCH0_gc );
00341 
00342         /* Select system clock as TCC0 clock source. */
00343         TC0_ConfigClockSource( &TCC0, TC_CLKSEL_DIV1_gc );
00344 
00345         do {
00346                 do {
00347                         /* Wait for Input Capture. */
00348                 } while ( TC_GetCCAFlag( &TCC0 ) == 0  );
00349 
00350                 uint16_t highWord = TC_GetCaptureA( &TCC1 );
00351                 uint16_t lowWord = TC_GetCaptureA( &TCC0 );
00352                 inputCaptureTime = ( (uint32_t) highWord << 16 ) | lowWord;
00353 
00354                 PORTD.OUT = (uint8_t) (inputCaptureTime >> 24);
00355 
00356         } while (1);
00357 
00358 }

Here is the call graph for this function:

ISR ( TCC0_OVF_vect   ) 

Definition at line 290 of file TC_example.c.

00291 {
00292         /* Toggle PD0 output after 5 switch presses. */
00293         PORTD.OUTTGL = 0x01;
00294 }

ISR ( TCC0_CCA_vect   ) 

Definition at line 180 of file TC_example.c.

References CPU_PRESCALER, F_CPU, TC_GetCaptureA, and TC_Restart.

00181 {
00182         static uint32_t frequency;
00183         static uint32_t dutyCycle;
00184         static uint16_t totalPeriod;
00185         static uint16_t highPeriod;
00186 
00187         uint16_t thisCapture = TC_GetCaptureA( &TCC0 );
00188 
00189         /*  Save total period based on rising edge and reset counter. */
00190         if ( thisCapture & 0x8000 ) {
00191                 totalPeriod = thisCapture & 0x7FFF;
00192                 TC_Restart( &TCC0 );
00193         }
00194          /* Calculate duty cycle based on time from reset and falling edge. */
00195         else {
00196                 highPeriod = thisCapture;
00197         }
00198 
00199         dutyCycle = ( ( ( highPeriod * 100 ) / totalPeriod ) + dutyCycle ) / 2;
00200         frequency = ( ( ( F_CPU / CPU_PRESCALER ) / totalPeriod ) + frequency ) / 2;
00201 }

int main ( void   ) 

Definition at line 70 of file TC_example.c.

References Example1().

00071 {
00072         Example1();
00073         /*Example2();*/
00074         /*Example3();*/
00075         /*Example4();*/
00076         /*Example5();*/
00077         /*Example6();*/
00078 }

Here is the call graph for this function:

@DOC_TITLE@
Generated on Wed Apr 23 07:45:46 2008 for AVR1306 Using the XMEGA Timer/Counter by doxygen 1.5.5