📄 dig_port.c
字号:
/******************************************************************************/
/* */
/* Name: DIG_PORT.C - S-Function which sets or resets(output) or reads(input) */
/* a given pin of the digital port lines of the c167 */
/* */
/* Author: Farkhondeh Fallahpasnad */
/* Extensions: Sven Rebeschiess */
/* Date: 10.01.2000 */
/* */
/******************************************************************************/
// =============================================================================
// adapted for the GNU compiler (HighTec) : (FW-06-01)
// register set: C167CR
// now a level 2 s-function
//
// note: recompilation as a MATLAB_MEX_FILE is only required if the number or
// function of any of the call-up parameters has been changed. The resulting
// DLL is not functional (it's an empty function...)
//
// =============================================================================
#define S_FUNCTION_NAME dig_port
#define S_FUNCTION_LEVEL 2
#include "simstruc.h" // Simulink data types (SimStruct, etc.)
#ifdef MATLAB_MEX_FILE
#define abort_LED(x) return
#else
#include "ioregs12.h" /* port definitions etc. */
#include "mc_signal.h" // abort_LED(), blinky(), ...
#endif
// -------------------------------------------------------------------------------
// Number of S-function Parameters and macros to access from the SimStruct
// -------------------------------------------------------------------------------
#define BLOCK_ARG ssGetSFcnParam(S,0) // 0: DIG_IN block; 1: DIG_OUT block;
#define SAMPLE_TIME_ARG ssGetSFcnParam(S,1) // Sample time in seconds
#define PORT_ARG ssGetSFcnParam(S,2) // Port number
#define PIN_ARG ssGetSFcnParam(S,3) // Pin number
#define VON_ARG ssGetSFcnParam(S,4) // Activation threshold
#define VOFF_ARG ssGetSFcnParam(S,5) // De-activation threshold
#define NUMBER_OF_ARG 6 // Number of s-function input arguments
// -------------------------------------------------------------------------------
// Macros to access the S-function parameter values
// -------------------------------------------------------------------------------
#define BLOCK ((uint_T) mxGetPr (BLOCK_ARG)[0])
#define SAMPLE_TIME ((real_T) mxGetPr (SAMPLE_TIME_ARG)[0])
#define PORT ((uint_T) mxGetPr (PORT_ARG)[0])
#define PIN ((int_T) mxGetPr (PIN_ARG)[0])
#define VON ((real_T) mxGetPr (VON_ARG)[0])
#define VOFF ((real_T) mxGetPr (VOFF_ARG)[0])
/* Define Simulink block types: */
#define DIG_INPUT 0
#define DIG_OUTPUT 1
// ----------------------------------------------------------------------------------------------------
// S-Function methods
// ----------------------------------------------------------------------------------------------------
#define MDL_CHECK_PARAMETERS
#if defined(MDL_CHECK_PARAMETERS)
static void mdlCheckParameters(SimStruct *S)
{
int MAX_PIN;
// check common parameter (SAMPLE_TIME)
if (mxGetNumberOfElements(SAMPLE_TIME_ARG) != 1) abort_LED(11); // parameter must be a scalar
if ((SAMPLE_TIME < 0) && (SAMPLE_TIME != INHERITED_SAMPLE_TIME)) abort_LED(11); // invalid negative sample time
// determine maximum number the selected port
switch(PORT) {
case 0: MAX_PIN = 0; break; // port 0 (disabled)
case 1: MAX_PIN = 0; break; // port 1 (disabled)
case 2: MAX_PIN = 15; break; // port 2
case 3: MAX_PIN = 15; break; // port 3
case 4: MAX_PIN = 0; break; // port 4 (disabled)
case 5: MAX_PIN = 7; break; // port 5
case 6: MAX_PIN = 7; break; // port 6
case 7: MAX_PIN = 7; break; // port 7
case 8: MAX_PIN = 7; break; // port 8
default:
abort_LED (12);
break;
}
// check parameter: PIN
if (mxGetNumberOfElements(PIN_ARG) != 1) abort_LED(13); // parameter must be a scalar
if(PIN < 0 || PIN > MAX_PIN) abort_LED(13); // invalid range
}
#endif /* MDL_CHECK_PARAMETERS */
/* Function: mdlInitializeSizes ===============================================
*
*/
static void mdlInitializeSizes (SimStruct *S)
{
int i;
ssSetNumSFcnParams(S, NUMBER_OF_ARG); // expected number of parameters
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) abort_LED(10); // incorrect number of parameters
else
{
#ifdef MDL_CHECK_PARAMETERS
mdlCheckParameters(S); // check all parameters
#endif
}
// None of this s-functions's parameters are tunable during simulation
for (i=0; i < NUMBER_OF_ARG; i++) ssSetSFcnParamNotTunable(S, i);
switch (BLOCK)
{
case DIG_INPUT:
if(!ssSetNumInputPorts(S, 0)) abort_LED(17);
if(!ssSetNumOutputPorts(S, 1)) abort_LED(17);
ssSetOutputPortWidth(S, 0, 1); // scalar output (of the block)
break;
case DIG_OUTPUT:
if(!ssSetNumInputPorts(S, 1)) abort_LED(18);
if(!ssSetNumOutputPorts(S, 0)) abort_LED(18);
ssSetInputPortWidth(S, 0, 1); // scalar input (to the block)
ssSetInputPortDirectFeedThrough(S, 0, 1); // direct feedthrough (only executs after update of inputs)
ssSetInputPortRequiredContiguous(S, 0, 1); // ports to be stored contiguously in memory
break;
default:
#ifndef MATLAB_MEX_FILE
abort_LED (19);
#endif
break;
}
ssSetNumSampleTimes (S, 1); // only 'one' sampletime in this S-Function
ssSetNumContStates (S, 0); // number of continuous states
ssSetNumDiscStates (S, 0); // number of discrete states
ssSetNumIWork (S, 0); // number of integer work vector elements
ssSetNumRWork (S, 0); // number of real work vector elements
ssSetNumPWork (S, 0); // number of pointer work vector elements
}
/* Function: mdlInitializeSampleTimes =========================================
*
*/
static void mdlInitializeSampleTimes (SimStruct *S)
{
ssSetSampleTime(S, 0, SAMPLE_TIME); // this S-Function only has 'one' sampletime -> index '0'
ssSetOffsetTime(S, 0, 0.0);
}
/* Function: mdlStart =========================================================
*
*/
#define MDL_START
static void mdlStart(SimStruct *S)
{
#ifndef MATLAB_MEX_FILE
switch(BLOCK) {
case DIG_INPUT:
// Set required pin of port(P0 ... P8) as input
switch(PORT) {
case 0: break; // (disabled)
case 1: break; // (disabled)
case 2: DP2 &= (65535-(1<<PIN)); break;
case 3: DP3 &= (65535-(1<<PIN)); break;
case 4: break; // (disabled)
case 5: break; // (always input: A/D)
case 6: DP6 &= (255-(1<<PIN)); break;
case 7: DP7 &= (255-(1<<PIN)); break;
case 8: DP8 &= (255-(1<<PIN)); break;
default: abort_LED (20);
}
break;
case DIG_OUTPUT:
// set required pin of port(P0 ... P8) as output
switch(PORT) {
case 0: break; // (disabled)
case 1: break; // (disabled)
case 2: DP2 |= (1<<PIN); break;
case 3: DP3 |= (1<<PIN); break;
case 4: break; // (disabled)
case 5: break; // (always input: A/D)
case 6: DP6 |= (1<<PIN); break;
case 7: DP7 |= (1<<PIN); break;
case 8: DP8 |= (1<<PIN); break;
default: abort_LED (21);
}
break;
default:
abort_LED (22);
} /* switch(BLOCK) */
#endif /* MATLAB_MEX_FILE */
}
/*
* mdlOutputs - compute the outputs
*
* In this function, you compute the outputs of your S-function
* block. The outputs are placed in the y variable.
*/
static void mdlOutputs(SimStruct *S, int_T tid)
{
#ifndef MATLAB_MEX_FILE
uint_T value;
switch(BLOCK) {
case DIG_INPUT:
// read state of selected input pin
switch(PORT) {
case 0: break; // (disabled)
case 1: break; // (disabled)
case 2: value = ((P2&(1<<PIN))>>PIN); break;
case 3: value = ((P3&(1<<PIN))>>PIN); break;
case 4: break; // (disabled)
case 5: value = ((P5&(1<<PIN))>>PIN); break;
case 6: value = ((P6&(1<<PIN))>>PIN); break;
case 7: value = ((P7&(1<<PIN))>>PIN); break;
case 8: value = ((P8&(1<<PIN))>>PIN); break;
default: abort_LED(23);
}
*ssGetOutputPortRealSignal(S,0) = (real_T)value;
break;
case DIG_OUTPUT:
// setting VON > VOFF creates a hysteresis (Schmitt trigger)
if(*ssGetInputPortRealSignal(S,0) >= VON) {
// simulation signal level 'high'
switch(PORT) {
case 0: break; // (disabled)
case 1: break; // (disabled)
case 2: P2 |= (1<<PIN); break;
case 3: P3 |= (1<<PIN); break;
case 4: break; // (disabled)
case 5: break; // (always input: A/D)
case 6: P6 |= (1<<PIN); break;
case 7: P7 |= (1<<PIN); break;
case 8: P8 |= (1<<PIN); break;
default: abort_LED(24);
}
// P2 &= 0xFFFE; // LED on (debug)
}
if(*ssGetInputPortRealSignal(S,0) < VOFF) {
// simulation signal level 'low'
switch(PORT) {
case 0: break; // (disabled)
case 1: break; // (disabled)
case 2: P2 &= (65535-(1<<PIN)); break;
case 3: P3 &= (65535-(1<<PIN)); break;
case 4: break; // (disabled)
case 5: break; // (always input: A/D)
case 6: P6 &= (255-(1<<PIN)); break;
case 7: P7 &= (255-(1<<PIN)); break;
case 8: P8 &= (255-(1<<PIN)); break;
default: abort_LED(25);
}
// P2 |= 0x0001; // LED off (debug)
}
break;
default:
abort_LED(26);
} /* switch(BLOCK) */
#endif /* MATLAB_MEX_FILE */
}
/*
* mdlTerminate - called when the simulation is terminated.
*
* In this function, you should perform any actions that are necessary
* at the termination of a simulation. For example, if memory was allocated
* in mdlInitializeConditions, this is the place to free it.
*/
static void mdlTerminate (SimStruct *S)
{
/* not used here */
}
// the define 'MATLAB_MEX_FILE' has to be specified when recompiling this module to a DLL.
// this is only required if the format of the call-up parameters is modified... (FW-06-01)
#ifdef MATLAB_MEX_FILE
#include "simulink.c"
#else
#include "cg_sfun.h"
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -