PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ledpwm_bullymon.c
Go to the documentation of this file.
1 /*
2  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
3  * All rights reserved.
4  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
5  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
6  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation for any purpose, without fee, and without written agreement is
10  * hereby granted, provided that the above copyright notice, the following
11  * two paragraphs and the authors appear in all copies of this software.
12  *
13  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
15  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
16  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17  *
18  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
23  *
24  * Please maintain this header in its entirety when copying/modifying
25  * these files.
26  *
27  *
28  */
29 #include <pic24_all.h>
30 #include <dataXfer.h>
31 
32 /** \file
33 Demonstrates pulse width modulation by
34 controlling the intensity of an LED. The
35 ADC input value on AN0 is used to vary the PWM
36 period.
37 Also demonstates the use of the variable
38 monitoring capability in Bully Bootloader.
39 */
40 
41 #ifndef PWM_PERIOD
42 #define PWM_PERIOD 1000 // desired period, in us
43 #endif
44 
45 void configTimer2(void) {
46  T2CON = T2_OFF | T2_IDLE_CON | T2_GATE_OFF
47  | T2_32BIT_MODE_OFF
48  | T2_SOURCE_INT
49  | T2_PS_1_8;
50  PR2 = usToU16Ticks(PWM_PERIOD, getTimerPrescale(T2CONbits)) - 1;
51  TMR2 = 0; //clear timer2 value
52  _T2IF = 0;
53  _T2IP = 1;
54  _T2IE = 1; //enable the Timer2 interrupt
55 }
56 
57 
58 void configOutputCompare1(void) {
59  T2CONbits.TON = 0; //disable Timer when configuring Output compare
60 #if (defined(__dsPIC33E__) || defined(__PIC24E__))
61  CONFIG_OC1_TO_RP(36); //map OC1 to RP36/RB4
62 #else
63  CONFIG_OC1_TO_RP(14); //map OC1 to RP14/RB14
64 #endif
65 //assumes TIMER2 initialized before OC1 so PRE bits are set
66  OC1RS = 0; //initially off
67 #if (defined(__dsPIC33E__) || defined(__PIC24E__))
68 //turn on the compare toggle mode using Timer2
69  OC1CON1 = OC_TIMER2_SRC | //Timer2 source
70  OC_PWM_CENTER_ALIGN; //PWM
71  OC1CON2 = 0x000C; //sync source is Timer2.
72 #else
73 //turn on the compare toggle mode using Timer2
74  OC1CON = OC_TIMER2_SRC | //Timer2 source
75  OC_PWM_FAULT_PIN_DISABLE; //PWM, no fault detection
76 #endif
77 }
78 
79 void _ISR _T2Interrupt(void) {
80  uint32_t u32_temp;
81  _T2IF = 0; //clear the timer interrupt bit
82  //update the PWM duty cycle from the ADC value
83  u32_temp = ADC1BUF0; //use 32-bit value for range
84  //compute new pulse width that is 0 to 99% of PR2
85  // pulse width (PR2) * ADC/4096
86  u32_temp = (u32_temp * (PR2))>> 12 ; // >>12 is same as divide/4096
87  OC1RS = u32_temp; //update pulse width value
88  SET_SAMP_BIT_ADC1(); //start sampling and conversion
89 }
90 
91 /// Indexes of all the variables to be transferred.
92 enum { U32_PW_NDX, OC1RS_NDX, ADC1BUF0_NDX };
93 
94 
95 
96 int main(void) {
97  uint32_t u32_pw;
98 
99  // Initialize
100  configBasic(HELLO_MSG);
101  initDataXfer();
102 
103  // All variables received by the PIC must be specified.
104  // Params: Index Variable PC can change Format Description
105  SPECIFY_VAR(U32_PW_NDX, u32_pw, FALSE, "%u", "PWM pulse width (us)");
106  SPECIFY_VAR(OC1RS_NDX, OC1RS, FALSE, "%hu", "Raw PWM value");
107  SPECIFY_VAR(ADC1BUF0_NDX, ADC1BUF0, FALSE, "%hu", "Raw ADC value");
108 
109  // Configure PWM
110  configTimer2();
111  configOutputCompare1();
112  CONFIG_AN0_AS_ANALOG();
113  configADC1_ManualCH0( ADC_CH0_POS_SAMPLEA_AN0, 31, 1 );
114  SET_SAMP_BIT_ADC1(); //start sampling and conversion
115  T2CONbits.TON = 1; //turn on Timer2 to start PWM
116 
117  // Report results only
118  while (1) {
119  u32_pw = ticksToUs(OC1RS, getTimerPrescale(T2CONbits));
120  sendVar(U32_PW_NDX);
121  sendVar(OC1RS_NDX);
122  sendVar(ADC1BUF0_NDX);
123  DELAY_MS(100);
124  doHeartbeat();
125  }
126 }