转:使用DSP的数字示波器的例子

2019-07-29 16:37发布

Digital Oscilloscope C/C++ Source Code Example of Using DirectDSP? software
Below is a C/C++ source code example of using off-the-shelf DSP/analog hardware to perform a basic digital oscilloscope function. Note the use of the DSShowHardwareSelector call to bring up a list of supported hardware.


#include <windows.h>
#include <stdlib.h>
// DirectDSP? software package include files
#include "enmgr.h"   // Engine Manager
#include "hwmgr.h"   // Hardware Manager
#include "hwlib.h"   // Hardware Library

// some global variables
  ...note:  many variable and type declarations omitted for brevity...
HANDLE FAR  hEngine = NULL;  // declare at least one variable FAR to limit this to a
single-instance program
HANDLE      hBoard = NULL;
BOOL        fBoardInitialized = FALSE;
char        szBoard[30];
UINT        uMemArch;
int         wBuflen = 1024;
DWORD       dwMemSize,dwBufferBaseAddr;
HWND        hwndScope = NULL;
WORD        wBoardClass;
float       FsDesired = 22050.0;
float       FsActual;
DWORD       dwFsMode;
short int   ChanList = 0;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInst, LPSTR lpszCmdParam, int nCmdShow) {
// comment this call if status messages from HwLib should not be visible
    DSShowEngMgrStatusWindow();  // turn on debug status window in Engine Manager

// show hardware selector dialog (Hardware Manager); returns board designator string
// note:  if hardware choice is fixed, then skip this call and use correct board
designator string
// in DSAssignBoard call below
    if (DSShowHardwareSelectorDlg(NULL, szBoard) == IDCANCEL) goto cleanup;

// open engine
    hEngine = DSEngineOpen(DS_EO_HSM, NULL);  // first try to open Hypersignal-Macro or
                                              // Hypersignal-Macro EX as engine
    if (!hEngine) {
        hEngine = DSEngineOpen(DS_EO_HSA, NULL);  // if that doesn't work, try
                                                  // Hypersignal-Acoustic
        if (!hEngine) {
            itoa(DSGetHWLibErrorStatus(), tmpstr, 10);
            lstrcat(tmpstr, " is error code; DSEngineOpen failed");
            MessageBox(GetActiveWindow(), tmpstr, "Dscope Test Prog", MB_OK);
            goto cleanup;
        }
    }

// assign a board handle:  engine handle, board designator, bus type, IO base addr,
Mem base addr
    hBoard = DSAssignBoard(hEngine, szBoard, NULL, NULL, NULL);
// initialize the board; make sure it's installed, reset all processors
    fBoardInitialized = DSInitBoard(hBoard);
    if (!fBoardInitialized) {
        itoa(DSGetEngineErrorStatus(hEngine), tmpstr, 10);
        lstrcat(tmpstr, " is error code; DSInitBoard failed");
        MessageBox(GetActiveWindow(), tmpstr, "Dscope Test Prog", MB_OK);
        goto cleanup;
    }

// interrogate engine for board type values
    wBoardClass = DSGetBoardClass(hBoard);

// get memory architecture
    uMemArch = DSGetMemArch(hBoard);
    if (uMemArch == NULL) {
       MessageBox(GetActiveWindow(), "DSGetMemArch failed","Dscope Test Prog", MB_OK);
       goto cleanup;
    }

// determine sampling rate ctrl. reg. value, and actual rate (closest rate possible
to desired);
// CalcSampFreq returns ctrl. reg. value directly, uses ptr to return actual
sampling frequency (in Hz)
    dwFsMode = DSCalcSampFreq(hBoard, FsDesired, 1, &ChanList, &FsActual);  // demo
assumes 1 channel, initial value 22.05 kHz

// load executable DSP code file (usually a COFF file produced by DSP manufacturer's
linker)
    if (!DSLoadFileProcessor(hBoard, NULL, 1)) {  // load default file for the board
type (processor 0 only)
        MessageBox(GetActiveWindow(), "DSLoadFileBoard:  problem loading file", "Dscope
Test Prog", MB_OK);
        goto cleanup;
    }

// get the memory size, (note that this currently has to be done after LoadFile)
    dwMemSize = DSGetMemSize(hBoard, 0x01);  // processor 0 only

// reset the DSP board (should already be in reset state; processor 0 only)
    DSResetProcessor(hBoard, 0x01);

// send down some important variables (needed if a default Hypersignal DSP file is
being used)
    DSPutDSPProperty(hBoard, DSP_BOARDCLASS, wBoardClass & 0x0ff);  // main type in
low byte
    DSPutDSPProperty(hBoard, DSP_BOARDSUBCLASS, wBoardClass >> 8);  // subtype in
