A PWM/duty cycle measurement library using Timer2
Dependents: PWMAverage_test pwm_duty_measurement
PWMAverage.cpp@1:34a9269390d9, 2012-08-29 (annotated)
- Committer:
- p07gbar
- Date:
- Wed Aug 29 11:44:01 2012 +0000
- Revision:
- 1:34a9269390d9
- Parent:
- 0:5da51898a166
Tidied the documentation, wrote a basic example
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
p07gbar | 0:5da51898a166 | 1 | #include "PWMAverage.h" |
p07gbar | 0:5da51898a166 | 2 | |
p07gbar | 0:5da51898a166 | 3 | #define PWMA_PCLK 96000000 |
p07gbar | 0:5da51898a166 | 4 | |
p07gbar | 0:5da51898a166 | 5 | |
p07gbar | 0:5da51898a166 | 6 | PWMAverage * PWMAverage::instance; |
p07gbar | 0:5da51898a166 | 7 | |
p07gbar | 0:5da51898a166 | 8 | |
p07gbar | 0:5da51898a166 | 9 | void PWMAverage::_tisr() |
p07gbar | 0:5da51898a166 | 10 | { |
p07gbar | 0:5da51898a166 | 11 | //printf("."); |
p07gbar | 0:5da51898a166 | 12 | int cr0 = LPC_TIM2->CR0; |
p07gbar | 0:5da51898a166 | 13 | int cr1 = LPC_TIM2->CR1; |
p07gbar | 0:5da51898a166 | 14 | |
p07gbar | 0:5da51898a166 | 15 | LPC_TIM2->IR = 0x3F; |
p07gbar | 0:5da51898a166 | 16 | |
p07gbar | 0:5da51898a166 | 17 | LPC_TIM2->TCR = 3; |
p07gbar | 0:5da51898a166 | 18 | LPC_TIM2->TCR = 1; |
p07gbar | 0:5da51898a166 | 19 | |
p07gbar | 0:5da51898a166 | 20 | //LPC_NVIC->ICPR0 |= (1<<3) |
p07gbar | 0:5da51898a166 | 21 | |
p07gbar | 0:5da51898a166 | 22 | if(!instance->starting) |
p07gbar | 0:5da51898a166 | 23 | { |
p07gbar | 0:5da51898a166 | 24 | instance->total += cr1 + 82; |
p07gbar | 0:5da51898a166 | 25 | instance->totalup += cr0 + 82; |
p07gbar | 0:5da51898a166 | 26 | instance->count_++; |
p07gbar | 0:5da51898a166 | 27 | } |
p07gbar | 0:5da51898a166 | 28 | else instance->starting = false; |
p07gbar | 0:5da51898a166 | 29 | |
p07gbar | 0:5da51898a166 | 30 | } |
p07gbar | 0:5da51898a166 | 31 | |
p07gbar | 0:5da51898a166 | 32 | PWMAverage::PWMAverage(PinName cap0, PinName cap1) |
p07gbar | 0:5da51898a166 | 33 | { |
p07gbar | 0:5da51898a166 | 34 | prescaler_point = 0x0; |
p07gbar | 0:5da51898a166 | 35 | configure(); |
p07gbar | 0:5da51898a166 | 36 | stop(); |
p07gbar | 0:5da51898a166 | 37 | |
p07gbar | 0:5da51898a166 | 38 | timeMult = (1/PWMA_PCLK)*(prescaler_point+1); |
p07gbar | 0:5da51898a166 | 39 | timeDiv = PWMA_PCLK/(prescaler_point+1); |
p07gbar | 0:5da51898a166 | 40 | instance = this; |
p07gbar | 0:5da51898a166 | 41 | } |
p07gbar | 0:5da51898a166 | 42 | |
p07gbar | 0:5da51898a166 | 43 | void PWMAverage::reset() |
p07gbar | 0:5da51898a166 | 44 | { |
p07gbar | 0:5da51898a166 | 45 | count_ = 0; |
p07gbar | 0:5da51898a166 | 46 | total = 0; |
p07gbar | 0:5da51898a166 | 47 | totalup = 0; |
p07gbar | 0:5da51898a166 | 48 | LPC_TIM2->TCR = 2; |
p07gbar | 0:5da51898a166 | 49 | LPC_TIM2->TCR = 0; |
p07gbar | 0:5da51898a166 | 50 | } |
p07gbar | 0:5da51898a166 | 51 | |
p07gbar | 0:5da51898a166 | 52 | void PWMAverage::start() |
p07gbar | 0:5da51898a166 | 53 | { |
p07gbar | 0:5da51898a166 | 54 | //reset(); |
p07gbar | 0:5da51898a166 | 55 | starting = true; |
p07gbar | 0:5da51898a166 | 56 | enable(true); |
p07gbar | 0:5da51898a166 | 57 | NVIC_EnableIRQ(TIMER2_IRQn); |
p07gbar | 0:5da51898a166 | 58 | } |
p07gbar | 0:5da51898a166 | 59 | |
p07gbar | 0:5da51898a166 | 60 | void PWMAverage::stop() |
p07gbar | 0:5da51898a166 | 61 | { |
p07gbar | 0:5da51898a166 | 62 | enable(false); |
p07gbar | 0:5da51898a166 | 63 | NVIC_DisableIRQ(TIMER2_IRQn); |
p07gbar | 0:5da51898a166 | 64 | } |
p07gbar | 0:5da51898a166 | 65 | |
p07gbar | 0:5da51898a166 | 66 | float PWMAverage::read() |
p07gbar | 0:5da51898a166 | 67 | { |
p07gbar | 0:5da51898a166 | 68 | if(period() != 0) return float(avg_up()/period()); |
p07gbar | 0:5da51898a166 | 69 | else return 0; |
p07gbar | 0:5da51898a166 | 70 | } |
p07gbar | 0:5da51898a166 | 71 | |
p07gbar | 0:5da51898a166 | 72 | double PWMAverage::avg_up() |
p07gbar | 0:5da51898a166 | 73 | { |
p07gbar | 0:5da51898a166 | 74 | if(count_!= 0) return (double(totalup)/timeDiv)/double(count_); |
p07gbar | 0:5da51898a166 | 75 | else return 0; |
p07gbar | 0:5da51898a166 | 76 | |
p07gbar | 0:5da51898a166 | 77 | } |
p07gbar | 0:5da51898a166 | 78 | |
p07gbar | 0:5da51898a166 | 79 | float PWMAverage::avg_UP() |
p07gbar | 0:5da51898a166 | 80 | { |
p07gbar | 0:5da51898a166 | 81 | if(count_!= 0) return float((double(totalup)/timeDiv)/double(count_)); |
p07gbar | 0:5da51898a166 | 82 | else return 0; |
p07gbar | 0:5da51898a166 | 83 | } |
p07gbar | 0:5da51898a166 | 84 | |
p07gbar | 0:5da51898a166 | 85 | double PWMAverage::avg_down() |
p07gbar | 0:5da51898a166 | 86 | { |
p07gbar | 0:5da51898a166 | 87 | if(count_!= 0) return (double(total-totalup)/timeDiv)/double(count_); |
p07gbar | 0:5da51898a166 | 88 | else return 0; |
p07gbar | 0:5da51898a166 | 89 | } |
p07gbar | 0:5da51898a166 | 90 | |
p07gbar | 0:5da51898a166 | 91 | double PWMAverage::period() |
p07gbar | 0:5da51898a166 | 92 | { |
p07gbar | 0:5da51898a166 | 93 | if(count_!= 0) return (double(total)/timeDiv)/double(count_); |
p07gbar | 0:5da51898a166 | 94 | else return 0; |
p07gbar | 0:5da51898a166 | 95 | } |
p07gbar | 0:5da51898a166 | 96 | |
p07gbar | 0:5da51898a166 | 97 | int PWMAverage::count() |
p07gbar | 0:5da51898a166 | 98 | { |
p07gbar | 0:5da51898a166 | 99 | return count_; |
p07gbar | 0:5da51898a166 | 100 | } |
p07gbar | 0:5da51898a166 | 101 | |
p07gbar | 0:5da51898a166 | 102 | void PWMAverage::enable(bool yn) |
p07gbar | 0:5da51898a166 | 103 | { |
p07gbar | 0:5da51898a166 | 104 | LPC_TIM2->TCR = yn; |
p07gbar | 0:5da51898a166 | 105 | } |
p07gbar | 0:5da51898a166 | 106 | |
p07gbar | 0:5da51898a166 | 107 | void PWMAverage::configure() |
p07gbar | 0:5da51898a166 | 108 | { |
p07gbar | 0:5da51898a166 | 109 | //Power Periferal |
p07gbar | 0:5da51898a166 | 110 | |
p07gbar | 0:5da51898a166 | 111 | LPC_SC->PCONP |= (1<<22); |
p07gbar | 0:5da51898a166 | 112 | |
p07gbar | 0:5da51898a166 | 113 | //Setup Pins |
p07gbar | 0:5da51898a166 | 114 | |
p07gbar | 0:5da51898a166 | 115 | LPC_PINCON->PINSEL0 |= (0x3<<8); |
p07gbar | 0:5da51898a166 | 116 | LPC_PINCON->PINSEL0 |= (0x3<<10); |
p07gbar | 0:5da51898a166 | 117 | |
p07gbar | 0:5da51898a166 | 118 | //Setup clock source |
p07gbar | 0:5da51898a166 | 119 | |
p07gbar | 0:5da51898a166 | 120 | LPC_SC->PCLKSEL1 |= (0x1<<12); |
p07gbar | 0:5da51898a166 | 121 | |
p07gbar | 0:5da51898a166 | 122 | //Setup PC |
p07gbar | 0:5da51898a166 | 123 | |
p07gbar | 0:5da51898a166 | 124 | LPC_TIM2->PR = prescaler_point; |
p07gbar | 0:5da51898a166 | 125 | |
p07gbar | 0:5da51898a166 | 126 | //Setup CAP0 - Store on fall |
p07gbar | 0:5da51898a166 | 127 | |
p07gbar | 0:5da51898a166 | 128 | LPC_TIM2->CCR |= 0x2; |
p07gbar | 0:5da51898a166 | 129 | |
p07gbar | 0:5da51898a166 | 130 | //Setup CAP1 - Store on rise, interrupt |
p07gbar | 0:5da51898a166 | 131 | |
p07gbar | 0:5da51898a166 | 132 | LPC_TIM2->CCR |= 0x5<<3; |
p07gbar | 0:5da51898a166 | 133 | |
p07gbar | 0:5da51898a166 | 134 | //Setup IRQs |
p07gbar | 0:5da51898a166 | 135 | NVIC_DisableIRQ(TIMER2_IRQn); |
p07gbar | 0:5da51898a166 | 136 | NVIC_SetVector(TIMER2_IRQn, (uint32_t)&_tisr); |
p07gbar | 0:5da51898a166 | 137 | NVIC_EnableIRQ(TIMER2_IRQn); |
p07gbar | 0:5da51898a166 | 138 | // |
p07gbar | 0:5da51898a166 | 139 | } |