Only for mbed LPC1768, mbed LPC1114FN28, Nucleo-F401 and Nucleo-F411. No way to change pin assign.
Dependencies: freq_counter TextLCD
Fork of 5MHzOSC by
Please refer following page.
http://developer.mbed.org/users/kenjiArai/notebook/simple-frequency-counter/
/users/kenjiArai/notebook/frequency-counters/
main.cpp
- Committer:
- kenjiArai
- Date:
- 2020-08-04
- Revision:
- 9:0b84a8ce225a
- Parent:
- 8:651bfebc5f39
File content as of revision 9:0b84a8ce225a:
/* * mbed Application program / Frequency Counter * * 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: August 4th, 2020 */ //#define USE_TEXT_LCD // use Text LCD/I2C Interface #include "mbed.h" #include "freq_counter.h" #define GATE_TIME_10SEC 10000000 #define GATE_TIME_1SEC 1000000 #define GATE_TIME_100MS 100000 #define GATE_TIME_10MS 10000 #define GATE_TIME GATE_TIME_1SEC extern void print_revision(void); // LPC1768 --------------------------------------------------------------------- #if defined(TARGET_LPC1768) // LPC1768 Frequency example // Ref Clock output -> "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) DigitalOut led_gate(LED1); I2C i2cBus(p9, p10); // SDA, SCL PwmOut fmclck(p21); // for RESERVE pin21 as PWM1[6] F_COUNTER fc(p30); void PWM6_SETCLK(int div); // LPC1114 --------------------------------------------------------------------- #elif defined(TARGET_LPC1114) // LPC1114 Frequency example // Ref Clock output -> "dp24" pin as CLOCKOUT DigitalOut led_gate(LED2); I2C i2cBus(dp5,dp27); // SDA, SCL F_COUNTER fc(dp14); void clock_out(void); # define CLK_REFRENCE() clock_out() # warning "Don't forget LPC1114 runs with internal clock." # warning "Measurement data is not accurate!!" // STM32 / Nucleo -------------------------------------------------------------- #elif defined(TARGET_NUCLEO_F401RE)\ || defined(TARGET_NUCLEO_F411RE)\ || defined(TARGET_NUCLEO_F446RE) // STM32 Frequency example // Ref Clock output -> "PC_9" pin as MCO2 System clock / 4 DigitalOut led_gate(LED1); I2C i2cBus(PB_9,PB_8); // SDA, SCL F_COUNTER fc(PA_0); void port_mco2_set(void); # define CLK_REFRENCE() port_mco2_set() // Other CPU's ----------------------------------------------------------------- #else # error "No support for your CPU" #endif // Only for LCD control ------------------------------------------------------- #if defined(USE_TEXT_LCD) #include "TextLCD.h" // Std. lib./ LCD control // LCD(Akizuki AQM0802A) TextLCD_I2C_N lcd(&i2cBus, 0x7c, TextLCD::LCD8x2); void lcd_onotialize(void); void display_on_lcd(float freqency, uint32_t t_gate); # define LCD_INITIALIZE() lcd_onotialize() # define DISPLAY_ON_LCD(x,y) display_on_lcd(x,y) #else # define LCD_INITIALIZE() {;} # define DISPLAY_ON_LCD(x,y) {;} #endif //------------------------------------------------------------------------------ // Control Program //------------------------------------------------------------------------------ int main() { float freqency; uint32_t t_gate; print_revision(); printf("\r\nFrequency Counter by JH1PJL created on " __DATE__ "\r\n"); // lcd LCD_INITIALIZE(); // Set Internalclock for reference CLK_REFRENCE(); while(true) { led_gate = 1; t_gate = GATE_TIME; freqency = (float)fc.read_frequency(t_gate); led_gate = 0; printf("f= %9.0f [Hz], gate= %4.3f [Sec]\r\n", freqency, (float)t_gate / 1e6); DISPLAY_ON_LCD(freqency, t_gate); } } #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) { // 1)Reset counter, disable PWM LPC_PWM1->TCR = (1 << 1); LPC_SC->PCLKSEL0 &= ~(0x3 << 12); // 2)Set peripheral clock divider to /1, i.e. system clock LPC_SC->PCLKSEL0 |= (1 << 12); // 3)Match Register 0 is shared period counter for all PWM1 LPC_PWM1->MR0 = div - 1; LPC_PWM1->MR6 = (div + 1)>> 1; // 4)Start updating at next period start LPC_PWM1->LER |= 1; // 5)Enable counter and PWM LPC_PWM1->TCR = (1 << 0) + (1 << 3); printf("Set pin21(PWM6) for clock output\r\n"); } #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 printf("Set P0_1(pin24)/dp18 for clock output\r\n"); } #elif defined(TARGET_NUCLEO_F401RE)\ || defined(TARGET_NUCLEO_F411RE)\ || defined(TARGET_NUCLEO_F446RE) void port_mco2_set(void) { // PC9 -> MCO_2 DigitalOut dumy1(PC_9); uint32_t 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] |= 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; // MCO_2 output SYSCLK 1/4 // MCO2 MCO2PRE RCC->CFGR |= (0x0 << 30) + (0x6 << 27); printf("Set PC9 for clock output\r\n"); } #else # error "No support for your CPU" #endif #if defined(USE_TEXT_LCD) void lcd_onotialize(void) { // Initialize 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.setCursor(TextLCD::CurOff_BlkOff); lcd.setContrast(0x16); thread_sleep_for(5000); lcd.locate(0, 1); // 2nd line top // 12345678 lcd.puts(" "); } void display_on_lcd(float freqency, uint32_t t_gate) { lcd.locate(0, 0); // 1st line top lcd.printf("%8.0f", freqency); lcd.locate(0, 1); // 2nd line top switch (t_gate) { case GATE_TIME_10SEC: // 12345678 lcd.printf("Hz x0.1"); break; case GATE_TIME_1SEC: // 12345678 lcd.printf("Hz x1"); break; case GATE_TIME_100MS: // 12345678 lcd.printf("Hz x10"); break; case GATE_TIME_10MS: // 12345678 lcd.printf("Hz x100"); break; default: // 12345678 lcd.printf("Hz gate?"); break; } } #endif