![](/media/cache/profiles/f0fcf351df4eb6786e9bb6fc4e2dee02.jpg.50x50_q85.jpg)
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)
Dependencies: freq_counter_STM32F4xx
see /users/kenjiArai/notebook/frequency-counters/
Diff: main.cpp
- Revision:
- 9:ac5faab540da
- Parent:
- 8:651bfebc5f39
--- a/main.cpp Sun May 17 04:20:22 2015 +0000 +++ b/main.cpp Mon Jan 13 07:46:07 2020 +0000 @@ -1,358 +1,117 @@ /* * mbed Application program / Frequency Counter * - * Copyright (c) 2014-2015 Kenji Arai / JH1PJL - * http://www.page.sannet.ne.jp/kenjia/index.html - * http://mbed.org/users/kenjiArai/ - * Created: October 18th, 2014 - * Revised: May 17th, 2015 + * Copyright (c) 2014,'15,'20 Kenji Arai / JH1PJL + * http://www7b.biglobe.ne.jp/~kenjia/ + * https://os.mbed.com/users/kenjiArai/ + * Created: October 18th, 2014 + * Revised: January 13th, 2020 * - * 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. */ -#define USE_COM // use Communication with PC(UART) -//#define USE_TEXT_LCD // use Text LCD/I2C Interface -//#define USE_GRAP_LCD // use Grafic LCD/SPI interface +/* + checked on + Nucleo-F401RE, F411RE & F446RE + */ -// Include --------------------------------------------------------------------------------------- +// Include -------------------------------------------------------------------- #include "mbed.h" #include "freq_counter.h" -#if defined(USE_TEXT_LCD) -#include "TextLCD.h" // Std. lib./ LCD control -#endif -#if defined(USE_GRAP_LCD) -#include "ST7565_SPI_LCD.h" -#endif -// Definition ------------------------------------------------------------------------------------ -#ifdef USE_COM -#define BAUD(x) pc.baud(x) -#define GETC(x) pc.getc(x) -#define PUTC(x) pc.putc(x) -#define PRINTF(...) pc.printf(__VA_ARGS__) -#define READABLE(x) pc.readable(x) -#else -#define BAUD(x) {;} -#define GETC(x) {;} -#define PUTC(x) {;} -#define PRINTF(...) {;} -#define READABLE(x) {;} -#endif - -#if defined(TARGET_LPC1768) - -// LPC1768 Frequency example -// Outout mbed's "PWM6" pin to 96MHZ/19 = 5.052MHz (Approx) -#define CLK_REFRENCE() PWM6_SETCLK(19) -// Outout mbed's "PWM6" pin to 96MHZ/96 = 1.000MHz (Approx) -//#define CLK_REFRENCE() PWM6_SETCLK(96) - -#elif defined(TARGET_LPC1114) - -#define led_not_zero temp_ram -#define led_01 temp_ram -#define led_10 temp_ram -#define CLK_REFRENCE() clock_out() -#warning "Don't forget LPC1114 runs with internal clock. Measurement data is not accurate!!" - -#elif defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) - -#define led_not_zero temp_ram -#define led_01 temp_ram -#define led_10 temp_ram -#define CLK_REFRENCE() port_mco1_mco2_set() - -#else -#error "No support for this CPU" -#endif - -// Object ---------------------------------------------------------------------------------------- -#if defined(TARGET_LPC1768) - -DigitalOut led_gate(LED1); -DigitalOut led_not_zero(LED2); -DigitalOut led_01(LED3); -DigitalOut led_10(LED4); -DigitalIn sw_01(p19); -DigitalIn sw_10(p20); +// Definition ----------------------------------------------------------------- +#define GATE_TIME 1.0f +// Object --------------------------------------------------------------------- +DigitalOut led(LED1); +// PA_8 & PC_9 uses for MCO_1 % MCO_2 -> Clock output for checking +DigitalOut osc1(PA_8); +DigitalOut osc2(PC_9); Serial pc(USBTX, USBRX); -I2C i2cBus(p9, p10); // SDA, SCL -#if defined(USE_TEXT_LCD) -TextLCD_I2C_N lcd(&i2cBus, 0x7c, TextLCD::LCD8x2); // LCD(Akizuki AQM0802A) -#endif -#if defined(USE_GRAP_LCD) -ST7565 glcd(p5, p7, p19, p8, p20, ST7565::AD12864SPI); // mosi, sck, reset, a0, ncs -#endif -PwmOut fmclck(p21); // for RESERVE pin21 as PWM1[6] -F_COUNTER fc(p30); - -#elif defined(TARGET_LPC1114) +F_COUNTER fc(PA_0, GATE_TIME); +//F_COUNTER fc(PA_1, GATE_TIME); +//F_COUNTER fc(PB_3, GATE_TIME); -DigitalOut led_gate(LED2); -DigitalIn sw_01(dp25); -DigitalIn sw_10(dp26); -Serial pc(dp16,dp15); // Communication with Host -I2C i2cBus(dp5,dp27); // SDA, SCL -#if defined(USE_TEXT_LCD) -TextLCD_I2C_N lcd(&i2cBus, 0x7c, TextLCD::LCD8x2); // LCD(Akizuki AQM0802A) -#endif -#if defined(USE_GRAP_LCD) -ST7565 glcd(dp2, dp6, dp10, dp4, dp9, ST7565::AQM1248A); // mosi, sck, reset, a0, ncs -#endif -F_COUNTER fc(dp14); -// dp24 uses for CLOCKOUT -> Clock output for checking -#elif defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) +// RAM ------------------------------------------------------------------------ -DigitalOut led_gate(LED1); -DigitalIn sw_01(PC_0); -DigitalIn sw_10(PC_1); -Serial pc(USBTX, USBRX); -I2C i2cBus(PB_9,PB_8); // SDA, SCL -#if defined(USE_TEXT_LCD) -TextLCD_I2C_N lcd(&i2cBus, 0x7c, TextLCD::LCD8x2); // LCD(Akizuki AQM0802A) -#endif -#if defined(USE_GRAP_LCD) -ST7565 glcd(PB_5, PB_3, PA_10, PB_10, PA_9, ST7565::AD12864SPI); // mosi, sck, reset, a0, ncs -#endif -F_COUNTER fc(PA_0); -// PA8 & PC9 uses for MCO_1 % MCO_2 -> Clock output for checking - -#else -#error "No support for this CPU" -#endif +// ROM / Constant data -------------------------------------------------------- +const float gate_time_select[] = {1.0f, 2.0f, 5.0f, 10.0f, 0.5f, 0.1f}; -// RAM ------------------------------------------------------------------------------------------- -float freqency; -double t_gate; -uint8_t sw; - -uint32_t temp_ram; // dummy ram (please keep it!) - -// ROM / Constant data --------------------------------------------------------------------------- +// Function prototypes -------------------------------------------------------- +void port_mco1_mco2_set(void); -// Function prototypes --------------------------------------------------------------------------- -void read_sw_and_set_gate_time(void); -#if defined(TARGET_LPC1768) -void PWM6_SETCLK(int div); -#endif -#if defined(TARGET_LPC1114) -void clock_out(void); -#endif -#if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) -void port_mco1_mco2_set(void); -#endif - -//------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ // Control Program -//------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ int main() { - PRINTF("\r\nFrequency Counter by JH1PJL created on "__DATE__"\r\n"); - t_gate = 1.0; - // Initialize LCD -#if defined(USE_TEXT_LCD) - lcd.locate(0, 0); // 1st line top - // 12345678 - lcd.printf("Fre-Cntr"); - lcd.locate(0, 1); // 2nd line top - // 12345678 - lcd.puts(" JH1PJL "); - lcd.setContrast(0x16); -#endif -#if defined(USE_GRAP_LCD) - glcd.cls(); - glcd.locate(0, 0); - glcd.printf("--- Frequency Counter --\r\n"); - glcd.printf(" Kenji Arai / JH1PJL\r\n" ); - glcd.printf(" \r\n"); -#if defined(TARGET_LPC1768) - glcd.set_contrast(0x06); - glcd.printf(" Input: P30 PWM out: P21\r\n" ); - glcd.printf(" LED1:Gate LED2:signal \r\n" ); -#elif defined(TARGET_LPC1114) - glcd.set_contrast(0x01); - glcd.printf(" LED2:Gate " ); -#elif defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) - glcd.set_contrast(0x06); - glcd.printf(" Input: PA0 PWM out: PA8\r\n" ); - glcd.printf(" LED1:Gate \r\n" ); -#else -#error "No support for this CPU" -#endif -#endif // defined(USE_GRAP_LCD) -#if defined(USE_TEXT_LCD) - wait(5.0); - lcd.locate(0, 1); // 2nd line top - // 12345678 - lcd.puts(" "); -#endif - // Set Internalclock for reference - CLK_REFRENCE(); - freqency = 0; + pc.printf("\r\nStart Frequency Counter\r\n"); + port_mco1_mco2_set(); // Set Internalclock for reference + float t_gate = GATE_TIME; + float freqency = 0; + uint32_t pin = fc.read_pin(); + pc.printf("Signal input pin "); + if (pin == PA_0) { + pc.printf("= PA_0(A0)\r\n"); + } else if (pin == PA_1) { + pc.printf("= PA_1(A1)\r\n"); + } else if (pin == PB_3) { + pc.printf("= PB_3(D3)\r\n"); + } else { + pc.printf("is NOT correct!!\r\n"); + } + uint32_t size_of_table = sizeof(gate_time_select) / sizeof(float); + pc.printf("# of parameter %d\r\n", size_of_table); while(true) { - led_gate = 1; - freqency = (float)fc.read_frequency(t_gate); - led_gate = 0; - wait(1.1 - t_gate); - if (freqency == 0) { - led_not_zero = 1; - } else { - led_not_zero = 0; - } - read_sw_and_set_gate_time(); - PRINTF("f= %9.0f [Hz], gate= %4.3f [Sec]\r\n", freqency/t_gate, t_gate); -#if defined(USE_TEXT_LCD) - lcd.locate(0, 0); // 1st line top - lcd.printf("%8.0f", freqency); - lcd.locate(0, 1); // 2nd line top -#endif -#if defined(USE_GRAP_LCD) - glcd.locate(0, 10); - glcd.printf(" \r\n"); - glcd.locate(10, 10); - glcd.printf("%8.0f Hz", freqency); - glcd.locate(10, 20); -#endif - switch (sw) { - case 0: -#if defined(USE_TEXT_LCD) - // 12345678 - lcd.printf("x1000 Hz"); -#endif -#if defined(USE_GRAP_LCD) - glcd.printf(" x1000 "); -#endif - break; - case 1: -#if defined(USE_TEXT_LCD) - // 12345678 - lcd.printf("x100 Hz"); -#endif -#if defined(USE_GRAP_LCD) - glcd.printf(" x100 "); -#endif - break; - case 2: -#if defined(USE_TEXT_LCD) - // 12345678 - lcd.printf("x10 Hz"); -#endif -#if defined(USE_GRAP_LCD) - glcd.printf("x10 "); -#endif - break; - case 3: - default: -#if defined(USE_TEXT_LCD) - // 12345678 - lcd.printf("x1 Hz"); -#endif -#if defined(USE_GRAP_LCD) - glcd.printf(" x1 "); -#endif - break; + for (uint32_t i = 0; i < size_of_table; i++) { + t_gate = gate_time_select[i]; + pc.printf("Change gate time : %5.2f [Sec]\r\n", t_gate); + fc.set_gate_time(t_gate); + for (uint32_t i = 0; i < 5; i++) { + led = !led; + freqency = (float)fc.read_frequency() / t_gate; + pc.printf("f= %10.0f [Hz], gate= %5.2f [Sec]\r\n", + freqency, t_gate); + } } } } -void read_sw_and_set_gate_time(void) -{ - if (sw_10) { - led_10 = 1; - sw = 2; - } else { - led_10 = 0; - sw = 0; - } - if (sw_01) { - led_01 = 1; - sw += 1; - } else { - led_01 = 0; - } - switch (sw) { - case 0: - t_gate = 0.001; - break; - case 1: - t_gate = 0.01; - break; - case 2: - t_gate = 0.1; - break; - case 3: - default: - t_gate = 1.0; - break; - } -} - -#if defined(TARGET_LPC1768) - -// 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 -} - -#elif defined(TARGET_LPC1114) - -// CLOCKOUT from pin24(dp18) -// Freq = 48MHz/4 = 12MHz -void clock_out(void) -{ - LPC_SYSCON->CLKOUTCLKSEL = 3; // System clock - LPC_SYSCON->CLKOUTDIV = 4; // div 1/4 - LPC_IOCON->PIO0_1 = 1; // select CLKOUT to P0_1(pin24)/dp18 - LPC_SYSCON->CLKOUTUEN = 1; // enable output -} - -#elif defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) - void port_mco1_mco2_set(void) { uint32_t temp = 0x00; - // PA8 -> MCO_1 + SystemCoreClockUpdate(); + // PA_8 -> MCO_1 temp = ((uint32_t)(GPIO_AF0_MCO) << (((uint32_t)8 & (uint32_t)0x07) * 4)) ; - GPIOA->AFR[8 >> 3] &= ~((uint32_t)0xf << ((uint32_t)(8 & (uint32_t)0x07) * 4)) ; + GPIOA->AFR[8 >> 3] &= + ~((uint32_t)0xf << ((uint32_t)(8 & (uint32_t)0x07) * 4)) ; GPIOA->AFR[8 >> 3] |= temp; GPIOA->MODER &= ~(GPIO_MODER_MODER0 << (8 * 2)); GPIOA->MODER |= (0x2 << (8 * 2)); GPIOA->OSPEEDR |= (0x03 << (8 * 2)); // High speed - // PC9 -> MCO_2 + // PC_9 -> MCO_2 temp = ((uint32_t)(GPIO_AF0_MCO) << (((uint32_t)9 & (uint32_t)0x07) * 4)) ; - GPIOC->AFR[9 >> 3] &= ~((uint32_t)0xf << ((uint32_t)(9 & (uint32_t)0x07) * 4)) ; + GPIOC->AFR[9 >> 3] &= + ~((uint32_t)0xf << ((uint32_t)(9 & (uint32_t)0x07) * 4)) ; GPIOC->AFR[9 >> 3] |= temp; GPIOC->MODER &= ~(GPIO_MODER_MODER0 << (9 * 2)); GPIOC->MODER |= (0x2 << (9 * 2)); GPIOC->OSPEEDR |= (0x03 << (9 * 2)); // High speed // Select output clock source RCC->CFGR &= 0x009fffff; -#if 0 - // MC0_1 output HSE 1/4, MCO_2 output SYSCLK 1/4 + pc.printf("System clock = %d [Hz], HSE = %d [Hz]\r\n", + SystemCoreClock, HSE_VALUE); +#if 1 + // MCO_1 output HSE 1/4, MCO_2 output SYSCLK 1/4 // MCO2 MCO2PRE MCO1PRE MCO1 RCC->CFGR |= (0x0 << 30) + (0x6 << 27) + (0x6 << 24) + (0x3 << 22); + pc.printf("PA_8(MCO_1) = %d [Hz], PC_9(MCO_2) = %d [Hz]\r\n", + HSE_VALUE / 4, SystemCoreClock / 4); #else - // MC0_1 output HSE 1/1, MCO_2 output SYSCLK 1/2 + // MCO_1 output HSE 1/1, MCO_2 output SYSCLK 1/2 // MCO2 MCO2PRE MCO1PRE MCO1 RCC->CFGR |= (0x0 << 30) + (0x4 << 27) + (0x0 << 24) + (0x3 << 22); + pc.printf("PA_8(MCO_1) = %d [Hz], PC_9(MCO_2) = %d [Hz]\r\n", + HSE_VALUE, SystemCoreClock / 2); #endif } - -#else -#error "No support for this CPU" -#endif \ No newline at end of file