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 fuyuno sakura

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

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