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:
Tue Aug 04 03:59:07 2020 +0000
Revision:
4:9a726b997366
Parent:
3:61bea8bfe404
modified for running on mbed-os-6.2.0

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