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/

Revision:
5:af9fa3d0731c
Parent:
4:e7d16ef216d4
Child:
6:44c2bcbdd77b
diff -r e7d16ef216d4 -r af9fa3d0731c main.cpp
--- a/main.cpp	Tue Jun 18 14:18:04 2013 +0000
+++ b/main.cpp	Sun Oct 19 06:45:13 2014 +0000
@@ -1,63 +1,181 @@
-//
-//  CLOCK OUT to PWM1[6] Sample with Freq Counter using Cap2.0 
-//  For LPC1768-mbed
-//
-//  Reference: 5MHz Clock Out Code and Comment - http://mbed.org/forum/mbed/topic/733/
-//
-//  !! To Self Measurement Output Clock, Connect p21 <-> p30 with jumper wire.
-//  2013.6.18 : Wrong comment about MR6 and Duty fix.
-//
+/*
+ * mbed Application program / Frequency Counter
+ *
+ * Copyright (c) 2014 Kenji Arai / JH1PJL
+ *  http://www.page.sannet.ne.jp/kenjia/index.html
+ *  http://mbed.org/users/kenjiArai/
+ *      Created: October   18th, 2014
+ *      Revised: October   19th, 2014
+ *
+ * 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.
+ */
 
+//  Include ---------------------------------------------------------------------------------------
 #include "mbed.h"
+#include "TextLCD.h"            // Std. lib./ LCD control
+#include "freq_counter.h"
 
-PwmOut fmclck(p21);     // for RESERVE pin21 as PWM1[6]
-DigitalIn clkin(p30);   // for RESERVE pin30 as CAP2[0]
+//  Definition ------------------------------------------------------------------------------------
+#define USE_COM         // use Communication with PC(UART)
 
-// Reset Counter and Count Start
-void P30_RESET_CTR(void)
-{
-    LPC_TIM2->TCR = 2;             // Reset the counter (bit1<=1,bit0<=0)
-    LPC_TIM2->TCR = 1;             // UnReset counter (bit1<=0,bit0<=1)
-}
+#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
 
-// Get Counter Value
-int P30_GET_CTR(void)
-{
-    return LPC_TIM2->TC; // Read the counter value
-}
+// LPC1768 Frequency example
+// Outout mbed's "PWM6" pin to 96MHZ/19 = 5.052MHz (Approx)
+#define PWM_EAMPLE()    PWM6_SETCLK(19)
+// Outout mbed's "PWM6" pin to 96MHZ/96 = 1.000MHz (Approx)
+//#define PWM_EAMPLE()    PWM6_SETCLK(96)
+  
+//  Object ----------------------------------------------------------------------------------------
+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
+TextLCD_I2C_N lcd(&i2cBus, 0x7c, TextLCD::LCD8x2);  // LCD(Akizuki AQM0802A)
+PwmOut fmclck(p21);                 // for RESERVE pin21 as PWM1[6]
+F_COUNTER fc(p30);
 
-// Setting p30 to Cap2.0
-void P30_INIT_CTR(void)
-{
-    LPC_SC->PCONP |= 1 << 22;               // 1)Power up TimerCounter2 (bit22)
-    LPC_PINCON->PINSEL0 |= 3 << 8;          // 2)Set P0[4] to CAP2[0]
-    LPC_TIM2->TCR = 2;                          // 3)Counter Reset (bit1<=1,bit0<=0)
-    LPC_TIM2->CTCR = 1;                     // 4)Count on riging edge Cap2[0]
-    LPC_TIM2->CCR = 0;                                          // 5)Input Capture Disabled
-    LPC_TIM2->TCR = 1;                          // 6)Counter Start (bit1<=0,bit0<=1)
-}
+//  RAM -------------------------------------------------------------------------------------------
+float freqency;
+float t_gate;
+uint8_t sw;
+
+//  ROM / Constant data ---------------------------------------------------------------------------
 
+//  Function prototypes ---------------------------------------------------------------------------
+
+//  Function prototypes ---------------------------------------------------------------------------
+
+//-------------------------------------------------------------------------------------------------
+//  Control Program
+//-------------------------------------------------------------------------------------------------
+#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    
+    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
+}
+#else
+#error "No support for this CPU"
+#endif
+
+void example_freq_out(void)
+{
+    PWM_EAMPLE();
+}
+
+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;
+    }
 }
 
-int main() {        
-    PWM6_SETCLK(19) ; // Outout mbed's "PWM6" pin to 96MHZ/19 = 5.052MHz (Approx)
-    // PWM6_SETCLK(96) ; // Outout mbed's "PWM6" pin to 96MHZ/96 = 1.000MHz (Approx)
-    P30_INIT_CTR();
-    while(1){
-        P30_RESET_CTR();
-        wait(1.0); // Gate time for count
-        printf("pin30 Freq = %d (Hz)\r\n",P30_GET_CTR());
+int main()
+{
+    PRINTF("Frequency Counter by JH1PJL created on "__DATE__"\r\n");
+    t_gate = 1.0;
+    // 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.setContrast(0x16);
+    wait(5.0);
+    lcd.locate(0, 1);    // 2nd line top
+    //        12345678
+    lcd.puts("        ");
+    // Set PWM for example
+    example_freq_out();
+    freqency = 0;
+    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("p30 f = %9.0f [Hz] gate %4.3f [Sec]\r\n", freqency/t_gate, t_gate);
+        lcd.locate(0, 0);    // 1st line top
+        lcd.printf("%8.0f", freqency);
+        lcd.locate(0, 1);    // 2nd line top
+        switch (sw) {
+            case 0:
+                //          12345678
+                lcd.printf("x1000 Hz");
+                break;
+            case 1:
+                //          12345678
+                lcd.printf("x100  Hz");
+                break;
+            case 2:
+                //          12345678
+                lcd.printf("x10   Hz");
+                break;
+            case 3:
+            default:
+                //          12345678
+                lcd.printf("x1    Hz");
+                break;
+        }
     }
 }