Frequency Counter Library. Only for mbed LPC1768, mbed LPC1114FN28, Nucleo-F401 and Nucleo-F411. No way to change pin assign.

Dependents:   Frequency_Counter Frequency_wind_speed_measure Frequency_counter_wind_speed

Please refer following page.
http://developer.mbed.org/users/kenjiArai/notebook/simple-frequency-counter/

Committer:
kenjiArai
Date:
Wed Oct 22 00:35:23 2014 +0000
Revision:
3:61bea8bfe404
Parent:
2:54c05b0a117a
Child:
4:9a726b997366
Added mbed LPC1114FN28 board based on Tetsuya Suzuki/fc1114 program

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 2:54c05b0a117a 8 * Additional functions and modification
kenjiArai 0:83661d0d09c0 9 * started: October 18th, 2014
kenjiArai 3:61bea8bfe404 10 * Revised: October 22nd, 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 2:54c05b0a117a 18 //-------------------------------------------------------------------------------------------------
kenjiArai 3:61bea8bfe404 19 // Reference program No.1 (see line 104)
kenjiArai 2:54c05b0a117a 20 //-------------------------------------------------------------------------------------------------
kenjiArai 2:54c05b0a117a 21 // 5MHzOSC
kenjiArai 2:54c05b0a117a 22 // http://developer.mbed.org/users/mio/code/5MHzOSC/
kenjiArai 2:54c05b0a117a 23 // by fuyono sakura
kenjiArai 2:54c05b0a117a 24 // http://developer.mbed.org/users/mio/
kenjiArai 0:83661d0d09c0 25
kenjiArai 3:61bea8bfe404 26 //-------------------------------------------------------------------------------------------------
kenjiArai 3:61bea8bfe404 27 // Reference program No.2 (see line 173)
kenjiArai 3:61bea8bfe404 28 //-------------------------------------------------------------------------------------------------
kenjiArai 3:61bea8bfe404 29 // fc114
kenjiArai 3:61bea8bfe404 30 // http://developer.mbed.org/users/rutles/code/fc1114/
kenjiArai 3:61bea8bfe404 31 // by Tetsuya Suzuki
kenjiArai 3:61bea8bfe404 32 // http://developer.mbed.org/users/rutles/
kenjiArai 3:61bea8bfe404 33
kenjiArai 0:83661d0d09c0 34 #include "mbed.h"
kenjiArai 0:83661d0d09c0 35 #include "freq_counter.h"
kenjiArai 0:83661d0d09c0 36
kenjiArai 0:83661d0d09c0 37 F_COUNTER::F_COUNTER(PinName f_in): _pin(f_in)
kenjiArai 0:83661d0d09c0 38 {
kenjiArai 0:83661d0d09c0 39 initialize();
kenjiArai 0:83661d0d09c0 40 }
kenjiArai 0:83661d0d09c0 41
kenjiArai 0:83661d0d09c0 42 void F_COUNTER::initialize(void)
kenjiArai 0:83661d0d09c0 43 {
kenjiArai 0:83661d0d09c0 44 #if defined(TARGET_LPC1768)
kenjiArai 0:83661d0d09c0 45 LPC_SC->PCONP |= 1 << 22; // 1)Power up TimerCounter3 (bit23)
kenjiArai 0:83661d0d09c0 46 LPC_PINCON->PINSEL0 |= 3 << 8; // 2)Set P0[23] to CAP3[0]
kenjiArai 0:83661d0d09c0 47 LPC_TIM2->TCR = 2; // 3)Counter Reset (bit1<=1,bit0<=0)
kenjiArai 0:83661d0d09c0 48 LPC_TIM2->CTCR = 1; // 4)Count on riging edge Cap3[0]
kenjiArai 0:83661d0d09c0 49 LPC_TIM2->CCR = 0; // 5)Input Capture Disabled
kenjiArai 0:83661d0d09c0 50 LPC_TIM2->TCR = 1; // 6)Counter Start (bit1<=0,bit0<=1)
kenjiArai 3:61bea8bfe404 51 #elif defined(TARGET_LPC1114)
kenjiArai 3:61bea8bfe404 52 LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 9); //TMR32B0 wakeup
kenjiArai 3:61bea8bfe404 53 LPC_IOCON->PIO1_5 |= (1 << 1); // Set dp14 (pin20) as CT32B0_CAP0
kenjiArai 3:61bea8bfe404 54 LPC_IOCON->PIO1_5 |= (1 << 5); // Hysteresis enable
kenjiArai 3:61bea8bfe404 55 LPC_TMR32B0->TCR = 2; // reset
kenjiArai 3:61bea8bfe404 56 LPC_TMR32B0->CTCR = 1; // counter mode
kenjiArai 3:61bea8bfe404 57 LPC_TMR32B0->CCR = 0; // Input Capture Disable)
kenjiArai 3:61bea8bfe404 58 LPC_TMR32B0->PR = 0; // no prescale
kenjiArai 3:61bea8bfe404 59 LPC_TMR32B0->TCR = 1; // start
kenjiArai 2:54c05b0a117a 60 #elif defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE)
kenjiArai 1:fd2e1c853ab6 61 // PA0 -> Counter frequency input pin as Timer2 TI1
kenjiArai 1:fd2e1c853ab6 62 GPIOA->AFR[0] &= 0xfffffff0;
kenjiArai 1:fd2e1c853ab6 63 GPIOA->AFR[0] |= GPIO_AF1_TIM2;
kenjiArai 1:fd2e1c853ab6 64 GPIOA->MODER &= ~(GPIO_MODER_MODER0);
kenjiArai 1:fd2e1c853ab6 65 GPIOA->MODER |= 0x2;
kenjiArai 1:fd2e1c853ab6 66 // Initialize Timer2(32bit) for an external up counter mode
kenjiArai 1:fd2e1c853ab6 67 RCC->APB1ENR |= ((uint32_t)0x00000001);
kenjiArai 1:fd2e1c853ab6 68 TIM2->CR1 &= (uint16_t)(~(TIM_CR1_DIR | TIM_CR1_CMS | TIM_CR1_CKD)); // count_up + div by 1
kenjiArai 1:fd2e1c853ab6 69 TIM2->ARR = 0xFFFFFFFF;
kenjiArai 1:fd2e1c853ab6 70 TIM2->PSC = 0x0000;
kenjiArai 1:fd2e1c853ab6 71 TIM2->CCMR1 &= (uint16_t)~TIM_CCMR1_IC1F; // input filter
kenjiArai 1:fd2e1c853ab6 72 TIM2->CCER = TIM_CCER_CC1P; // positive edge
kenjiArai 1:fd2e1c853ab6 73 TIM2->SMCR &= (uint16_t)~(TIM_SMCR_SMS | TIM_SMCR_TS | TIM_SMCR_ECE);
kenjiArai 1:fd2e1c853ab6 74 TIM2->SMCR |= (uint16_t)(TIM_TS_TI1FP1 | TIM_SMCR_SMS); // external mode 1
kenjiArai 1:fd2e1c853ab6 75 TIM2->CR1 |= TIM_CR1_CEN; //Enable the TIM Counter
kenjiArai 0:83661d0d09c0 76 #else
kenjiArai 0:83661d0d09c0 77 #error "No support for this CPU"
kenjiArai 0:83661d0d09c0 78 #endif
kenjiArai 0:83661d0d09c0 79 }
kenjiArai 0:83661d0d09c0 80
kenjiArai 0:83661d0d09c0 81 uint32_t F_COUNTER::read_frequency(float gate_time)
kenjiArai 0:83661d0d09c0 82 {
kenjiArai 0:83661d0d09c0 83 #if defined(TARGET_LPC1768)
kenjiArai 0:83661d0d09c0 84 LPC_TIM2->TCR = 2; // Reset the counter (bit1<=1,bit0<=0)
kenjiArai 0:83661d0d09c0 85 LPC_TIM2->TCR = 1; // UnReset counter (bit1<=0,bit0<=1)
kenjiArai 3:61bea8bfe404 86 wait(gate_time); // Gate time for count
kenjiArai 3:61bea8bfe404 87 freq = LPC_TIM2->TC; // read counter
kenjiArai 3:61bea8bfe404 88 #elif defined(TARGET_LPC1114)
kenjiArai 3:61bea8bfe404 89 LPC_TMR32B0->TCR = 2; // reset
kenjiArai 3:61bea8bfe404 90 LPC_TMR32B0->TCR = 1; // start
kenjiArai 0:83661d0d09c0 91 wait(gate_time); // Gate time for count
kenjiArai 3:61bea8bfe404 92 freq = LPC_TMR32B0->TC; // read counter
kenjiArai 2:54c05b0a117a 93 #elif defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE)
kenjiArai 1:fd2e1c853ab6 94 TIM2->CNT = 0;
kenjiArai 1:fd2e1c853ab6 95 wait(gate_time); // Gate time for count
kenjiArai 3:61bea8bfe404 96 freq = TIM2->CNT; // read counter
kenjiArai 0:83661d0d09c0 97 #else
kenjiArai 0:83661d0d09c0 98 #error "No support for this CPU"
kenjiArai 0:83661d0d09c0 99 #endif
kenjiArai 3:61bea8bfe404 100 return freq;
kenjiArai 0:83661d0d09c0 101 }
kenjiArai 0:83661d0d09c0 102
kenjiArai 0:83661d0d09c0 103 #if 0
kenjiArai 0:83661d0d09c0 104 //
kenjiArai 0:83661d0d09c0 105 // CLOCK OUT to PWM1[6] Sample with Freq Counter using Cap2.0
kenjiArai 0:83661d0d09c0 106 // For LPC1768-mbed
kenjiArai 0:83661d0d09c0 107 //
kenjiArai 0:83661d0d09c0 108 // Reference: 5MHz Clock Out Code and Comment - http://mbed.org/forum/mbed/topic/733/
kenjiArai 0:83661d0d09c0 109 //
kenjiArai 0:83661d0d09c0 110 // !! To Self Measurement Output Clock, Connect p21 <-> p30 with jumper wire.
kenjiArai 0:83661d0d09c0 111 // 2013.6.18 : Wrong comment about MR6 and Duty fix.
kenjiArai 0:83661d0d09c0 112 //
kenjiArai 0:83661d0d09c0 113
kenjiArai 0:83661d0d09c0 114 #include "mbed.h"
kenjiArai 0:83661d0d09c0 115
kenjiArai 0:83661d0d09c0 116 PwmOut fmclck(p21); // for RESERVE pin21 as PWM1[6]
kenjiArai 0:83661d0d09c0 117 DigitalIn clkin(p30); // for RESERVE pin30 as CAP2[0]
kenjiArai 0:83661d0d09c0 118
kenjiArai 0:83661d0d09c0 119 // Reset Counter and Count Start
kenjiArai 0:83661d0d09c0 120 void P30_RESET_CTR(void)
kenjiArai 0:83661d0d09c0 121 {
kenjiArai 0:83661d0d09c0 122 LPC_TIM2->TCR = 2; // Reset the counter (bit1<=1,bit0<=0)
kenjiArai 0:83661d0d09c0 123 LPC_TIM2->TCR = 1; // UnReset counter (bit1<=0,bit0<=1)
kenjiArai 0:83661d0d09c0 124 }
kenjiArai 0:83661d0d09c0 125
kenjiArai 0:83661d0d09c0 126 // Get Counter Value
kenjiArai 0:83661d0d09c0 127 int P30_GET_CTR(void)
kenjiArai 0:83661d0d09c0 128 {
kenjiArai 0:83661d0d09c0 129 return LPC_TIM2->TC; // Read the counter value
kenjiArai 0:83661d0d09c0 130 }
kenjiArai 0:83661d0d09c0 131
kenjiArai 0:83661d0d09c0 132 // Setting p30 to Cap2.0
kenjiArai 0:83661d0d09c0 133 void P30_INIT_CTR(void)
kenjiArai 0:83661d0d09c0 134 {
kenjiArai 0:83661d0d09c0 135 LPC_SC->PCONP |= 1 << 22; // 1)Power up TimerCounter2 (bit22)
kenjiArai 0:83661d0d09c0 136 LPC_PINCON->PINSEL0 |= 3 << 8; // 2)Set P0[4] to CAP2[0]
kenjiArai 0:83661d0d09c0 137 LPC_TIM2->TCR = 2; // 3)Counter Reset (bit1<=1,bit0<=0)
kenjiArai 0:83661d0d09c0 138 LPC_TIM2->CTCR = 1; // 4)Count on riging edge Cap2[0]
kenjiArai 0:83661d0d09c0 139 LPC_TIM2->CCR = 0; // 5)Input Capture Disabled
kenjiArai 0:83661d0d09c0 140 LPC_TIM2->TCR = 1; // 6)Counter Start (bit1<=0,bit0<=1)
kenjiArai 0:83661d0d09c0 141 }
kenjiArai 0:83661d0d09c0 142
kenjiArai 0:83661d0d09c0 143 // Clock Output From pin21(PWM6)
kenjiArai 0:83661d0d09c0 144 // Set Clock Freq with div.
kenjiArai 0:83661d0d09c0 145 // if mbed is running at 96MHz, div is set 96 to Get 1MHz.
kenjiArai 0:83661d0d09c0 146 void PWM6_SETCLK(int div)
kenjiArai 0:83661d0d09c0 147 {
kenjiArai 0:83661d0d09c0 148 LPC_PWM1->TCR = (1 << 1); // 1)Reset counter, disable PWM
kenjiArai 0:83661d0d09c0 149 LPC_SC->PCLKSEL0 &= ~(0x3 << 12);
kenjiArai 0:83661d0d09c0 150 LPC_SC->PCLKSEL0 |= (1 << 12); // 2)Set peripheral clock divider to /1, i.e. system clock
kenjiArai 0:83661d0d09c0 151 LPC_PWM1->MR0 = div - 1; // 3)Match Register 0 is shared period counter for all PWM1
kenjiArai 0:83661d0d09c0 152 LPC_PWM1->MR6 = (div + 1)>> 1; //
kenjiArai 0:83661d0d09c0 153 LPC_PWM1->LER |= 1; // 4)Start updating at next period start
kenjiArai 0:83661d0d09c0 154 LPC_PWM1->TCR = (1 << 0) || (1 << 3); // 5)Enable counter and PWM
kenjiArai 0:83661d0d09c0 155 }
kenjiArai 0:83661d0d09c0 156
kenjiArai 0:83661d0d09c0 157 int main()
kenjiArai 0:83661d0d09c0 158 {
kenjiArai 0:83661d0d09c0 159 PWM6_SETCLK(19) ; // Outout mbed's "PWM6" pin to 96MHZ/19 = 5.052MHz (Approx)
kenjiArai 0:83661d0d09c0 160 // PWM6_SETCLK(96) ; // Outout mbed's "PWM6" pin to 96MHZ/96 = 1.000MHz (Approx)
kenjiArai 0:83661d0d09c0 161 P30_INIT_CTR();
kenjiArai 0:83661d0d09c0 162 while(1) {
kenjiArai 0:83661d0d09c0 163 P30_RESET_CTR();
kenjiArai 0:83661d0d09c0 164 wait(1.0); // Gate time for count
kenjiArai 0:83661d0d09c0 165 printf("pin30 Freq = %d (Hz)\r\n",P30_GET_CTR());
kenjiArai 0:83661d0d09c0 166 }
kenjiArai 0:83661d0d09c0 167 }
kenjiArai 0:83661d0d09c0 168
kenjiArai 0:83661d0d09c0 169 #endif
kenjiArai 3:61bea8bfe404 170
kenjiArai 3:61bea8bfe404 171 #if 0
kenjiArai 3:61bea8bfe404 172
kenjiArai 3:61bea8bfe404 173 // fc1114 - Frequency counter with i2c slave.
kenjiArai 3:61bea8bfe404 174 // target: LPC1114FN28
kenjiArai 3:61bea8bfe404 175
kenjiArai 3:61bea8bfe404 176 #include "mbed.h"
kenjiArai 3:61bea8bfe404 177
kenjiArai 3:61bea8bfe404 178 #define I2C_ADRS 0x70
kenjiArai 3:61bea8bfe404 179
kenjiArai 3:61bea8bfe404 180 DigitalOut led(dp28);
kenjiArai 3:61bea8bfe404 181 I2CSlave slave(dp5, dp27);
kenjiArai 3:61bea8bfe404 182 Ticker tick;
kenjiArai 3:61bea8bfe404 183
kenjiArai 3:61bea8bfe404 184 volatile uint32_t frq;
kenjiArai 3:61bea8bfe404 185
kenjiArai 3:61bea8bfe404 186 void isr_tick()
kenjiArai 3:61bea8bfe404 187 {
kenjiArai 3:61bea8bfe404 188 frq = LPC_TMR32B0->TC;
kenjiArai 3:61bea8bfe404 189 LPC_TMR32B0->TC = 0;
kenjiArai 3:61bea8bfe404 190
kenjiArai 3:61bea8bfe404 191 led = !led;
kenjiArai 3:61bea8bfe404 192 }
kenjiArai 3:61bea8bfe404 193
kenjiArai 3:61bea8bfe404 194 int main()
kenjiArai 3:61bea8bfe404 195 {
kenjiArai 3:61bea8bfe404 196 union {
kenjiArai 3:61bea8bfe404 197 char b[4];
kenjiArai 3:61bea8bfe404 198 uint32_t w;
kenjiArai 3:61bea8bfe404 199 } buf;
kenjiArai 3:61bea8bfe404 200 char dummy[4];
kenjiArai 3:61bea8bfe404 201
kenjiArai 3:61bea8bfe404 202 led = 1;
kenjiArai 3:61bea8bfe404 203 tick.attach(&isr_tick, 1);
kenjiArai 3:61bea8bfe404 204
kenjiArai 3:61bea8bfe404 205 LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 9);//TMR32B0 wakeup
kenjiArai 3:61bea8bfe404 206 LPC_IOCON->PIO1_5 |= (1 << 1);// Set PIN14 as CT32B0_CAP0
kenjiArai 3:61bea8bfe404 207 LPC_IOCON->PIO1_5 |= (1 << 5);// Hysteresis enable
kenjiArai 3:61bea8bfe404 208 LPC_TMR32B0->TCR = 2; // reset
kenjiArai 3:61bea8bfe404 209 LPC_TMR32B0->CTCR = 1; // counter mode
kenjiArai 3:61bea8bfe404 210 LPC_TMR32B0->CCR = 0; // Input Capture Disable)
kenjiArai 3:61bea8bfe404 211 LPC_TMR32B0->PR = 0;// no prescale
kenjiArai 3:61bea8bfe404 212 LPC_TMR32B0->TCR = 1; // start
kenjiArai 3:61bea8bfe404 213
kenjiArai 3:61bea8bfe404 214 slave.address(I2C_ADRS << 1);
kenjiArai 3:61bea8bfe404 215
kenjiArai 3:61bea8bfe404 216 while (1) {
kenjiArai 3:61bea8bfe404 217 int i = slave.receive();
kenjiArai 3:61bea8bfe404 218 switch (i) {
kenjiArai 3:61bea8bfe404 219 case I2CSlave::ReadAddressed:
kenjiArai 3:61bea8bfe404 220 buf.w = frq;
kenjiArai 3:61bea8bfe404 221 slave.write(buf.b, 4);
kenjiArai 3:61bea8bfe404 222 break;
kenjiArai 3:61bea8bfe404 223 case I2CSlave::WriteGeneral:
kenjiArai 3:61bea8bfe404 224 slave.read(dummy, 4);
kenjiArai 3:61bea8bfe404 225 break;
kenjiArai 3:61bea8bfe404 226 case I2CSlave::WriteAddressed:
kenjiArai 3:61bea8bfe404 227 slave.read(dummy, 4);
kenjiArai 3:61bea8bfe404 228 break;
kenjiArai 3:61bea8bfe404 229 }
kenjiArai 3:61bea8bfe404 230 }
kenjiArai 3:61bea8bfe404 231 }
kenjiArai 3:61bea8bfe404 232
kenjiArai 3:61bea8bfe404 233 #endif