📄 ad_dacon.c
字号:
/******************************************************************************/
/* */
/* Name: AD_DACON.C - S-Function for reading the on-chip A/D converters of */
/* the microcontroller and writing the D/A converters */
/* of the D/A chip "AD7847" which is placed on an exten- */
/* sion board and which can be programmed via latch "P7" */
/* of the "kitCON-166" microcontroller evaluation board */
/* */
/* Author: Andreas Weiss */
/* Extensions: Sven Rebeschiess */
/* Date: 5.8.1999 */
/* */
/******************************************************************************/
// =============================================================================
// 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...)
//
// FW-12-01
// =============================================================================
#define S_FUNCTION_NAME ad_dacon
#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 "vector12.h" /* interrupt vector table */
#include "mc_signal.h" // abort_LED(), blinky(), ...
#endif
// max. number of A/D (D/A) channels
#define MAX_AD_CHANNELS 16 // C167
#define MAX_DA_CHANNELS 0 // C167
// max. voltage A/D conversion / D/A conversion (unipolar)
#define MAX_AD_VOLTAGE 5.0
#define MAX_DA_VOLTAGE 10.0
/* resolution of the A/D (D/A) converter */
#define AD_RESOLUTION 1024
#define DA_RESOLUTION 4096
// -------------------------------------------------------------------------------
// Number of S-function Parameters and macros to access from the SimStruct
// -------------------------------------------------------------------------------
#define BLOCK_ARG ssGetSFcnParam(S,0) /* 1: A/D block; 2: D/A block */
#define SAMPLE_TIME_ARG ssGetSFcnParam(S,1) /* Sample time in seconds */
#define NUM_AD_CHAN_ARG ssGetSFcnParam(S,2) /* Number of A/D channels */
#define NUM_DA_CHAN_ARG ssGetSFcnParam(S,3) /* Number of D/A channels */
#define NUMBER_OF_ARG 4 /* Number of 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 NUM_AD_CHAN ((uint_T) mxGetPr (NUM_AD_CHAN_ARG)[0])
#define NUM_DA_CHAN ((uint_T) mxGetPr (NUM_DA_CHAN_ARG)[0])
/* Define Simulink block types: */
#define AD_CONV 1
#define DA_CONV 2
// ----------------------------------------------------------------------------------------------------
// global variables
// ----------------------------------------------------------------------------------------------------
static unsigned int ADstore[MAX_AD_CHANNELS]; // defined statically so we can reuse previous values
// in case the conversion is not complete by the time
// the values are required...
// ----------------------------------------------------------------------------------------------------
// local functions
// ----------------------------------------------------------------------------------------------------
/* not used on the PhyCore167
// =====================================================================================================
// Reset_DA ... currently not used (FW-06-01)
// =====================================================================================================
// Reset all D/A converters to 0 V
void Reset_DA (void)
{
EnableDA0_Ext(0); // Disable D/A Channel 0 (External)
EnableDA1_Ext(0); // Disable D/A Channel 1 (External)
// When accessing latch P7 (which is used for programming the D/A
// converter AD7847 of the kitCON-166 extension board) every value has
// to be written twice:
DA_Port = 0x0000; // CSA, CSB und WR aktivieren ...
DA_Port = 0x0000; // ... und alle Datenbits auf 0 setzen
DA_Port = 0x3000; // Positive Flanke an CSA und CSB =>
DA_Port = 0x3000; // Daten auf DA0 und DA1 黚ernehmen
DA_Port = 0x7000; // WR, CSA und CSB deaktivieren
DA_Port = 0x7000;
}
// =====================================================================================================
*/
// =====================================================================================================
// AD conversion terminated INTERRUPT HANDLER
// =====================================================================================================
void AD_finished(void) __attribute__ ((interrupt));
void AD_finished(void)
{
unsigned int res;
unsigned int channel;
#ifndef MATLAB_MEX_FILE
// at the end of each AD conversion: save ADDAT
res = ADDAT;
channel = (res & 0xF000)>>12;
ADstore[channel] = res & (AD_RESOLUTION-1);
//#ifdef TIMING
// last channel converted -> reset P3.3
//if(!channel) P3 &= 0xFFF7; // indicate 'A/D' stopped
//#endif
#endif
}
// =====================================================================================================
// ----------------------------------------------------------------------------------------------------
// S-Function methods
// ----------------------------------------------------------------------------------------------------
/* Function: mdlCheckParameters ===============================================
*
*/
#define MDL_CHECK_PARAMETERS
#if defined(MDL_CHECK_PARAMETERS)
static void mdlCheckParameters(SimStruct *S)
{
// check common parameter (SAMPLE_TIME)
if (mxGetNumberOfElements(SAMPLE_TIME_ARG) != 1) abort_LED(21); // parameter must be a scalar
if ((SAMPLE_TIME < 0) && (SAMPLE_TIME != INHERITED_SAMPLE_TIME)) abort_LED(21); // invalid negative sample time
// currently unused (only AD) -> BLOCK dependency disabled... (FW-07-01)
/*---------------
// check block dependent parameter
switch (BLOCK)
{
case AD_CONV:
----------------*/
// check parameter: NUM_AD_CHAN
if (mxGetNumberOfElements(NUM_AD_CHAN_ARG) != 1) abort_LED(22); // parameter must be a scalar
if ((NUM_AD_CHAN < 1) || (NUM_AD_CHAN > MAX_AD_CHANNELS)) abort_LED(22); // invalid range
/*----------------
break;
case DA_CONV:
// check parameter: NUM_DA_CHAN
if (mxGetNumberOfElements(NUM_DA_CHAN_ARG) != 1) abort_LED(23); // parameter must be a scalar
if ((NUM_AD_CHAN < 1) || (NUM_DA_CHAN > MAX_DA_CHANNELS)) abort_LED(23); // invalid range
break;
default:
abort_LED(24); // incorrect BLOCK parameter
break;
}
----------------*/
}
#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(20); // 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);
ssSetNumContStates (S, 0); // number of continuous states
ssSetNumDiscStates (S, 0); // number of discrete states
// currently unused (only AD) -> BLOCK dependency disabled... (FW-07-01)
/*---------------
switch(BLOCK)
{
case AD_CONV:
----------------*/
if(!ssSetNumInputPorts(S, 0)) abort_LED(25);
if(!ssSetNumOutputPorts(S, 1)) abort_LED(25); // output: vector...
ssSetOutputPortWidth(S, 0, NUM_AD_CHAN); // ... of width NUM_AD_CHAN
/*---------------
break;
case DA_CONV:
if(!ssSetNumInputPorts(S, 1)) abort_LED(26);
if(!ssSetNumOutputPorts(S, 0)) abort_LED(26);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -