⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lmscopedlg.cpp

📁 一个简单示波器的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

//***************************************************************************
//
// The oscilloscope is reporting that the trigger position has been changed.
// Update the UI to match.
//
//***************************************************************************
LRESULT ClmscopeDlg::OnScopeTriggerPosChanged(WPARAM wParam, LPARAM lParam)
{
    CString strText;

    //
    // Set the trigger position.
    //
    m_cTriggerPosSlider.SetPos((int)lParam);

    //
    // Update the current waveform display with the new trigger position.
    //
    m_cWaveform.SetTriggerPos((int)lParam);

    return((LRESULT)0);
}

//***************************************************************************
//
// The oscilloscope is reporting that the trigger level has been changed.
// Update the UI to match.
//
//***************************************************************************
LRESULT ClmscopeDlg::OnScopeTriggerTypeChanged(WPARAM wParam, LPARAM lParam)
{
    //
    // Set the trigger type.
    //
    m_cTriggerType.SetCurSelByValue((DWORD)lParam);

    //
    // Set the trigger channel radio button
    //
    if(wParam == SCOPE_CHANNEL_1)
    {
        m_cTriggerCh1.SetCheck(1);
        m_cTriggerCh2.SetCheck(0);
    }
    else
    {
        m_cTriggerCh2.SetCheck(1);
        m_cTriggerCh1.SetCheck(0);
    }

    return((LRESULT)0);
}

//***************************************************************************
//
// The oscilloscope is reporting that channel 2 capture has been enabled or
// disabled.
//
//***************************************************************************
LRESULT ClmscopeDlg::OnScopeChannel2(WPARAM wParam, LPARAM lParam)
{
    BOOL bEnabled;

    //
    // Was the channel enabled or disabled?
    //
    bEnabled = (wParam == SCOPE_CHANNEL2_ENABLE) ? TRUE : FALSE;

    //
    // Channel 2 has been enabled or disabled. Set the state of the
    // checkbox appropriately and also the radio button that allows selection
    // of channel 2 as the trigger source.
    //
    m_cChannel2Enable.SetCheck(bEnabled);
    m_cTriggerCh2.EnableWindow(bEnabled);
    m_cFindChannel2.EnableWindow(bEnabled);
    m_cChannel2Scale.EnableWindow(bEnabled);
    m_cChannel2PosSlider.EnableWindow(bEnabled);
    m_cChannel2Pos.EnableWindow(bEnabled);
    m_cChannel2Scale.EnableWindow(bEnabled);
    m_cCh2Min.EnableWindow(bEnabled);
    m_cCh2Max.EnableWindow(bEnabled);
    m_cCh2Mean.EnableWindow(bEnabled);

    return((LRESULT)0);
}

//***************************************************************************
//
// Enable or disable controls as required by the current connection state.
//
//***************************************************************************
void ClmscopeDlg::UpdateControlEnables(void)
{
    m_cChannel1PosSlider.EnableWindow(m_bConnected);
    m_cChannel2PosSlider.EnableWindow(m_bConnected);
    m_cTriggerLevelSlider.EnableWindow(m_bConnected);
    m_cTriggerPosSlider.EnableWindow(m_bConnected);
    m_cChannel1Scale.EnableWindow(m_bConnected);
    m_cChannel2Scale.EnableWindow(m_bConnected);
    m_cChannel2Enable.EnableWindow(m_bConnected);
    m_cFindChannel1.EnableWindow(m_bConnected);
    m_cFindChannel2.EnableWindow(m_bConnected);
    m_cTimebase.EnableWindow(m_bConnected);
    m_cOneShot.EnableWindow(m_bConnected);
    m_cChannel1Pos.EnableWindow(m_bConnected);
    m_cChannel2Pos.EnableWindow(m_bConnected);
    m_cStopStart.EnableWindow(m_bConnected);
    m_cTriggerType.EnableWindow(m_bConnected);
    m_cCh1Min.EnableWindow(m_bConnected);
    m_cCh1Max.EnableWindow(m_bConnected);
    m_cCh1Mean.EnableWindow(m_bConnected);
    m_cCh2Min.EnableWindow(m_bConnected);
    m_cCh2Max.EnableWindow(m_bConnected);
    m_cCh2Mean.EnableWindow(m_bConnected);
    m_cTriggerCh1.EnableWindow(m_bConnected);
    m_cTriggerCh2.EnableWindow(m_bConnected);
    m_cTriggerLevel.EnableWindow(m_bConnected);
}

//***************************************************************************
//
// Set the values of all the controls after we have connected and
// received a settings structure from the device.
//
//***************************************************************************
void ClmscopeDlg::SetControlsOnConnection(tScopeSettings *pSettings)
{
    CString strText;

    //
    // Set the state of the various channel 2 controls
    //
    OnScopeChannel2((pSettings->ucChannel2Enabled ? SCOPE_CHANNEL2_ENABLE :
                                                    SCOPE_CHANNEL2_DISABLE), 0);

    //
    // Set the trigger type.
    //
    OnScopeTriggerTypeChanged(pSettings->ucTriggerChannel, pSettings->ucTriggerType);

    //
    // Set the trigger level.
    //
    OnScopeTriggerLevelChanged(0, pSettings->ulTriggerLevelmV);

    //
    // Set the timebase.
    //
    OnScopeTimebaseChanged(0, pSettings->ulTimebaseuS);

    //
    // Set the channel 1 and 2 vertical scales.
    //
    OnScopeScaleChanged(SCOPE_CHANNEL_1, pSettings->usChannel1ScalemVdiv);
    OnScopeScaleChanged(SCOPE_CHANNEL_2, pSettings->usChannel2ScalemVdiv);

    //
    // Set the initial channel 1 and 2 vertical offset.
    //
    OnScopePositionChanged(SCOPE_CHANNEL_1, pSettings->sChannel1OffsetmV);
    OnScopePositionChanged(SCOPE_CHANNEL_2, pSettings->sChannel2OffsetmV);

    //
    // Set the trigger position slider.
    //
    OnScopeTriggerPosChanged(0, pSettings->lTriggerPos);

    //
    // Determine whether we need to enable or disable the "One Shot" button.
    //
    if(pSettings->ucStarted)
    {
        OnScopeStarted(0, 0);
    }
    else
    {
        OnScopeStopped(0, 0);
    }
}

//***************************************************************************
//
// The "Quit" button has been pressed. Tidy up and exit.
//
//***************************************************************************
void ClmscopeDlg::OnBnClickedOk()
{
    //
    // Update the status bar text
    //
    m_csbStatusBar.SetPaneTextByResource(0, IDS_STATUS_CLOSING, TRUE);

    //
    // Free resources allocated by the scope control module.
    //
    ScopeControlDisconnect();
    ScopeControlTerm();

    //
    // Call Windows to do the usual shutdown processing.
    //
    OnOK();
}

//*****************************************************************************
//
// Formats a string containing a number, its units and a suffix string.
//
// \param pcString points to the CString into which the string is to be
// formatted.
// \param pcSuffix points to a string that is to be appended to the end of
// the formatted number and units.
// \param pcUnit points to a string describing the unit of measurement of
// the number as passed in lValue.
// \param pcUnit1000 points to a string describing the unit of measurement of
// the (lValue / 1000).
// \param lValue is the number which is to be formatted into the buffer.
//
// This function is called to generate strings suitable for display when the
// number to be rendered may take on a wide range of values. It considers the
// size of lValue and, if necessary, divides by 1000 and formats it with
// as few digits after the decimal point as necessary (to remove trailing 0s).
// For example, passing lValue 5300, pcSuffix "/div", pcUnit "mV" and
// pcUnit1000 "V" would return formatted string "5.3V/div". Reducing lValue
// to 800 would result in "800mV/div".
//
// \return None.
//
//*****************************************************************************
void ClmscopeDlg::ScaleAndFormatString(CString *pcString, LPCTSTR pcSuffix,
                             LPCTSTR pcUnit, LPCTSTR pcUnit1000, long lValue)
{
    if(abs(lValue) >= 1000)
    {
        //
        // The value is greater than or equal to 1000 so we will divide down
        // and show it in decimal format.
        //

        //
        // Check for trailing zeros and format as appropriate.
        //
        if((lValue % 1000) == 0)
        {
            //
            // Multiple of 1000 - no decimal point or fractional digits needed.
            //
            pcString->Format((LPCTSTR)L"%d%s%s", (lValue / 1000), pcUnit1000,
                              pcSuffix);
        }
        else if((lValue % 100) == 0)
        {
            //
            // Multiple of 100 - 1 decimal place needed.
            //
            pcString->Format((LPCTSTR)L"%d.%d%s%s", (lValue / 1000),
                             abs((lValue % 1000) / 100), pcUnit1000,
                             pcSuffix);
        }
        else if((lValue % 10) == 0)
        {
            //
            // Multiple of 10 - 2 decimal place needed.
            //
            pcString->Format((LPCTSTR)L"%d.%02d%s%s", (lValue / 1000),
                             abs((lValue % 1000) / 10), pcUnit1000, pcSuffix);
        }
        else
        {
            //
            // 3 decimal place needed.
            //
            pcString->Format((LPCTSTR)L"%d.%03d%s%s", (lValue / 1000),
                             abs(lValue % 1000), pcUnit1000, pcSuffix);
        }
    }
    else
    {
        //
        // The value passed is less than 1000 so we just display it as it is.
        //
        pcString->Format((LPCTSTR)L"%d%s%s", lValue, pcUnit,  pcSuffix);
    }
}

