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/

Committer:
kenjiArai
Date:
Tue Oct 21 03:44:46 2014 +0000
Revision:
1:fd2e1c853ab6
Parent:
0:83661d0d09c0
Child:
2:54c05b0a117a
Added Nucleo-F401 board (original only for mbed LPC1768)

Who changed what in which revision?

UserRevisionLine numberNew 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 1:fd2e1c853ab6 10 * Revised: October 21st, 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 1:fd2e1c853ab6 36 #elif defined(TARGET_NUCLEO_F401RE)
kenjiArai 1:fd2e1c853ab6 37 // PA0 -> Counter frequency input pin as Timer2 TI1
kenjiArai 1:fd2e1c853ab6 38 GPIOA->AFR[0] &= 0xfffffff0;
kenjiArai 1:fd2e1c853ab6 39 GPIOA->AFR[0] |= GPIO_AF1_TIM2;
kenjiArai 1:fd2e1c853ab6 40 GPIOA->MODER &= ~(GPIO_MODER_MODER0);
kenjiArai 1:fd2e1c853ab6 41 GPIOA->MODER |= 0x2;
kenjiArai 1:fd2e1c853ab6 42 // Initialize Timer2(32bit) for an external up counter mode
kenjiArai 1:fd2e1c853ab6 43 RCC->APB1ENR |= ((uint32_t)0x00000001);
kenjiArai 1:fd2e1c853ab6 44 TIM2->CR1 &= (uint16_t)(~(TIM_CR1_DIR | TIM_CR1_CMS | TIM_CR1_CKD)); // count_up + div by 1
kenjiArai 1:fd2e1c853ab6 45 TIM2->ARR = 0xFFFFFFFF;
kenjiArai 1:fd2e1c853ab6 46 TIM2->PSC = 0x0000;
kenjiArai 1:fd2e1c853ab6 47 TIM2->CCMR1 &= (uint16_t)~TIM_CCMR1_IC1F; // input filter
kenjiArai 1:fd2e1c853ab6 48 TIM2->CCER = TIM_CCER_CC1P; // positive edge
kenjiArai 1:fd2e1c853ab6 49 TIM2->SMCR &= (uint16_t)~(TIM_SMCR_SMS | TIM_SMCR_TS | TIM_SMCR_ECE);
kenjiArai 1:fd2e1c853ab6 50 TIM2->SMCR |= (uint16_t)(TIM_TS_TI1FP1 | TIM_SMCR_SMS); // external mode 1
kenjiArai 1:fd2e1c853ab6 51 TIM2->CR1 |= TIM_CR1_CEN; //Enable the TIM Counter
kenjiArai 0:83661d0d09c0 52 #else
kenjiArai 0:83661d0d09c0 53 #error "No support for this CPU"
kenjiArai 0:83661d0d09c0 54 #endif
kenjiArai 0:83661d0d09c0 55 }
kenjiArai 0:83661d0d09c0 56
kenjiArai 0:83661d0d09c0 57 uint32_t F_COUNTER::read_frequency(float gate_time)
kenjiArai 0:83661d0d09c0 58 {
kenjiArai 0:83661d0d09c0 59 #if defined(TARGET_LPC1768)
kenjiArai 0:83661d0d09c0 60 LPC_TIM2->TCR = 2; // Reset the counter (bit1<=1,bit0<=0)
kenjiArai 0:83661d0d09c0 61 LPC_TIM2->TCR = 1; // UnReset counter (bit1<=0,bit0<=1)
kenjiArai 0:83661d0d09c0 62 wait(gate_time); // Gate time for count
kenjiArai 0:83661d0d09c0 63 freq = LPC_TIM2->TC;
kenjiArai 0:83661d0d09c0 64 return freq;
kenjiArai 1:fd2e1c853ab6 65 #elif defined(TARGET_NUCLEO_F401RE)
kenjiArai 1:fd2e1c853ab6 66 TIM2->CNT = 0;
kenjiArai 1:fd2e1c853ab6 67 wait(gate_time); // Gate time for count
kenjiArai 1:fd2e1c853ab6 68 freq = TIM2->CNT;
kenjiArai 1:fd2e1c853ab6 69 return freq;
kenjiArai 0:83661d0d09c0 70 #else
kenjiArai 0:83661d0d09c0 71 #error "No support for this CPU"
kenjiArai 0:83661d0d09c0 72 #endif
kenjiArai 0:83661d0d09c0 73 }
kenjiArai 0:83661d0d09c0 74
kenjiArai 0:83661d0d09c0 75 #if 0
kenjiArai 0:83661d0d09c0 76 //-------------------------------------------------------------------------------------------------
kenjiArai 0:83661d0d09c0 77 // Reference program
kenjiArai 0:83661d0d09c0 78 //-------------------------------------------------------------------------------------------------
kenjiArai 0:83661d0d09c0 79
kenjiArai 0:83661d0d09c0 80 // 5MHzOSC
kenjiArai 0:83661d0d09c0 81 // http://developer.mbed.org/users/mio/code/5MHzOSC/
kenjiArai 0:83661d0d09c0 82 // by fuyono sakura
kenjiArai 0:83661d0d09c0 83 // http://developer.mbed.org/users/mio/
kenjiArai 0:83661d0d09c0 84
kenjiArai 0:83661d0d09c0 85 //
kenjiArai 0:83661d0d09c0 86 // CLOCK OUT to PWM1[6] Sample with Freq Counter using Cap2.0
kenjiArai 0:83661d0d09c0 87 // For LPC1768-mbed
kenjiArai 0:83661d0d09c0 88 //
kenjiArai 0:83661d0d09c0 89 // Reference: 5MHz Clock Out Code and Comment - http://mbed.org/forum/mbed/topic/733/
kenjiArai 0:83661d0d09c0 90 //
kenjiArai 0:83661d0d09c0 91 // !! To Self Measurement Output Clock, Connect p21 <-> p30 with jumper wire.
kenjiArai 0:83661d0d09c0 92 // 2013.6.18 : Wrong comment about MR6 and Duty fix.
kenjiArai 0:83661d0d09c0 93 //
kenjiArai 0:83661d0d09c0 94
kenjiArai 0:83661d0d09c0 95 #include "mbed.h"
kenjiArai 0:83661d0d09c0 96
kenjiArai 0:83661d0d09c0 97 PwmOut fmclck(p21); // for RESERVE pin21 as PWM1[6]
kenjiArai 0:83661d0d09c0 98 DigitalIn clkin(p30); // for RESERVE pin30 as CAP2[0]
kenjiArai 0:83661d0d09c0 99
kenjiArai 0:83661d0d09c0 100 // Reset Counter and Count Start
kenjiArai 0:83661d0d09c0 101 void P30_RESET_CTR(void)
kenjiArai 0:83661d0d09c0 102 {
kenjiArai 0:83661d0d09c0 103 LPC_TIM2->TCR = 2; // Reset the counter (bit1<=1,bit0<=0)
kenjiArai 0:83661d0d09c0 104 LPC_TIM2->TCR = 1; // UnReset counter (bit1<=0,bit0<=1)
kenjiArai 0:83661d0d09c0 105 }
kenjiArai 0:83661d0d09c0 106
kenjiArai 0:83661d0d09c0 107 // Get Counter Value
kenjiArai 0:83661d0d09c0 108 int P30_GET_CTR(void)
kenjiArai 0:83661d0d09c0 109 {
kenjiArai 0:83661d0d09c0 110 return LPC_TIM2->TC; // Read the counter value
kenjiArai 0:83661d0d09c0 111 }
kenjiArai 0:83661d0d09c0 112
kenjiArai 0:83661d0d09c0 113 // Setting p30 to Cap2.0
kenjiArai 0:83661d0d09c0 114 void P30_INIT_CTR(void)
kenjiArai 0:83661d0d09c0 115 {
kenjiArai 0:83661d0d09c0 116 LPC_SC->PCONP |= 1 << 22; // 1)Power up TimerCounter2 (bit22)
kenjiArai 0:83661d0d09c0 117 LPC_PINCON->PINSEL0 |= 3 << 8; // 2)Set P0[4] to CAP2[0]
kenjiArai 0:83661d0d09c0 118 LPC_TIM2->TCR = 2; // 3)Counter Reset (bit1<=1,bit0<=0)
kenjiArai 0:83661d0d09c0 119 LPC_TIM2->CTCR = 1; // 4)Count on riging edge Cap2[0]
kenjiArai 0:83661d0d09c0 120 LPC_TIM2->CCR = 0; // 5)Input Capture Disabled
kenjiArai 0:83661d0d09c0 121 LPC_TIM2->TCR = 1; // 6)Counter Start (bit1<=0,bit0<=1)
kenjiArai 0:83661d0d09c0 122 }
kenjiArai 0:83661d0d09c0 123
kenjiArai 0:83661d0d09c0 124 // Clock Output From pin21(PWM6)
kenjiArai 0:83661d0d09c0 125 // Set Clock Freq with div.
kenjiArai 0:83661d0d09c0 126 // if mbed is running at 96MHz, div is set 96 to Get 1MHz.
kenjiArai 0:83661d0d09c0 127 void PWM6_SETCLK(int div)
kenjiArai 0:83661d0d09c0 128 {
kenjiArai 0:83661d0d09c0 129 LPC_PWM1->TCR = (1 << 1); // 1)Reset counter, disable PWM
kenjiArai 0:83661d0d09c0 130 LPC_SC->PCLKSEL0 &= ~(0x3 << 12);
kenjiArai 0:83661d0d09c0 131 LPC_SC->PCLKSEL0 |= (1 << 12); // 2)Set peripheral clock divider to /1, i.e. system clock
kenjiArai 0:83661d0d09c0 132 LPC_PWM1->MR0 = div - 1; // 3)Match Register 0 is shared period counter for all PWM1
kenjiArai 0:83661d0d09c0 133 LPC_PWM1->MR6 = (div + 1)>> 1; //
kenjiArai 0:83661d0d09c0 134 LPC_PWM1->LER |= 1; // 4)Start updating at next period start
kenjiArai 0:83661d0d09c0 135 LPC_PWM1->TCR = (1 << 0) || (1 << 3); // 5)Enable counter and PWM
kenjiArai 0:83661d0d09c0 136 }
kenjiArai 0:83661d0d09c0 137
kenjiArai 0:83661d0d09c0 138 int main()
kenjiArai 0:83661d0d09c0 139 {
kenjiArai 0:83661d0d09c0 140 PWM6_SETCLK(19) ; // Outout mbed's "PWM6" pin to 96MHZ/19 = 5.052MHz (Approx)
kenjiArai 0:83661d0d09c0 141 // PWM6_SETCLK(96) ; // Outout mbed's "PWM6" pin to 96MHZ/96 = 1.000MHz (Approx)
kenjiArai 0:83661d0d09c0 142 P30_INIT_CTR();
kenjiArai 0:83661d0d09c0 143 while(1) {
kenjiArai 0:83661d0d09c0 144 P30_RESET_CTR();
kenjiArai 0:83661d0d09c0 145 wait(1.0); // Gate time for count
kenjiArai 0:83661d0d09c0 146 printf("pin30 Freq = %d (Hz)\r\n",P30_GET_CTR());
kenjiArai 0:83661d0d09c0 147 }
kenjiArai 0:83661d0d09c0 148 }
kenjiArai 0:83661d0d09c0 149
kenjiArai 0:83661d0d09c0 150 #endif