Main Page | File List | Globals

main.c

Go to the documentation of this file.
00001 // This file has been prepared for Doxygen automatic documentation generation.
00060 #if __GCC__
00061 #include <avr/io.h>
00062 #include <avr/signal.h>
00063 #include <avr/interrupt.h>      /* sei */
00064 #define SEI()   sei()
00065 #define CLI()   cli()
00066 #define SLEEP() __asm__ __volatile__ ("sleep \r\n" :: )
00067 #else /* IAR */
00068 #include <stdio.h>
00069 #include <inavr.h>
00070 #define ENABLE_BIT_DEFINITIONS
00071 #include <iom64.h>
00072 #define SEI()   asm("SEI")
00073 #define CLI()   asm("CLI")
00074 #define SLEEP() asm("SLEEP")
00075 #endif
00076 
00077 #include "icp.h"
00078 
00079 /*
00080  * LED debug definitions (ATmega64).
00081  * The current detected PWD duty cycle is displayed on PC[7:0]
00082  */
00083 #define LED_DEBUG_DDR   DDRC
00084 #define LED_DEBUG_PORT  PORTC
00085 
00092 unsigned char hb_count;                 /* counts [0:4] to make the test visible */
00093 #if __GCC__
00094 SIGNAL(SIG_OVERFLOW0)
00095 #else
00096 #pragma vector=TIMER0_OVF_vect
00097 __interrupt void TIMER0_OVF(void)
00098 #endif
00099 {
00100         if (++hb_count >= 4)    /* apx 0.25 seconds */
00101         {
00102                 /*
00103                  * Clear the post-scale counter
00104                  */
00105                 hb_count = 0;
00106 
00107                 /*
00108                  * Update the duty cycle (OCR2). The result is allowed
00109                  * to overflow back to 0 to restart the run.
00110                  */
00111                 OCR2 += 1;
00112         }
00113         return;
00114 }
00115 
00128 void
00129 hb_init(void)
00130 {
00131         /*
00132          * The heartbeat timer (timer0) is used in free-running mode.
00133          */
00134         ASSR = 0;       /* AS0 = 0 */;  /* disable asynchronous mode */
00135         while (ASSR) /*EMPTY*/;
00136         TCCR0 = (1 << CS02) | (1 << CS01) | (1 << CS00); /* prescale /1024 */
00137         TIMSK |= (1 << TOIE0);                          /* enable overflow interrupt */
00138 
00139         return;
00140 }
00141 
00150 void
00151 pwm_init(void)
00152 {
00153         /*
00154          * Set up PWM using timer2
00155          */
00156         DDRB |= (1 << PB7);             /* enable PWM (OC2) output pin */
00157         OCR2 = 0;                               /* start at 0% */
00158         TCCR2 = (1 << WGM21) | (1 << WGM20)     /* fast PWM */
00159                   |     (1 << COM21) | (0 << COM20)             /* non-inverted PWM */
00160                   |     (0 << CS22)  | (1 << CS21) | (1 << CS20)  /* prescale /64       */
00161                         ;
00162         return;
00163 }
00164 
00170 int
00171 main(void)
00172 {
00173         icp_sample_t sample;
00174 
00175         /*
00176          * Init subsystems
00177          */
00178         hb_init();                                              /* main.c       */
00179         icp_init();                                             /* icp.c        */
00180         pwm_init();                                             /* main.c       */
00181 
00182         /*
00183          * PORTC for LED debug
00184          */
00185         LED_DEBUG_PORT = 0xFF;                  /* initially off */
00186         LED_DEBUG_DDR = 0xFF;                   /* all output */
00187 
00188         /*
00189          * The ISRs do most of the work.
00190          */
00191         SEI();                                                  /* enable interrupts since init is done */
00192 
00193         MCUCR |= (1 << SE);                             /* enable (idle mode) sleep */
00194 
00195         /*
00196          * Loop forever
00197          */
00198         for (;;)
00199         {
00200                 /*
00201                  * Fetch the latest reading and display it on the LEDs.
00202                  */
00203                 sample = icp_rx();
00204 
00205                 LED_DEBUG_PORT = ~sample;
00206 
00207                 /*
00208                  * Sleep until the next interrupt. This will wake up twice
00209                  * per PWM period, plus (apx.) 4 times per second for the
00210                  * heartbeat/update timer. This is more often than needed,
00211                  * but is certainly sufficient for this demonstration.
00212                  */
00213                 SLEEP();
00214         }
00215         /*NOTREACHED*/
00216         return(0);
00217 }

Generated on Wed Nov 2 14:20:47 2005 for AVR135: Using Timer Capture to Measure PWM Duty Cycle by  doxygen 1.4.4