//***************************************************************************
//
// Fill the various combo boxes with the appropriate strings and values.
//
//***************************************************************************
void ClmscopeDlg::InitComboBoxContents(void)
{
    int iLoop;

    //
    // Empty each of the combo boxes.
    //
    m_cTimebase.ResetContent();
    m_cChannel1Scale.ResetContent();
    m_cChannel2Scale.ResetContent();
    m_cTriggerType.ResetContent();

    //
    // Fill the scale combo boxes.
    //
    for(iLoop = 0; iLoop < (sizeof(g_pdwVoltages) / sizeof(DWORD)); iLoop++)
    {
        CString strText;

        //
        // Format the string matching the millivolt value in the array.
        //
        ScaleAndFormatString(&strText,  (LPCTSTR)L"\\div", (LPCTSTR)L"mV",
                             (LPCTSTR)L"V", g_pdwVoltages[iLoop]);
        m_cChannel1Scale.InsertString(iLoop, strText);
        m_cChannel1Scale.SetItemData(iLoop, g_pdwVoltages[iLoop]);
        m_cChannel2Scale.InsertString(iLoop, strText);
        m_cChannel2Scale.SetItemData(iLoop, g_pdwVoltages[iLoop]);
    }

    //
    // Fill the timebase combo box.
    //
    for(iLoop = 0; iLoop < (sizeof(g_pdwTimebases) / sizeof(DWORD)); iLoop++)
    {
        CString strText;

        //
        // Format the string matching the millivolt value in the array.
        //
        ScaleAndFormatString(&strText,  (LPCTSTR)L"\\div", (LPCTSTR)L"uS",
                             (LPCTSTR)L"mS", g_pdwTimebases[iLoop]);
        m_cTimebase.InsertString(iLoop, strText);
        m_cTimebase.SetItemData(iLoop, g_pdwTimebases[iLoop]);
    }

    //
    // Fill the trigger type combo box.
    //
    for(iLoop = 0; iLoop < (sizeof(g_psTriggers) / sizeof(tComboEntry)); iLoop++)
    {
        CString strText;

        //
        // Format the string matching the millivolt value in the array.
        //
        strText.LoadString(g_psTriggers[iLoop].iStringID);
        m_cTriggerType.InsertString(iLoop, strText);
        m_cTriggerType.SetItemData(iLoop, g_psTriggers[iLoop].dwValue);
    }
}


//***************************************************************************
//
// Update the voltage measurements displayed when a new data set is
// received.
//
//***************************************************************************
void ClmscopeDlg::UpdateVoltageMeasurements(void)
{
    unsigned long ulLoop;
    int iMax[2];
    int iMin[2];
    int iMean[2];
    CString strMin;
    CString strMax;
    CString strMean;

    //
    // If we don't have any data, just clear the various display strings.
    //
    if(m_psScopeData == NULL)
    {
        strMin = L"";
        m_cCh1Max.SetWindowText(strMin);
        m_cCh2Max.SetWindowText(strMin);
        m_cCh1Min.SetWindowText(strMin);
        m_cCh2Min.SetWindowText(strMin);
        m_cCh1Mean.SetWindowText(strMin);
        m_cCh2Mean.SetWindowText(strMin);
        return;
    }

    //
    // Clear our result variables.
    //
    iMax[0] = -30000;
    iMax[1] = -30000;
    iMin[0] = 30000;
    iMin[1] = 30000;
    iMean[0] = 0;
    iMean[1] = 0;

    //
    // Are we dealing with a single- or dual-channel dataset?
    //
    if(m_psScopeData->bDualChannel)
    {
        tScopeDualDataElement *psElement;

        //
        // Dual channel data.
        //
        psElement = (tScopeDualDataElement *)((char *)m_psScopeData +
                                          m_iSampleOffset);

        //
        // Find the minimum, maximum and mean voltages for the channels.
        //
        for(ulLoop = 0; ulLoop < m_psScopeData->ulTotalElements; ulLoop++)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -