00001 /* 00002 * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")" 00003 * All rights reserved. 00004 * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University) 00005 * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University) 00006 * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University) 00007 * 00008 * Permission to use, copy, modify, and distribute this software and its 00009 * documentation for any purpose, without fee, and without written agreement is 00010 * hereby granted, provided that the above copyright notice, the following 00011 * two paragraphs and the authors appear in all copies of this software. 00012 * 00013 * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR 00014 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT 00015 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS" 00016 * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00017 * 00018 * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES, 00019 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 00020 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 00021 * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO 00022 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." 00023 * 00024 * Please maintain this header in its entirety when copying/modifying 00025 * these files. 00026 * 00027 * 00028 */ 00029 #include "pic24_all.h" 00030 #include <stdio.h> 00031 00041 #ifndef PWM_PERIOD 00042 #define PWM_PERIOD 20000 // desired period, in us 00043 #endif 00044 #define MIN_PW 600 //minimum pulse width, in us 00045 #define MAX_PW 2400 //maximum pulse width, in us 00046 00047 void configTimer2(void) { 00048 T2CON = T2_OFF | T2_IDLE_CON | T2_GATE_OFF 00049 | T2_32BIT_MODE_OFF 00050 | T2_SOURCE_INT 00051 | T2_PS_1_64 ; //1 tick = 1.6 us at FCY=40 MHz 00052 PR2 = usToU16Ticks(PWM_PERIOD, getTimerPrescale(T2CONbits)); 00053 TMR2 = 0; //clear timer2 value 00054 _T2IF = 0; 00055 _T2IP = 1; 00056 _T2IE = 1; //enable the Timer2 interrupt 00057 } 00058 00059 uint16 u16_minPWTicks; 00060 uint16 u16_maxPWTicks; 00061 void configOutputCapture1(void) { 00062 u16_minPWTicks = usToU16Ticks(MIN_PW, getTimerPrescale(T2CONbits)); 00063 u16_maxPWTicks = usToU16Ticks(MAX_PW, getTimerPrescale(T2CONbits)); 00064 T2CONbits.TON = 0; //disable Timer when configuring Output compare 00065 CONFIG_RB3_AS_DIG_OUTPUT(); 00066 CONFIG_OC1_TO_RP(3); //map OC1 to RP3/RB3 00067 //assumes TIMER2 initialized before OC1 so PRE bits are set 00068 OC1RS = 0; //initially off 00069 //turn on the compare toggle mode using Timer2 00070 OC1CON = OC_TIMER2_SRC | //Timer2 source 00071 OC_PWM_FAULT_PIN_DISABLE; //PWM, no fault detection 00072 } 00073 00074 00075 00076 void _ISR _T2Interrupt(void) { 00077 uint32 u32_temp; 00078 _T2IF = 0; //clear the timer interrupt bit 00079 //update the PWM duty cycle from the ADC value 00080 u32_temp = ADC1BUF0; //use 32-bit value for range 00081 //compute new pulse width using ADC value 00082 // (max - min) * ADC/1024 + min 00083 u32_temp = ((u32_temp * (u16_maxPWTicks-u16_minPWTicks))>> 10) + u16_minPWTicks; // >>10 is same as divide/1024 00084 OC1RS = u32_temp; //update pulse width value 00085 AD1CON1bits.SAMP = 1; //start next ADC conversion for next interrupt 00086 } 00087 00088 int main(void) { 00089 uint32 u32_pw; 00090 configBasic(HELLO_MSG); 00091 configTimer2(); 00092 configOutputCapture1(); 00093 CONFIG_AN0_AS_ANALOG(); 00094 configADC1_ManualCH0(ADC_CH0_POS_SAMPLEA_AN0, 31, 1); 00095 SET_SAMP_BIT_ADC1(); //start sampling and conversion 00096 T2CONbits.TON = 1; //turn on Timer2 to start PWM 00097 while (1) { 00098 u32_pw = ticksToUs(OC1RS, getTimerPrescale(T2CONbits)); 00099 printf("PWM PW (us): %ld \n",u32_pw); 00100 DELAY_MS(100); 00101 } 00102 }