![](/media/cache/profiles/f0fcf351df4eb6786e9bb6fc4e2dee02.jpg.50x50_q85.jpg)
Very simple but enough accuracy "Frequency Counter". Using GPS 1PPS signal for 1sec gate. CPU is F746, F446 and F411.
Dependencies: fc_GPS1PPS_f746_f4xx iSerial mbed
Please refer following.
/users/kenjiArai/notebook/frequency-counters/
Concept block are follows.
F746
/media/uploads/kenjiArai/block_diagram_fc_f746_wo_oven.pdf
F411&F446
/media/uploads/kenjiArai/block_diagram_fc_f411_wo_oven.pdf
Hardware Circuit(common F746,F446 and F411)
/media/uploads/kenjiArai/fc_f746ng_circuit.pdf
Diff: main.cpp
- Revision:
- 0:da29cdc50643
diff -r 000000000000 -r da29cdc50643 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Nov 16 13:22:00 2016 +0000 @@ -0,0 +1,285 @@ +/* + * mbed Application program / Frequency Counter using GPS 1PPS gate puls + * Only for ST DISCO-F746NG and Nucleo-F411RE + F446RE + * + * Copyright (c) 2014,'15,'16 Kenji Arai / JH1PJL + * http://www.page.sannet.ne.jp/kenjia/index.html + * http://mbed.org/users/kenjiArai/ + * Created: October 18th, 2014 + * Revised: January 2nd, 2015 + * Re-started: June 25th, 2016 ported from F411 to F746 + * Re-started: October 5th, 2016 Change board -> DISCO-F746NG + * Re-started: October 10th, 2016 back to F411 + * Revised: Nobember 15th, 2016 + * + * Base program: Frequency_counter_w_GPS_1PPS (only for Nucleo-F411RE board) + * https://developer.mbed.org/users/kenjiArai/code/Frequency_Counter_w_GPS_1PPS/ + * + * 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. + */ + +#define USE_COM // use Communication with PC(UART) +#define USE_DEBUG + +// Include -------------------------------------------------------------------- +#include "mbed.h" +#include "GPSrcvr.h" +#include "fc_GPS1PPS.h" + +// 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 + +#ifdef USE_DEBUG +#define U_DEBUGBAUD(x) pc.baud(x) +#define U_DEBUG(...) pc.printf(__VA_ARGS__) +#define DBG(c) pc.putc(c) +#else +#define U_DEBUGBAUD(x) {;} +#define U_DEBUG(...) {;} +#define DBG(c) {;} +#endif + +#if defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_F446RE) +#define RECIPRO_LMT 4500 +#define RECIPRO_10KHZ 5000 +#elif defined(TARGET_STM32F746NG) +#define RECIPRO_LMT 9000 +#define RECIPRO_10KHZ 10000 +#else +#error "Target is only Nucleo-F411RE + F446RE or DISCO-F746NG!!!" +#endif +#define GSP_BUF_B (128 * 3) +#define GPS_BUF_S (128 * 2) + +enum input_select { + BNC_NORMAL = 1, + RECIPRO_AC, + RECIPRO_DC, + SMA_10, + SMA_20 +}; + +using namespace Frequency_counter; + +// Object --------------------------------------------------------------------- +#if defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_F446RE) +DigitalOut input_frq_select(PA_4); +DigitalInOut prescaler10or20(PA_7); +DigitalOut recipro_select(PB_6); +#elif defined(TARGET_STM32F746NG) +DigitalOut input_frq_select(PF_9); +DigitalInOut prescaler10or20(PB_15); +DigitalOut recipro_select(PA_8); +#endif +DigitalOut led1(LED1); +Serial pc(USBTX, USBRX); +Timer tmr; + +//**** Req. Counter +FRQ_CUNTR fc; + +// RAM ------------------------------------------------------------------------ +// Freq. +double new_frequency; +double f_10sec; +double f_100sec; +double f_1000sec; +double freq_recipro; +// Operation mode +uint8_t input_mode; + +// ROM / Constant data -------------------------------------------------------- +// 12345678901234567890 +static char *const msg_msg0 = "Frequency Counter by JH1PJL K.Arai"; +#if defined(TARGET_NUCLEO_F411RE) +static char *const msg_msg1 = "on Nucleo-F411RE System"; +#elif defined(TARGET_NUCLEO_F446RE) +static char *const msg_msg1 = "on Nucleo-F446RE System"; +#elif defined(TARGET_STM32F746NG) +static char *const msg_msg1 = "on DISCO-F746NG System"; +#endif +static char *const msg_msg2 = " "__DATE__" "; +static char *const msg_mode1 = " BNC none-prescaler "; +static char *const msg_mode2 = " BNC recipro(BNC none-prescaler) "; +static char *const msg_mode3 = " BNC recipro(dedicated BNC input)"; +static char *const msg_mode4 = " SMA prescaler 1/10 "; +static char *const msg_mode5 = " SMA prescaler 1/20 "; + +// Function prototypes -------------------------------------------------------- +void gps_data_rcv(void); + +//------------------------------------------------------------------------------ +// Control Program +//------------------------------------------------------------------------------ +void freq_measurement(uint8_t mode) +{ + uint16_t n = 0; + char buf[48]; + time_t seconds; + double scale; + + if (mode == SMA_20){ + scale = 20.0f; + } else if(mode == SMA_10){ + scale = 10.0f; + } else { + scale = 1.0f; + } + while(true){ + tmr.reset(); + tmr.start(); + if (fc.status_freq_update() != 0) { + new_frequency = fc.read_freq_data() * scale; + f_10sec = fc.read_freq_w_gate_time(10) * scale; + f_100sec = fc.read_freq_w_gate_time(100) * scale; + f_1000sec = fc.read_freq_w_gate_time(1000) * scale; + PRINTF("%8d, Freq: %9.0f,", ++n, new_frequency); + PRINTF(" F10s: %10.1f, F100s: %11.2f,", f_10sec, f_100sec); + PRINTF(" F1000s: %12.3f,", f_1000sec); + } else { + PRINTF("%8d, No data,,,,", ++n); + } + if (mode == SMA_20){ + PRINTF(" Div: 1/20,"); + } else if(mode == SMA_10){ + PRINTF(" Div: 1/10,"); + } else { + PRINTF(" Div: 1/1 ,"); + } + seconds = time(NULL) + 32400; // Adjust UTC to JST + strftime(buf, 40, " %I:%M:%S %p JST (%m/%d)", localtime(&seconds)); + PRINTF("%s\r\n", buf); + wait_ms(1000 - tmr.read_ms()); // 1sec interval + } +} + +void recipro() +{ + uint16_t n = 0; + char buf[48]; + time_t seconds; + double freq_recipro; + uint32_t interval_recipro; + uint32_t base_clk; + int32_t run2stop; + + while(true){ + fc.recipro_start_measure(); + PRINTF("Start measurement\r"); + while (fc.recipro_check_trigger() == 0){ + run2stop = tmr.read_ms(); + if (run2stop >= 100000){ // 100sec 0.001Hz + break; + } + } + if (run2stop >= 1000000){ // 100sec 0.001Hz + freq_recipro = 0; + } else { + interval_recipro = fc.recipro_read_data(); + base_clk = fc.recipro_base_clk_data(1); + if (interval_recipro >= 9000){// Measure less than 10KHz frequency + freq_recipro = (double)base_clk / (double)interval_recipro; + PRINTF("%8d, Freq: %11.5f [Hz] , ", n++, freq_recipro); + PRINTF("Raw: %11u [cnt] , ", interval_recipro); + PRINTF("Base: %11u [Hz], ", base_clk); + seconds = time(NULL) + 32400; // Adjust UTC to JST + strftime(buf, 40, + " %I:%M:%S %p JST (%m/%d)", localtime(&seconds)); + PRINTF("%s\r\n", buf); + run2stop = tmr.read_ms(); + if (run2stop < 1000){ + run2stop = 1000 - run2stop; + wait_ms(run2stop); // 1sec interval + } + } else { + freq_recipro = 0; + } + } + } +} + +int main() +{ + PRINTF("\r\n%s%s\r\n", msg_msg0, msg_msg2); + PRINTF("%s\r\n", msg_msg1); + PRINTF("Wait GPS 1PPS signal\r\n"); + gps_data_rcv(); + PRINTF("\r\nPlease select measurement mode.\r\n"); + PRINTF("%s-> 1\r\n", msg_mode1); + PRINTF("%s-> 2\r\n", msg_mode2); + PRINTF("%s-> 3\r\n", msg_mode3); + PRINTF("%s-> 4\r\n", msg_mode4); + PRINTF("%s-> 5\r\n", msg_mode5); + PRINTF("Enter 1 to 5 (other input then 1)\r\n"); + // Select operation mode + char c = GETC() - '0'; + if ((c > 5) || (c <= 0)){ c = 1;} + input_mode = c; + PRINTF("If you want to change the input signal,"); + PRINTF(" please restart the system (Enter Alt+B from your PC)\r\n"); + PRINTF("\r\nStart measuring\r\nMeasureing mode = "); + switch(input_mode){ + case RECIPRO_AC: + PRINTF("%s\r\n", msg_mode2); + input_frq_select = 1; + prescaler10or20.output(); + prescaler10or20 = 0; + recipro_select = 0; + recipro(); + break; + case RECIPRO_DC: + PRINTF("%s\r\n", msg_mode3); + input_frq_select = 1; + prescaler10or20.output(); + prescaler10or20 = 0; + recipro_select = 1; + recipro(); + break; + case SMA_10: + PRINTF("%s\r\n", msg_mode4); + input_frq_select = 0; + prescaler10or20.output(); + prescaler10or20 = 0; + recipro_select = 0; + freq_measurement(input_mode); + break; + case SMA_20: + PRINTF("%s\r\n", msg_mode5); + input_frq_select = 0; + prescaler10or20.input(); + recipro_select = 0; + freq_measurement(input_mode); + break; + case BNC_NORMAL: + default: + input_mode = BNC_NORMAL; + PRINTF("%s\r\n", msg_mode1); + input_frq_select = 1; + prescaler10or20.output(); + prescaler10or20 = 0; + recipro_select = 0; + freq_measurement(input_mode); + break; + } + while(true){;} // Just in case +} + +