high byte
    DSPutDSPProperty(hBoard, DSP_OPMODE, 2);       // Dig. Scope is mode 2
    DSPutDSPProperty(hBoard, DSP_FILTTYPE1, 0);    // disable trace 1 real-time filter
    DSPutDSPProperty(hBoard, DSP_FILTTYPE2, 0);    // disable trace 2 real-time filter
    DSPutDSPProperty(hBoard, DSP_TRIGLEVEL, 0);    // free-run triggering
    DSPutDSPProperty(hBoard, DSP_TRIGCHANLIST, 0);
    DSPutDSPProperty(hBoard, DSP_BUFLEN, wBuflen); // buffer size
    DSPutDSPProperty(hBoard, DSP_HOSTBUFNUM, 0);
    DSPutDSPProperty(hBoard, DSP_BUFNUM, 0);
    DSPutDSPProperty(hBoard, DSP_CHANLIST, 0);     // starting channel
    DSPutDSPProperty(hBoard, DSP_NUMCHAN, 1);      // number of channels
    DSPutDSPProperty(hBoard, DSP_GAINLIST, 0);     // gain list
    DSPutDSPProperty(hBoard, DSP_FSMODE, dwFsMode);  // sampling rate control register
(mode value)
    DSPutDSPProperty(hBoard, DSP_FSVALUE, *((long*)&FsActual));  // actual sampling rate
(in Hz)

// get address of input time domain data
    dwBufferBaseAddr = DSGetDSPProperty(hBoard, DSP_TIMDATAADDR);

    if (!hPrevInst) {
  ...note:  window class registration and CreateWindow code omitted for brevity...
  
        hwndScope = CreateWindow(...
        ShowWindow(hwndScope, nCmdShow);
        UpdateWindow(hwndScope);
    }

// scope window is born; turn the board loose...  (processor 0 only)
    DSRunProcessor(hBoard, 0x01);

// tell engine to wait for a buffer, and then send a BUFRDY message to our window when
one is ready
    DSRegisterEngineMsgWnd(hEngine, DS_REMW_SETDSPDATARDYMSG, hwndScope);  // register
callback window for buffer ready messages
    DSWaitForBuffer(hBoard, 0, NULL, DS_WFB_POLLED);

// time to give up and become a Windows animal
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage (&msg);
        DispatchMessage (&msg);
    }

cleanup:
    if (fBoardInitialized) DSDisableBoard(hBoard);  // disable board (all processors)
    if (hBoard != NULL) DSFreeBoard(hBoard);
    if (hEngine != NULL) DSEngineClose(hEngine);
    return msg.wParam;
}

long WINAPI _export WndProc(HWND hwnd, WORD wMsg, WORD wParam, LONG lParam) {
    ...note:  most variable declarations omitted for brevity...
static HGLOBAL    hBuf = NULL;
static int far*   buf;
static short int  nCurBuf = 0;
    switch (wMsg) {
    ...note:  other message-processing code omitted for brevity...
        case WM_CREATE:
         // allocate some memory to hold board buffers
            hBuf = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DISCARDABLE,
MAX_BUF_LEN*sizeof(int));
            break;

        case WM_DSPENGINE_BUFRDY:  // message sent by DSP engine when data buffer is ready
            buf = (int far*)GlobalLock(hBuf);
         // transfer below illustrates two common type of DSP memory architectures
            if (uMemArch == DS_GMA_VECTOR) {  // vector data memory
                if (nCurBuf == 0)
                  uStatus = DSGetMem(hBoard, DS_GM_VECTOR_DATA_X, dwBufferBaseAddr,
DS_GM_SIZE16, buf, wBuflen);
                else
                  uStatus = DSGetMem(hBoard, DS_GM_VECTOR_DATA_Y, dwBufferBaseAddr,
DS_GM_SIZE16, buf, wBuflen);
            }
            else { // linear data/prog memory, or modified harvard arch. with linear
data memory
                uStatus = DSGetMem(hBoard, DS_GM_LINEAR_DATA_RT,
dwBufferBaseAddr+nCurBuf*wBuflen, DS_GM_SIZE16, buf, wBuflen);
            }
            GlobalUnlock(hBuf);
            if (!uStatus) MessageBox(hwnd, "DSGetMem:  problem with point transfer",
"Dscope Test Prog", MB_OK);
            else FirstBufferRcvd = TRUE;

            nCurBuf ^= 1;  // switch buffers
            DSPutDSPProperty(hBoard, DSP_HOSTBUFNUM, nCurBuf);  // write the new buffer #
   
            if (!IsIconic(hwnd)) DSWaitForBuffer(hBoard, nCurBuf, NULL, DS_WFB_POLLED);
            break;
    }
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。