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/
Diff: freq_counter.cpp
- Revision:
- 0:83661d0d09c0
- Child:
- 1:fd2e1c853ab6
diff -r 000000000000 -r 83661d0d09c0 freq_counter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/freq_counter.cpp Sun Oct 19 06:44:51 2014 +0000 @@ -0,0 +1,129 @@ +/* + * mbed Library program + * Frequency Counter Hardware relataed program + * + * Copyright (c) 2014 Kenji Arai / JH1PJL + * http://www.page.sannet.ne.jp/kenjia/index.html + * http://mbed.org/users/kenjiArai/ + * Addition and Modification + * started: October 18th, 2014 + * Revised: October 19th, 2014 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "mbed.h" +#include "freq_counter.h" + +F_COUNTER::F_COUNTER(PinName f_in): _pin(f_in) +{ + initialize(); +} + +void F_COUNTER::initialize(void) +{ +#if defined(TARGET_LPC1768) + LPC_SC->PCONP |= 1 << 22; // 1)Power up TimerCounter3 (bit23) + LPC_PINCON->PINSEL0 |= 3 << 8; // 2)Set P0[23] to CAP3[0] + LPC_TIM2->TCR = 2; // 3)Counter Reset (bit1<=1,bit0<=0) + LPC_TIM2->CTCR = 1; // 4)Count on riging edge Cap3[0] + LPC_TIM2->CCR = 0; // 5)Input Capture Disabled + LPC_TIM2->TCR = 1; // 6)Counter Start (bit1<=0,bit0<=1) +#else +#error "No support for this CPU" +#endif +} + +uint32_t F_COUNTER::read_frequency(float gate_time) +{ +#if defined(TARGET_LPC1768) + LPC_TIM2->TCR = 2; // Reset the counter (bit1<=1,bit0<=0) + LPC_TIM2->TCR = 1; // UnReset counter (bit1<=0,bit0<=1) + wait(gate_time); // Gate time for count + freq = LPC_TIM2->TC; + return freq; +#else +#error "No support for this CPU" +#endif +} + +#if 0 +//------------------------------------------------------------------------------------------------- +// Reference program +//------------------------------------------------------------------------------------------------- + +// 5MHzOSC +// http://developer.mbed.org/users/mio/code/5MHzOSC/ +// by fuyono sakura +// http://developer.mbed.org/users/mio/ + +// +// CLOCK OUT to PWM1[6] Sample with Freq Counter using Cap2.0 +// For LPC1768-mbed +// +// Reference: 5MHz Clock Out Code and Comment - http://mbed.org/forum/mbed/topic/733/ +// +// !! To Self Measurement Output Clock, Connect p21 <-> p30 with jumper wire. +// 2013.6.18 : Wrong comment about MR6 and Duty fix. +// + +#include "mbed.h" + +PwmOut fmclck(p21); // for RESERVE pin21 as PWM1[6] +DigitalIn clkin(p30); // for RESERVE pin30 as CAP2[0] + +// Reset Counter and Count Start +void P30_RESET_CTR(void) +{ + LPC_TIM2->TCR = 2; // Reset the counter (bit1<=1,bit0<=0) + LPC_TIM2->TCR = 1; // UnReset counter (bit1<=0,bit0<=1) +} + +// Get Counter Value +int P30_GET_CTR(void) +{ + return LPC_TIM2->TC; // Read the counter value +} + +// Setting p30 to Cap2.0 +void P30_INIT_CTR(void) +{ + LPC_SC->PCONP |= 1 << 22; // 1)Power up TimerCounter2 (bit22) + LPC_PINCON->PINSEL0 |= 3 << 8; // 2)Set P0[4] to CAP2[0] + LPC_TIM2->TCR = 2; // 3)Counter Reset (bit1<=1,bit0<=0) + LPC_TIM2->CTCR = 1; // 4)Count on riging edge Cap2[0] + LPC_TIM2->CCR = 0; // 5)Input Capture Disabled + LPC_TIM2->TCR = 1; // 6)Counter Start (bit1<=0,bit0<=1) +} + +// Clock Output From pin21(PWM6) +// Set Clock Freq with div. +// if mbed is running at 96MHz, div is set 96 to Get 1MHz. +void PWM6_SETCLK(int div) +{ + LPC_PWM1->TCR = (1 << 1); // 1)Reset counter, disable PWM + LPC_SC->PCLKSEL0 &= ~(0x3 << 12); + LPC_SC->PCLKSEL0 |= (1 << 12); // 2)Set peripheral clock divider to /1, i.e. system clock + LPC_PWM1->MR0 = div - 1; // 3)Match Register 0 is shared period counter for all PWM1 + LPC_PWM1->MR6 = (div + 1)>> 1; // + LPC_PWM1->LER |= 1; // 4)Start updating at next period start + LPC_PWM1->TCR = (1 << 0) || (1 << 3); // 5)Enable counter and PWM +} + +int main() +{ + PWM6_SETCLK(19) ; // Outout mbed's "PWM6" pin to 96MHZ/19 = 5.052MHz (Approx) + // PWM6_SETCLK(96) ; // Outout mbed's "PWM6" pin to 96MHZ/96 = 1.000MHz (Approx) + P30_INIT_CTR(); + while(1) { + P30_RESET_CTR(); + wait(1.0); // Gate time for count + printf("pin30 Freq = %d (Hz)\r\n",P30_GET_CTR()); + } +} + +#endif