ledpwm.c - Demonstrates pulse width modulation by controlling the intensity of an LED. The ADC input value on AN0 is used to vary the PWM period.ΒΆ
Demonstrates pulse width modulation by controlling the intensity of an LED. The ADC input value on AN0 is used to vary the PWM period. Also demonstates the use of the variable monitoring capability in Bully Bootloader.
#include <pic24_all.h>
#include <dataXfer.h>
/** \file
Demonstrates pulse width modulation by
controlling the intensity of an LED. The
ADC input value on AN0 is used to vary the PWM
period.
Also demonstates the use of the variable
monitoring capability in Bully Bootloader.
*/
#ifndef PWM_PERIOD
#define PWM_PERIOD 1000 // desired period, in us
#endif
void configTimer2(void) {
T2CON = T2_OFF | T2_IDLE_CON | T2_GATE_OFF
| T2_32BIT_MODE_OFF
| T2_SOURCE_INT
| T2_PS_1_8;
PR2 = usToU16Ticks(PWM_PERIOD, getTimerPrescale(T2CONbits)) - 1;
TMR2 = 0; //clear timer2 value
_T2IF = 0;
_T2IP = 1;
_T2IE = 1; //enable the Timer2 interrupt
}
void configOutputCompare1(void) {
T2CONbits.TON = 0; //disable Timer when configuring Output compare
CONFIG_OC1_TO_RP(RB4_RP); //map OC1 to RB4
OC1RS = 0; //clear both registers
OC1R = 0;
#ifdef OC1CON1
//turn on the compare toggle mode using Timer2
OC1CON1 = OC_TIMER2_SRC | //Timer2 source
OC_PWM_CENTER_ALIGN; //PWM
OC1CON2 = OC_SYNCSEL_TIMER2; //synchronize to timer2
#else
//older families, this PWM mode is compatible with center-aligned, OC1R=0
//as writes to OC1RS sets the pulse widith.
OC1CON = OC_TIMER2_SRC | //Timer2 source
OC_PWM_FAULT_PIN_DISABLE; //PWM, no fault detection
#endif
}
void _ISR _T2Interrupt(void) {
uint32_t u32_temp;
_T2IF = 0; //clear the timer interrupt bit
//update the PWM duty cycle from the ADC value
u32_temp = ADC1BUF0; //use 32-bit value for range
//compute new pulse width that is 0 to 99% of PR2
pulse width (PR2) * ADC/1024
u32_temp = (u32_temp * (PR2))>> 10 ; // >>10 is same as divide/1024
OC1RS = u32_temp; //update pulse width value
SET_SAMP_BIT_ADC1(); //start sampling and conversion
}
/// Indexes of all the variables to be transferred.
enum { U32_PW_NDX, OC1RS_NDX, ADC1BUF0_NDX };
int main(void) {
uint32_t u32_pw;
Initialize
configBasic(HELLO_MSG);
initDataXfer();
All variables received by the PIC must be specified. Params: Index Variable PC can change Format Description
SPECIFY_VAR(U32_PW_NDX, u32_pw, FALSE, "%u", "PWM pulse width (us)");
SPECIFY_VAR(OC1RS_NDX, OC1RS, FALSE, "%hu", "Raw PWM value");
SPECIFY_VAR(ADC1BUF0_NDX, ADC1BUF0, FALSE, "%hu", "Raw ADC value");
Configure PWM
configTimer2();
configOutputCompare1();
CONFIG_RA0_AS_ANALOG();
configADC1_ManualCH0(RA0_AN, 31, 0);
SET_SAMP_BIT_ADC1(); //start sampling and conversion
T2CONbits.TON = 1; //turn on Timer2 to start PWM
Report results only
while (1) {
u32_pw = ticksToUs(OC1RS, getTimerPrescale(T2CONbits));
sendVar(U32_PW_NDX);
sendVar(OC1RS_NDX);
sendVar(ADC1BUF0_NDX);
DELAY_MS(100);
doHeartbeat();
}
}