embed simulator

Dependencies:   mbed C12832

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'";
            }
        }
    }    
}