Xmega Application Note


TC_example.c

Go to the documentation of this file.
00001 /* This file has been prepared for Doxygen automatic documentation generation.*/
00050 /* Definition of the CPU clock speed and TC prescaler setting. */
00051 #define F_CPU           2000000UL
00052 #define CPU_PRESCALER   1
00053 
00054 #include "avr_compiler.h"
00055 #include "TC_driver.h"
00056 
00057 /* Prototyping of functions. */
00058 void Example1( void );
00059 void Example2( void );
00060 void Example3( void );
00061 void Example4( void );
00062 void Example5( void );
00063 void Example6( void );
00064 
00065 
00066 /* \brief This is the main function for executing one of the examples.
00067  *
00068  *  Uncomment one of the function calls to show the example.
00069  */
00070 int main( void )
00071 {
00072         Example1();
00073         /*Example2();*/
00074         /*Example3();*/
00075         /*Example4();*/
00076         /*Example5();*/
00077         /*Example6();*/
00078 }
00079 
00080 
00086 void Example1( void )
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 }
00098 
00099 
00106 void Example2( void )
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 }
00138 
00139 
00147 void Example3( void )
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 }
00178 
00179 
00180 ISR(TCC0_CCA_vect)
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 }
00202 
00203 
00210 void Example4( void )
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 }
00248 
00249 
00259 void Example5( void )
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 }
00288 
00289 
00290 ISR(TCC0_OVF_vect)
00291 {
00292         /* Toggle PD0 output after 5 switch presses. */
00293         PORTD.OUTTGL = 0x01;
00294 }
00295 
00296 
00309 void Example6( void )
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 }
@DOC_TITLE@
Generated on Wed Apr 23 07:45:44 2008 for AVR1306 Using the XMEGA Timer/Counter by doxygen 1.5.5