Simple frequency counter, run without modification on Nucleo board, Input pin PA0, PA1, PB3. Only for STM32F4 series (Tested on Nucleo-F401RE,-F411RE and F446RE)
Dependents: Frequency_Counter_for_STM32F4xx
see /users/kenjiArai/notebook/frequency-counters/
freq_counter.cpp@0:83661d0d09c0, 2014-10-19 (annotated)
- Committer:
- kenjiArai
- Date:
- Sun Oct 19 06:44:51 2014 +0000
- Revision:
- 0:83661d0d09c0
- Child:
- 1:fd2e1c853ab6
Frequency Counter Lib. based on mio/5MHzOSC program
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 0:83661d0d09c0 | 1 | /* |
kenjiArai | 0:83661d0d09c0 | 2 | * mbed Library program |
kenjiArai | 0:83661d0d09c0 | 3 | * Frequency Counter Hardware relataed program |
kenjiArai | 0:83661d0d09c0 | 4 | * |
kenjiArai | 0:83661d0d09c0 | 5 | * Copyright (c) 2014 Kenji Arai / JH1PJL |
kenjiArai | 0:83661d0d09c0 | 6 | * http://www.page.sannet.ne.jp/kenjia/index.html |
kenjiArai | 0:83661d0d09c0 | 7 | * http://mbed.org/users/kenjiArai/ |
kenjiArai | 0:83661d0d09c0 | 8 | * Addition and Modification |
kenjiArai | 0:83661d0d09c0 | 9 | * started: October 18th, 2014 |
kenjiArai | 0:83661d0d09c0 | 10 | * Revised: October 19th, 2014 |
kenjiArai | 0:83661d0d09c0 | 11 | * |
kenjiArai | 0:83661d0d09c0 | 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
kenjiArai | 0:83661d0d09c0 | 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE |
kenjiArai | 0:83661d0d09c0 | 14 | * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
kenjiArai | 0:83661d0d09c0 | 15 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
kenjiArai | 0:83661d0d09c0 | 16 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
kenjiArai | 0:83661d0d09c0 | 17 | */ |
kenjiArai | 0:83661d0d09c0 | 18 | |
kenjiArai | 0:83661d0d09c0 | 19 | #include "mbed.h" |
kenjiArai | 0:83661d0d09c0 | 20 | #include "freq_counter.h" |
kenjiArai | 0:83661d0d09c0 | 21 | |
kenjiArai | 0:83661d0d09c0 | 22 | F_COUNTER::F_COUNTER(PinName f_in): _pin(f_in) |
kenjiArai | 0:83661d0d09c0 | 23 | { |
kenjiArai | 0:83661d0d09c0 | 24 | initialize(); |
kenjiArai | 0:83661d0d09c0 | 25 | } |
kenjiArai | 0:83661d0d09c0 | 26 | |
kenjiArai | 0:83661d0d09c0 | 27 | void F_COUNTER::initialize(void) |
kenjiArai | 0:83661d0d09c0 | 28 | { |
kenjiArai | 0:83661d0d09c0 | 29 | #if defined(TARGET_LPC1768) |
kenjiArai | 0:83661d0d09c0 | 30 | LPC_SC->PCONP |= 1 << 22; // 1)Power up TimerCounter3 (bit23) |
kenjiArai | 0:83661d0d09c0 | 31 | LPC_PINCON->PINSEL0 |= 3 << 8; // 2)Set P0[23] to CAP3[0] |
kenjiArai | 0:83661d0d09c0 | 32 | LPC_TIM2->TCR = 2; // 3)Counter Reset (bit1<=1,bit0<=0) |
kenjiArai | 0:83661d0d09c0 | 33 | LPC_TIM2->CTCR = 1; // 4)Count on riging edge Cap3[0] |
kenjiArai | 0:83661d0d09c0 | 34 | LPC_TIM2->CCR = 0; // 5)Input Capture Disabled |
kenjiArai | 0:83661d0d09c0 | 35 | LPC_TIM2->TCR = 1; // 6)Counter Start (bit1<=0,bit0<=1) |
kenjiArai | 0:83661d0d09c0 | 36 | #else |
kenjiArai | 0:83661d0d09c0 | 37 | #error "No support for this CPU" |
kenjiArai | 0:83661d0d09c0 | 38 | #endif |
kenjiArai | 0:83661d0d09c0 | 39 | } |
kenjiArai | 0:83661d0d09c0 | 40 | |
kenjiArai | 0:83661d0d09c0 | 41 | uint32_t F_COUNTER::read_frequency(float gate_time) |
kenjiArai | 0:83661d0d09c0 | 42 | { |
kenjiArai | 0:83661d0d09c0 | 43 | #if defined(TARGET_LPC1768) |
kenjiArai | 0:83661d0d09c0 | 44 | LPC_TIM2->TCR = 2; // Reset the counter (bit1<=1,bit0<=0) |
kenjiArai | 0:83661d0d09c0 | 45 | LPC_TIM2->TCR = 1; // UnReset counter (bit1<=0,bit0<=1) |
kenjiArai | 0:83661d0d09c0 | 46 | wait(gate_time); // Gate time for count |
kenjiArai | 0:83661d0d09c0 | 47 | freq = LPC_TIM2->TC; |
kenjiArai | 0:83661d0d09c0 | 48 | return freq; |
kenjiArai | 0:83661d0d09c0 | 49 | #else |
kenjiArai | 0:83661d0d09c0 | 50 | #error "No support for this CPU" |
kenjiArai | 0:83661d0d09c0 | 51 | #endif |
kenjiArai | 0:83661d0d09c0 | 52 | } |
kenjiArai | 0:83661d0d09c0 | 53 | |
kenjiArai | 0:83661d0d09c0 | 54 | #if 0 |
kenjiArai | 0:83661d0d09c0 | 55 | //------------------------------------------------------------------------------------------------- |
kenjiArai | 0:83661d0d09c0 | 56 | // Reference program |
kenjiArai | 0:83661d0d09c0 | 57 | //------------------------------------------------------------------------------------------------- |
kenjiArai | 0:83661d0d09c0 | 58 | |
kenjiArai | 0:83661d0d09c0 | 59 | // 5MHzOSC |
kenjiArai | 0:83661d0d09c0 | 60 | // http://developer.mbed.org/users/mio/code/5MHzOSC/ |
kenjiArai | 0:83661d0d09c0 | 61 | // by fuyono sakura |
kenjiArai | 0:83661d0d09c0 | 62 | // http://developer.mbed.org/users/mio/ |
kenjiArai | 0:83661d0d09c0 | 63 | |
kenjiArai | 0:83661d0d09c0 | 64 | // |
kenjiArai | 0:83661d0d09c0 | 65 | // CLOCK OUT to PWM1[6] Sample with Freq Counter using Cap2.0 |
kenjiArai | 0:83661d0d09c0 | 66 | // For LPC1768-mbed |
kenjiArai | 0:83661d0d09c0 | 67 | // |
kenjiArai | 0:83661d0d09c0 | 68 | // Reference: 5MHz Clock Out Code and Comment - http://mbed.org/forum/mbed/topic/733/ |
kenjiArai | 0:83661d0d09c0 | 69 | // |
kenjiArai | 0:83661d0d09c0 | 70 | // !! To Self Measurement Output Clock, Connect p21 <-> p30 with jumper wire. |
kenjiArai | 0:83661d0d09c0 | 71 | // 2013.6.18 : Wrong comment about MR6 and Duty fix. |
kenjiArai | 0:83661d0d09c0 | 72 | // |
kenjiArai | 0:83661d0d09c0 | 73 | |
kenjiArai | 0:83661d0d09c0 | 74 | #include "mbed.h" |
kenjiArai | 0:83661d0d09c0 | 75 | |
kenjiArai | 0:83661d0d09c0 | 76 | PwmOut fmclck(p21); // for RESERVE pin21 as PWM1[6] |
kenjiArai | 0:83661d0d09c0 | 77 | DigitalIn clkin(p30); // for RESERVE pin30 as CAP2[0] |
kenjiArai | 0:83661d0d09c0 | 78 | |
kenjiArai | 0:83661d0d09c0 | 79 | // Reset Counter and Count Start |
kenjiArai | 0:83661d0d09c0 | 80 | void P30_RESET_CTR(void) |
kenjiArai | 0:83661d0d09c0 | 81 | { |
kenjiArai | 0:83661d0d09c0 | 82 | LPC_TIM2->TCR = 2; // Reset the counter (bit1<=1,bit0<=0) |
kenjiArai | 0:83661d0d09c0 | 83 | LPC_TIM2->TCR = 1; // UnReset counter (bit1<=0,bit0<=1) |
kenjiArai | 0:83661d0d09c0 | 84 | } |
kenjiArai | 0:83661d0d09c0 | 85 | |
kenjiArai | 0:83661d0d09c0 | 86 | // Get Counter Value |
kenjiArai | 0:83661d0d09c0 | 87 | int P30_GET_CTR(void) |
kenjiArai | 0:83661d0d09c0 | 88 | { |
kenjiArai | 0:83661d0d09c0 | 89 | return LPC_TIM2->TC; // Read the counter value |
kenjiArai | 0:83661d0d09c0 | 90 | } |
kenjiArai | 0:83661d0d09c0 | 91 | |
kenjiArai | 0:83661d0d09c0 | 92 | // Setting p30 to Cap2.0 |
kenjiArai | 0:83661d0d09c0 | 93 | void P30_INIT_CTR(void) |
kenjiArai | 0:83661d0d09c0 | 94 | { |
kenjiArai | 0:83661d0d09c0 | 95 | LPC_SC->PCONP |= 1 << 22; // 1)Power up TimerCounter2 (bit22) |
kenjiArai | 0:83661d0d09c0 | 96 | LPC_PINCON->PINSEL0 |= 3 << 8; // 2)Set P0[4] to CAP2[0] |
kenjiArai | 0:83661d0d09c0 | 97 | LPC_TIM2->TCR = 2; // 3)Counter Reset (bit1<=1,bit0<=0) |
kenjiArai | 0:83661d0d09c0 | 98 | LPC_TIM2->CTCR = 1; // 4)Count on riging edge Cap2[0] |
kenjiArai | 0:83661d0d09c0 | 99 | LPC_TIM2->CCR = 0; // 5)Input Capture Disabled |
kenjiArai | 0:83661d0d09c0 | 100 | LPC_TIM2->TCR = 1; // 6)Counter Start (bit1<=0,bit0<=1) |
kenjiArai | 0:83661d0d09c0 | 101 | } |
kenjiArai | 0:83661d0d09c0 | 102 | |
kenjiArai | 0:83661d0d09c0 | 103 | // Clock Output From pin21(PWM6) |
kenjiArai | 0:83661d0d09c0 | 104 | // Set Clock Freq with div. |
kenjiArai | 0:83661d0d09c0 | 105 | // if mbed is running at 96MHz, div is set 96 to Get 1MHz. |
kenjiArai | 0:83661d0d09c0 | 106 | void PWM6_SETCLK(int div) |
kenjiArai | 0:83661d0d09c0 | 107 | { |
kenjiArai | 0:83661d0d09c0 | 108 | LPC_PWM1->TCR = (1 << 1); // 1)Reset counter, disable PWM |
kenjiArai | 0:83661d0d09c0 | 109 | LPC_SC->PCLKSEL0 &= ~(0x3 << 12); |
kenjiArai | 0:83661d0d09c0 | 110 | LPC_SC->PCLKSEL0 |= (1 << 12); // 2)Set peripheral clock divider to /1, i.e. system clock |
kenjiArai | 0:83661d0d09c0 | 111 | LPC_PWM1->MR0 = div - 1; // 3)Match Register 0 is shared period counter for all PWM1 |
kenjiArai | 0:83661d0d09c0 | 112 | LPC_PWM1->MR6 = (div + 1)>> 1; // |
kenjiArai | 0:83661d0d09c0 | 113 | LPC_PWM1->LER |= 1; // 4)Start updating at next period start |
kenjiArai | 0:83661d0d09c0 | 114 | LPC_PWM1->TCR = (1 << 0) || (1 << 3); // 5)Enable counter and PWM |
kenjiArai | 0:83661d0d09c0 | 115 | } |
kenjiArai | 0:83661d0d09c0 | 116 | |
kenjiArai | 0:83661d0d09c0 | 117 | int main() |
kenjiArai | 0:83661d0d09c0 | 118 | { |
kenjiArai | 0:83661d0d09c0 | 119 | PWM6_SETCLK(19) ; // Outout mbed's "PWM6" pin to 96MHZ/19 = 5.052MHz (Approx) |
kenjiArai | 0:83661d0d09c0 | 120 | // PWM6_SETCLK(96) ; // Outout mbed's "PWM6" pin to 96MHZ/96 = 1.000MHz (Approx) |
kenjiArai | 0:83661d0d09c0 | 121 | P30_INIT_CTR(); |
kenjiArai | 0:83661d0d09c0 | 122 | while(1) { |
kenjiArai | 0:83661d0d09c0 | 123 | P30_RESET_CTR(); |
kenjiArai | 0:83661d0d09c0 | 124 | wait(1.0); // Gate time for count |
kenjiArai | 0:83661d0d09c0 | 125 | printf("pin30 Freq = %d (Hz)\r\n",P30_GET_CTR()); |
kenjiArai | 0:83661d0d09c0 | 126 | } |
kenjiArai | 0:83661d0d09c0 | 127 | } |
kenjiArai | 0:83661d0d09c0 | 128 | |
kenjiArai | 0:83661d0d09c0 | 129 | #endif |