以下是我在DSP2812PCI运动控制卡中用的Simulink仿真读写硬件的S-function动态链接库源程序:
/*
* File : F2812_EVA.c
* Abstract:
* An example C-file S-function for write cmpr to DSP2812,
* Date : 2007.12.02
*
* Real-Time Workshop note:
* This file can be used as is (noninlined) with the Real-Time Workshop
* C rapid prototyping targets, or it can be inlined using the Target
* Language Compiler technology and used with any target. See
* matlabroot/toolbox/simulink/blocks/tlc_c/timestwo.tlc
* matlabroot/toolbox/simulink/blocks/tlc_ada/timestwo.tlc
* the C and Ada TLC code to inline the S-function.
*
* See simulink/src/sfuntmpl_doc.c
*
* Copyright 1997-2007 TH, Inc.
* $Revision: 1.0 $
*/
#define S_FUNCTION_NAME test
#define S_FUNCTION_LEVEL 2
#define PCI_T1PR(S) ssGetSFcnParam(S, 0)
#define PCI_T1CON(S) ssGetSFcnParam(S, 1)
#define PCI_DBTCONA(S) ssGetSFcnParam(S, 2)
/* Parameters */
#include "simstruc.h"
#include "windows.h"
#include "THRMCM.h"
static BOOL bOpen = FALSE;
static WORD T1PR =0;
static WORD T1CON =0;
static WORD DBTCONA =0;
/*================*
* Build checking *
*================*/
/* Function: mdlInitializeSizes ===============================================
* Abstract:
* Setup sizes of the various vectors.
*/
static void mdlInitializeSizes(SimStruct *S)
{
int_T i;
ssSetNumSFcnParams(S, 3); /* Number of expected parameters */
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
return; /* Parameter mismatch will be reported by Simulink */
}
if (!ssSetNumInputPorts(S, 3)) return; /* Input Ports */
for (i = 0; i < 3; i++) {
/* snip */
ssSetInputPortWidth(S, i, 1);
ssSetInputPortDirectFeedThrough(S,i,1);
/* ssSetInputPortRequiredContiguous(S,i,1); // 加了这条语句就不能执
行取端口数据及其后面的代码 */
}
T1PR = (WORD) mxGetPr(PCI_T1PR(S))[0];
T1CON = (WORD) mxGetPr(PCI_T1CON(S))[0];
DBTCONA = (WORD) mxGetPr(PCI_DBTCONA(S))[0];
if (!ssSetNumOutputPorts(S,0)) return;
ssSetNumIWork(S, 1);
ssSetNumSampleTimes(S, 1);
/* Take care when specifying exception free code - see sfuntmpl_doc.c */
ssSetOptions(S,
SS_OPTION_WORKS_WITH_CODE_REUSE |
SS_OPTION_EXCEPTION_FREE_CODE|
SS_OPTION_USE_TLC_WITH_ACCELERATOR);
if (!bOpen)
{
bOpen = Init2812Card();
if(!bOpen)
{
return;
}
order_code_write(1);
t1pr_write(T1PR);
t1con_write(T1CON);
dbtcona_write(DBTCONA);
}
}
/* Function: mdlInitializeSampleTimes =========================================
* Abstract:
* Specify that we inherit our sample time from the driving block.
*/
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
}
/* Function: mdlOutputs =======================================================
* Abstract:
* y = 2*u
*/
static void mdlOutputs(SimStruct *S, int_T tid)
{
// int_T i;
WORD cmpr1=0;
WORD cmpr2=0;
WORD cmpr3=0;
InputRealPtrsType uPtrs0 = ssGetInputPortRealSignalPtrs(S,0);
InputRealPtrsType uPtrs1 = ssGetInputPortRealSignalPtrs(S,1);
InputRealPtrsType uPtrs2 = ssGetInputPortRealSignalPtrs(S,2);
cmpr1 = (WORD)(*uPtrs0[0]);
cmpr2 = (WORD)(*uPtrs1[0]);
cmpr3 = (WORD)(*uPtrs2[0]);
// for (i=0; i /*
* This example does not implement complex signal handling.
* To find out see an example about how to handle complex signal in
* S-function, see sdotproduct.c for details.
*/
// mexPrintf("uPtrs2=%f\n",*uPtrs0[2]); //调试测试用
order_code_write(2);
cmpr1_write(cmpr1);
cmpr2_write(cmpr2);
cmpr3_write(cmpr3);
// }
}
/* Function: mdlTerminate =====================================================
* Abstract:
* No termination needed, but we are required to have this routine.
*/
static void mdlTerminate(SimStruct *S)
{
if (bOpen)
{
order_code_write(0);
Exit2812Card();
}
}
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
#include "simulink.c" /* MEX-file interface mechanism */
#else
#include "cg_sfun.h" /* Code generation registration function */
#endif