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/
Diff: main.cpp
- Revision:
- 9:0b84a8ce225a
- Parent:
- 8:651bfebc5f39
--- a/main.cpp Sun May 17 04:20:22 2015 +0000 +++ b/main.cpp Tue Aug 04 03:59:57 2020 +0000 @@ -1,294 +1,115 @@ /* * 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/ + * 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: May 17th, 2015 - * - * 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. + * Revised: August 4th, 2020 */ -#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 -// 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 + +#define GATE_TIME_10SEC 10000000 +#define GATE_TIME_1SEC 1000000 +#define GATE_TIME_100MS 100000 +#define GATE_TIME_10MS 10000 -// 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 +#define GATE_TIME GATE_TIME_1SEC +extern void print_revision(void); + +// LPC1768 --------------------------------------------------------------------- #if defined(TARGET_LPC1768) // LPC1768 Frequency example -// Outout mbed's "PWM6" pin to 96MHZ/19 = 5.052MHz (Approx) -#define CLK_REFRENCE() PWM6_SETCLK(19) +// 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) -#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); -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) +// LPC1114 Frequency example +// Ref Clock output -> "dp24" pin as CLOCKOUT 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 +I2C i2cBus(dp5,dp27); // SDA, SCL F_COUNTER fc(dp14); -// dp24 uses for CLOCKOUT -> Clock output for checking + +void clock_out(void); +# define CLK_REFRENCE() clock_out() +# warning "Don't forget LPC1114 runs with internal clock." +# warning "Measurement data is not accurate!!" -#elif defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) +// 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); -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 + +void port_mco2_set(void); +# define CLK_REFRENCE() port_mco2_set() +// Other CPU's ----------------------------------------------------------------- #else -#error "No support for this CPU" +# error "No support for your CPU" #endif -// RAM ------------------------------------------------------------------------------------------- -float freqency; -double t_gate; -uint8_t sw; - -uint32_t temp_ram; // dummy ram (please keep it!) - -// ROM / Constant data --------------------------------------------------------------------------- - -// 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); +// 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() { - 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 + 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(); - freqency = 0; while(true) { led_gate = 1; + t_gate = GATE_TIME; 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; - } - } -} - -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; + printf("f= %9.0f [Hz], gate= %4.3f [Sec]\r\n", + freqency, (float)t_gate / 1e6); + DISPLAY_ON_LCD(freqency, t_gate); } } @@ -299,13 +120,19 @@ // 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 + // 1)Reset counter, disable PWM + LPC_PWM1->TCR = (1 << 1); 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 + // 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) @@ -318,41 +145,81 @@ 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) - -void port_mco1_mco2_set(void) -{ - uint32_t temp = 0x00; +#elif defined(TARGET_NUCLEO_F401RE)\ + || defined(TARGET_NUCLEO_F411RE)\ + || defined(TARGET_NUCLEO_F446RE) - // PA8 -> 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] |= temp; - GPIOA->MODER &= ~(GPIO_MODER_MODER0 << (8 * 2)); - GPIOA->MODER |= (0x2 << (8 * 2)); - GPIOA->OSPEEDR |= (0x03 << (8 * 2)); // High speed +void port_mco2_set(void) +{ // PC9 -> 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)) ; + 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; -#if 0 - // MC0_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); -#else - // MC0_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); -#endif + // 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 this CPU" +# 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 \ No newline at end of file