Konstantinos Fane
/
Frequencymeasurement
embed simulator
main.cpp
- Committer:
- kwstasfane1
- Date:
- 2021-04-22
- Revision:
- 5:faf243e88b50
- Parent:
- 4:ce121f9e6db5
File content as of revision 5:faf243e88b50:
/* Written by Konstantinos Fane */ #include "mbed.h" #include <string> #include "C12832.h" // LCD display C12832 lcd(p5, p7, p6, p8, p11); //dummy measurement values float m_freq_hz; // = 120730.546423; //*10^6 Hz float m_t_interval_ms; //= 988.056475; //result to be displayed float m_result; //variables used for frequency, period and time interval measruements float count1 = 0.0; float ton = 0.0; float toff = 0.0; float period = 0.0; const char* range_scale [3][3] = { {"MHz","KHz","Hz"}, {"ms","ms","s"}, {"ms","ms","s"} }; /* flag to hold which measurement mode to display, 0 = Frequency Measurement * 1 = Period Measurement, 2 = Time interval Measurement * to match the index of message display arrays */ int dsp_mode = 0; const char* mode_msg [] = {"Frequency", "Period", "Time Interval"}; /* flag to hold which measurement range to display * 0 = High Range, 1 = Medium Range, 2 = Low Range */ int dsp_range = 0; const char* range_msg [] = {"High Resolution", "Medium Resolution", "Low Resolution"}; int dsp_time_interval = 0; //0=R-R, 1=F-F, 2=R-F, 3=F-R //result string const char* res[] = {""}; //Interrupt to be used in actual implementation to read the input square wave signal InterruptIn squareIN(p17); //User interface measurement mode and range selection buttons InterruptIn mode(p12); InterruptIn range(p15); InterruptIn time_interval(p13); //user defined functions to implement the user interface void user_interface_disp(); void mode_select(); void range_select(); void time_interval_type_select(); void result_calculator(); //interrupt service routines void start_t1_isr(); void start_t2_isr(); Ticker ui_disp; //generate the 1s interrupt, to measure frequency (direct frequency measurement) Ticker result_calc; //generate 100us interrupt, to calculate a new result Timer t1; Timer t2; int main() { //Reciprocal frequency measurement, measures the number of rising edges every time they occur squareIN.rise(&start_t1_isr); squareIN.fall(&start_t2_isr); ui_disp.attach(&user_interface_disp, 1); //update the screen every 1 second result_calc.attach_us(&result_calculator,100); //calculate a new measurement result every 100us //interrupt routine for mode and range selection user input mode.rise(&mode_select); range.rise(&range_select); time_interval.rise(&time_interval_type_select); //start the timer t1,t2 t1.start(); t2.start(); while(1) { } } void start_t1_isr() { period = t1.read_us(); t1.reset(); t2.reset(); } void start_t2_isr() { ton = t2.read_us(); t2.reset(); } void user_interface_disp() { lcd.cls(); //clear screen lcd.locate(1,1); lcd.printf("Mode: %s", mode_msg[dsp_mode]); //display the type of time interval measurement if the mode is selected if(dsp_mode ==2) { lcd.locate(90,1); if(dsp_time_interval == 0) { lcd.printf("(R->R)"); } else if(dsp_time_interval == 1) { lcd.printf("(F->F)"); } else if(dsp_time_interval == 2) { lcd.printf("(R->F)"); } else if(dsp_time_interval == 3) { lcd.printf("(F->R)"); } } lcd.locate(1,10); lcd.printf("Range: %s", range_msg[dsp_range]); lcd.locate(1,20); //print the result lcd.printf(*res,m_result,range_scale[dsp_mode][dsp_range]); } void time_interval_type_select() { if (dsp_time_interval <3) { dsp_time_interval++; } else { dsp_time_interval = 0; } } //Interrupt service routine to handle the measurement mode selection void mode_select() { if (dsp_mode < 2) { dsp_mode++; } else { dsp_mode = 0; } } //Interrupt service routine to handle the measurement range selection void range_select() { if (dsp_range < 2) { dsp_range++; } else { dsp_range = 0; } } void result_calculator() { //calculate frequency in Hz and period in ms float m_period_ms = period/1000; //period calculated in us, divide by 1000 float m_freq_hz = 1/(m_period_ms/1000); if(dsp_mode == 0) //frequency measurement { if(dsp_range == 0) //High resolution (MHz) { m_result = m_freq_hz/1000000; if(m_result <= 10.001) { //assigns the decimal point precision for each range *res="%3.3f %s"; } else { *res="Out-of-range... '>10 MHz !'"; } } else if(dsp_range == 1) //medium resolution (KHz) { m_result = m_freq_hz/1000; if(m_result <= 100.001) { //assigns the decimal point precision for each range *res="%3.3f %s"; } else { *res="Out-of-range... '>100 KHz !'"; } } else //low resolution (Hz) { m_result = m_freq_hz; if(m_result <= 100.001) { //assigns the decimal point precision for each range *res="%3.3f %s"; } else { *res="Out-of-range... '>100 Hz !'"; } } } else if (dsp_mode == 1) //period measurement { if(dsp_range == 0) //High resolution (2.000 +- 0.0001 ms) { m_result = m_period_ms; if(m_result <= 2.0001) { //assigns the decimal point precision for each range *res="%1.4f %s"; } else { *res="Out-of-range... '>2.000 ms !'"; } } else if(dsp_range == 1) //medium resolution (20.00 +- 0.01 ms) { m_result = m_period_ms; if(m_result <= 20.01) { //assigns the decimal point precision for each range *res="%2.2f %s"; } else { *res="Out-of-range... '>20.00 ms !'"; } } else //low resolution (2.000 +- 0.001 s) { m_result = m_period_ms/1000; if(m_result <= 2.001) { //assigns the decimal point precision for each range *res="%1.3f %s"; } else { *res="Out-of-range... '>2.000 sec'"; } } } else // "(dsp_mode == 2)" time interval measurement { if(dsp_time_interval == 0 || dsp_time_interval == 1) //rising->rising, falling -> falling { m_result = m_period_ms; } else if(dsp_time_interval == 2) //rising->falling { m_result = ton/1000; } else if(dsp_time_interval == 3) //falling->falling { m_result = m_period_ms - (ton/1000); } if(dsp_range == 0) //High resolution (2.0000 +- 0.0001 ms) { if(m_result <= 2.0001) { //assigns the decimal point precision for each range *res="%1.4f %s"; } else { *res="Out-of-range... '>2.000 ms !'"; } } else if(dsp_range == 1) //medium resolution (20.00 +- 0.01 ms) { if(m_result <= 20.01) { //assigns the decimal point precision for each range *res="%2.2f %s"; } else { *res="Out-of-range... '>20.00 ms !'"; } } else //low resolution (2.000+-0.0001ms) { m_result = m_result/1000; if(m_result <= 2.001) { //assigns the decimal point precision for each range *res="%1.3f %s"; } else { *res="Out-of-range... '>2.000 sec'"; } } } }