Frequency counter library using GPS 1PPS signal and temperature controlled 50MHz Base clock. Ported from F411 Frequency Counter.
Dependents: Frequency_Cntr_1PPS_F746ZG
Fork of Frq_cuntr_full by
Please refer following.
/users/kenjiArai/notebook/frequency-counters/
frq_cuntr_full.h
- Committer:
- kenjiArai
- Date:
- 2014-11-22
- Revision:
- 1:102230f2879d
- Parent:
- 0:bfdc6ed58a06
- Child:
- 2:194f82ad3041
File content as of revision 1:102230f2879d:
/* * 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 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 * 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. */ #ifndef MBED_FRQ_CUNTR #define MBED_FRQ_CUNTR #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 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); /** 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