PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pwm_dac_test.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 <stdio.h>
31 
32 /** \file
33 Demonstrates a PWM DAC - connect an RC filter on the OC1
34 output and vary the pulse width of the PWM signal, and monitor
35 the DC value on the capacitor. The RC time constant should
36 be at least 10x greater than the PWM period. Example values
37 used for testing were R=6.8k, C = 1.0u, PWM period= 500 us.
38 Measured ripple was 80 mv, time for the DAC to change voltage
39 from 1.0 V to 3.0 V and vice versa was ~ 30 ms (about 60 PWM periods)
40 For more accuracy, use an external crystal and define
41 CLOCK_CONFIG=PRIPLL_8MHzCrystal_40MHzFCY in the MPLAB project.
42 Remove this macro if you wish to use the internal oscillator.
43 */
44 
45 #ifndef PWM_PERIOD
46 #define PWM_PERIOD 500 // desired period, in us
47 #endif
48 
49 void configTimer2(void) {
50  T2CON = T2_OFF | T2_IDLE_CON | T2_GATE_OFF
51  | T2_32BIT_MODE_OFF
52  | T2_SOURCE_INT
53  | T2_PS_1_64 ; //1 tick = 1.6 us at FCY=40 MHz
54  PR2 = usToU16Ticks(PWM_PERIOD, getTimerPrescale(T2CONbits)) - 1;
55  TMR2 = 0; //clear timer2 value
56  _T2IF = 0;
57  _T2IP = 1;
58  _T2IE = 1; //enable the Timer2 interrupt
59 }
60 
61 void configOutputCompare1(void) {
62  T2CONbits.TON = 0; //disable Timer when configuring Output compare
63  OC1R = 0;
64  OC1RS = 0; //initially off
65 #if (defined(__dsPIC33E__) || defined(__PIC24E__))
66  CONFIG_OC1_TO_RP(35); //map OC1 to RP35/RB3
67 //turn on the compare toggle mode using Timer2
68  OC1CON1 = OC_TIMER2_SRC | //Timer2 source
69  OC_PWM_CENTER_ALIGN; //PWM
70  OC1CON2 = 0x000C; //sync source is Timer2.
71 #else
72  CONFIG_RB3_AS_DIG_OUTPUT();
73  CONFIG_OC1_TO_RP(3); //map OC1 to RP3/RB3
74 //assumes TIMER2 initialized before OC1 so PRE bits are set
75 
76 //turn on the compare toggle mode using Timer2
77  OC1CON = OC_TIMER2_SRC | //Timer2 source
78  OC_PWM_FAULT_PIN_DISABLE; //PWM, no fault detection
79 #endif
80 }
81 
82 volatile uint8_t u8_updateFlag = 0;
83 volatile uint16_t u16_newOC1RS;
84 
85 void _ISR _T2Interrupt(void) {
86  _T2IF = 0; //clear the timer interrupt bit
87  if (u8_updateFlag) {
88  OC1RS = u16_newOC1RS; //update pulse width value
89  u8_updateFlag = 0;
90  _LATB9 = 1;
91  DELAY_US(1);
92  _LATB9 = 0;
93  }
94 }
95 
96 char sz1[32];
97 
98 int main(void) {
99  uint16_t u16_mv;
100  float f_tmp;
101  configBasic(HELLO_MSG);
102  CONFIG_RB9_AS_DIG_OUTPUT();
103  _LATB9 = 0;
104  configTimer2();
105  configOutputCompare1();
106  T2CONbits.TON = 1; //turn on Timer2 to start PWM
107  while (1) {
108  outString("Input voltage 0 to 3300 (mv): \n");
109  inStringEcho(sz1,30);
110  sscanf(sz1,"%d",(int *) &u16_mv);
111  f_tmp = u16_mv;
112  f_tmp = f_tmp/3300 * PR2;
113  u16_newOC1RS = f_tmp;
114  u8_updateFlag = 1;
115  }
116 }