Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: Frequency_Cntr_1PPS_F746ZG
Fork of Frq_cuntr_full by
Diff: frq_cuntr_full.h
- Revision:
- 1:102230f2879d
- Parent:
- 0:bfdc6ed58a06
- Child:
- 2:194f82ad3041
--- a/frq_cuntr_full.h Sat Nov 22 04:01:41 2014 +0000
+++ b/frq_cuntr_full.h Sat Nov 22 23:02:39 2014 +0000
@@ -1,13 +1,14 @@
/*
- * mbed Application program / Frequency Counter with GPS 1PPS Compensation
+ * mbed Library / Frequency Counter with GPS 1PPS Compensation
* Frequency Counter Hardware relataed program
+ * Only for ST Nucleo F411RE
*
* Copyright (c) 2014 Kenji Arai / JH1PJL
* http://www.page.sannet.ne.jp/kenjia/index.html
* http://mbed.org/users/kenjiArai/
* Additional functions and modification
* started: October 18th, 2014
- * Revised: Nobember 22nd, 2014
+ * Revised: Nobember 23rd, 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
@@ -21,105 +22,163 @@
#include "mbed.h"
+#define DEBUG // use Communication with PC(UART)
+/*
+ CAUTION:
+ If you select internal clock (100MHz), you need consider PLL clock behavior.
+ PLL clock drifts over 60Hz (increase frequency) within 30 to 40 second
+ then suddenly back to low frequency and increase again.
+ Even you prepare precision external clock, this frequency drift cannot avoid.
+ */
+#define BASE_EXTERNAL_CLOCK
+
namespace Frequency_counter
{
- #define DEBUG // use Communication with PC(UART)
- #define IRQ_DRIVE
- //#define BASE_EXTERNAL_CLOCK
-
- #if defined(BASE_EXTERNAL_CLOCK)
- #define CNT_UPPER (0xffffffff - 100)
- #define CNT_LOWER (0 + 100)
- //#define CNT_UPPER (30000000 + 1000000)
- //#define CNT_LOWER (30000000 - 1000000)
- #else
- #define CNT_UPPER (0xffffffff - 100)
- #define CNT_LOWER (0 + 100)
- //#define CNT_UPPER (100000000 - 100000)
- //#define CNT_LOWER (100000000 + 100000)
- #endif
-
- #if defined(BASE_EXTERNAL_CLOCK)
- #define ONE_SECOND_COUNT 0xe4e1c0
- #else
- #define ONE_SECOND_COUNT 0x2faf080
- #endif
-
- #define CNT_BF_SIZE 120
-
- //#if defined(IRQ_DRIVE)
- // 1PPS data
- extern uint32_t onepps_cnt[CNT_BF_SIZE];
- extern uint32_t onepps_num;
- extern uint64_t onepps_cnt_avarage;
- extern uint8_t onepps_buf_full;
- extern uint8_t onepps_ready_flg;
- // TIM2
- extern uint8_t tim2_ready_flg;
- extern uint32_t tim2_cnt_data;
- extern uint32_t tim2_old_cnt_data;
- // TIM3+4
- extern uint8_t tim3p4_ready_flg;
- extern uint32_t tim3p4_cnt_data;
- extern uint32_t tim3p4_old_cnt_data;
-
- // TIM2 IC2 Interrupt control
- void irq_ic2_TIM2(void);
- // TIM3 IC2 Interrupt control (same signal connected to TIM4 IC1)
- void irq_ic2_TIM3P4(void);
+#define CNT_BASE 29999978 // 30MHz
+#define CNT_FIX_BASE 600000 // 0.03sec
+
+#if defined(BASE_EXTERNAL_CLOCK)
+#define CNT_UPPER (CNT_BASE + 20)
+#define CNT_LOWER (CNT_BASE - 20)
+#else
+#define CNT_UPPER (0xffffffff - 100)
+#define CNT_LOWER (0 + 100)
+#endif
+
+#if defined(BASE_EXTERNAL_CLOCK)
+#define ONE_SECOND_COUNT (CNT_BASE - CNT_FIX_BASE)
+#else
+#define ONE_SECOND_COUNT 0x2faf080 // 50MHz
+#endif
+
+#define CNT_BF_SIZE 120 // 1PPS data save size
+
+/** Frequency Counter program
+ * Only for ST Nucleo F411RE Board
+ *
+ * @code
+ * #include "mbed.h"
+ *
+ * // PC_6,PC_7 & PB6 use for Timer3 & 4(16+16bit)
+ * // PA_0,PA_1 & PB10 use for Timer2(32bit)
+ * FRQ_CUNTR fc(PC_6, 1.0); // Input port(Fixed) & gate time[sec]
+ *
+ * int main() {
+ * // This is for test purpose
+ * fc.port_mco1_mco2_set(2); // Clk/2 ->1/1(100MHz) cannot measure!!
+ * fc.read_frequency_TIM2(1.0); // read TIM2 source frequency (test)
+ * fc.read_frequency_TIM3P4(1.0); // read TIM3 source frequency (test)
+ * while(true) {
+ * while (fc.status_1pps() == 0) {;}
+ * counter_1pps = fc.read_avarage_1pps();
+ * while (fc.status_freq_update() == 0) {;}
+ * new_frequency = fc.read_freq_data();
+ * print("1PPS/ave = %9d , FREQUENCY = %9d\r\n", counter_1pps, new_frequency);
+ * }
+ * }
+ * @endcode
+ */
+
+class FRQ_CUNTR
+{
+public:
+ /** Configure data pin (Not changeable)
+ * @param Freq. input pin
+ */
+ FRQ_CUNTR(PinName f_in, double gt);
+
+ /** Set gate time
+ * @param gate time [sec]
+ * @return !=0: new data is avairable, 0: not yet
+ */
+ double set_gate_time(double gt);
+
+ /** Read status (new frequency data is available or not)
+ * @param none
+ * @return !=0: new data is avairable, 0: not yet
+ */
+ uint32_t status_freq_update(void);
+
+ /** Read new frequency data
+ * @param none
+ * @return frequency data
+ */
+ uint32_t read_freq_data(void);
- class FRQ_CUNTR
- {
- public:
-
- FRQ_CUNTR(PinName f_in);
-
- void initialize_Freq_counter(void);
-
- // Read TIM2 captured counter value
- uint32_t read_ic2_counter_TIM2(void);
-
- // Check TIM2 IC2 status
- uint32_t check_ic2_status_TIM2(void);
-
- // Read TIM3+4(as 32bit) captured counter value
- uint32_t read_ic2_counter_TIM3P4(void);
-
- // Check TIM3 IC2 & TIM4 IC1 status
- uint32_t check_ic2_status_TIM3P4(void);
-
- // Avarage measued data GPS 1PPS by 50MHz Internal Clock
- void avarage_1pps(void);
-
- // Frequency check for test purpose
- uint32_t read_frequency_TIM2(float gate_time);
- uint32_t read_frequency_TIM3P4(float gate_time);
-
- // Clock output for test purpose
- void port_mco1_mco2_set(uint8_t select);
-
- protected:
- DigitalIn _pin;
-
- // Initialize TIM2
- // Internal clock (50MHz) and IC2 for GPS 1pps signal measurement
- void initialize_TIM2(void);
-
- // Initialize TIM3 and TIM4 as 32bit counter (TIM3(16bit) + TIM4(16bit))
- // TIM3 clock input is unkown freq.(measuring freq.) and TIM4 is slave counter
- // 1sec gate signal connected both TIM3 IC2 and TIM4 IC1
- void initialize_TIM3P4(void);
-
- private:
- #if defined(IRQ_DRIVE)
- // 1PPS data
- uint32_t onepps_cnt[CNT_BF_SIZE];
- uint32_t onepps_num;
- uint64_t onepps_cnt_avarage;
- uint8_t onepps_buf_full;
- uint8_t onepps_ready_flg;
- #endif
- };
+ /** Read avarage measued data GPS 1PPS
+ * @param none
+ * @return Frequency
+ */
+ uint32_t read_avarage_1pps(void);
+
+ /** Read status (new 1PPS data is available or not)
+ * @param none
+ * @return !=0: new data is avairable, 0: not yet
+ */
+ uint32_t status_1pps(void);
+
+ /** This is a test purpose function
+ * Check PA0 pin input or internal clock frequency
+ * @param none
+ * @return Frequency
+ */
+ uint32_t read_frequency_TIM2(float gate_time);
+
+ /** This is a test purpose function
+ * Check PC6 pin input frequency
+ * @param none
+ * @return Frequency
+ */
+ uint32_t read_frequency_TIM3P4(float gate_time);
+
+ /** This is a test purpose function
+ * Output clock from pin PA8 & PC9 uses for MCO_1 & MCO_2
+ * @param none
+ * @return none
+ */
+ void port_mco1_mco2_set(uint8_t select);
+
+protected:
+ DigitalIn _pin;
+
+ void initialize_Freq_counter(void); // Initialize timers
+ // Internal clock (50MHz) and IC2 for GPS 1pps signal measurement
+ void initialize_TIM2(void);
+ // Initialize TIM3 and TIM4 as 32bit counter (TIM3(16bit) + TIM4(16bit))
+ void initialize_TIM3P4(void);
+ uint32_t set_1PPS_data(void); // Set GPS 1PPS counter value
+ uint32_t read_ic2_counter_TIM2(void); // Read TIM2 captured counter value
+ uint32_t check_ic2_status_TIM2(void); // Check TIM2 IC2 status
+ uint32_t read_ic2_counter_TIM3P4(void); // Read TIM3+4(as 32bit) captured counter value
+ uint32_t check_ic2_status_TIM3P4(void); // Check TIM3 IC2 & TIM4 IC1 status
+ uint8_t read_oc_port_status(void); // Check TIM2 OC port
+
+private:
+ // TIM2
+ double gate_time;
+ uint32_t counter_tim2;
+ uint32_t old_cntr_tim2;
+ // TIM3+4
+ uint32_t counter_tim3p4;
+ uint32_t old_cntr_tim3p4;
+ // 1PPS data
+ uint32_t onepps_newest;
+ uint32_t onepps_cnt[CNT_BF_SIZE];
+ uint32_t onepps_num;
+ uint64_t onepps_cnt_avarage;
+ uint8_t onepps_buf_full;
+ uint8_t onepps_ready_flg;
+};
+
+/*
+ Interrupt handler does NOT work following code
+ NVIC_SetVector(TIM2_IRQn, (uint32_t)FRQ_CUNTR::irq_ic2_TIM2);
+ From this reason, I wrote below code and set interrupt handler out side "FRQ_CUNTR" class
+ NVIC_SetVector(TIM2_IRQn, (uint32_t)irq_ic2_TIM2);
+ */
+void irq_ic2_TIM2(void); // TIM2 IC2 Interrupt control
+void irq_ic2_TIM3P4(void); // TIM3 IC2 Interrupt control (same signal connected to TIM4 IC1)
+
} // Frequency_counter
-#endif // MBED_FRQ_CUNTR
+#endif // MBED_FRQ_CUNTR
